View difference between Paste ID: 0G9Ng48r and ai8xUASr
SHOW: | | - or go back to the newest paste.
1
var imageBlacklist = [] ;
2
function loadImageBlacklist() { JSON.parse(localStorage.imageBlacklist || "[]").forEach(addToImageBlaclist); }
3
function saveImageBlacklist() { localStorage.imageBlacklist = JSON.stringify(imageBlacklist); }
4
function addToImageBlaclist(md5) { if (md5 && -1 === imageBlacklist.indexOf(md5)) imageBlacklist.push(md5); }
5
function blacklistPostImages(post) { $(post).find('img.post-image').each(function (i, el) { var md5 = el.getAttribute('data-md5'); addToImageBlaclist(md5); el.remove(); }); }
6
function removeBlacklistedImages() { var removed = 0; $('img.post-image').each(function (i, el) { if (-1 !== imageBlacklist.indexOf(el.getAttribute('data-md5'))) { el.remove(); removed += 1; } }); return removed; }
7
function onNopeClicked(event) { event.preventDefault(); event.stopPropagation(); loadImageBlacklist(); var post = $(event.target).closest('.post'); blacklistPostImages(post); removeBlacklistedImages(); saveImageBlacklist(); }
8
function addNopeButtons() { $('.post').each(function(i, post) { if ($(post).find('.nope').length === 0) { $(post).prepend("<input type='button' class='nope' onClick='onNopeClicked(event)' value='Nope'></input>"); } }) }
9
 
10
setInterval(function () { loadImageBlacklist(); removeBlacklistedImages(); addNopeButtons(); }, 500);
11
// User Settings
12
var anonsw = {
13
    qflair: '', // Examples: REAL, &rarr;
14
    qcolor: '#17dd4c',
15
    youcolor: '#ffff00',
16
    notablecolor: '#ff4444',
17
    scrollcolor: 'rgba(153, 153, 153, 0.6)',
18
    scrollbackcolor: '#333',
19
    scrolltime: 400, // ms
20
    updateDelay: 200, // ms
21
    sidenavWidth: 30, // px
22
 
23
    floodEnabled: false,
24
    floodThreshold: 15, // min # posts before beginning fade
25
    floodVanish: 25, // max # posts before completed fade/hide
26
    floodBehavior: 'fade', // hide, fade
27
    fadenametripregex: /^(Anon(ymous)?-.*|.*-!!Hs1Jq13jV6)$/i,
28
    fadenametripfloodvalue: -1, // Effective post count for fading, or -1 for auto of floodThreshold+post count
29
    strikeThroughNameFags: true,
30
 
31
    rateHistoryLen: 50, // Data points on chart
32
    rateAvgLen: 10 // Number of data points to average for instantaneous rate
33
 
34
    // Suggestions from 589388.html#590283
35
    //    ...shill detection features, such as
36
    //          easily knowing the proportion of posts from a user that don't link.
37
    //          I'd want to know any ID that was posting > 1/3 posts targetting noone.
38
 
39
    // TODO: Behavior for post hover should be to show original post visual before all q.js mods
40
    // TODO: Add flags to turn on/off features
41
    // TODO: Custom-regex -> post color/fade (auto-filter by selecting text and choosing new menu item?)
42
    //       Examples: daily reminder, guys, check this out, shill, get out, filtered, tell us more, archive everything
43
    // TODO: Manual shade
44
    // TODO: remove Q trip codes from post content?
45
    // TODO: remove Q from end of post content if not a Q post?
46
    // TODO: recognize all of known Q trip codes? (make to sure to exclude known comps)
47
    // TODO: Links to reset on current Q/(you) post
48
    // TODO: Link to go to latest post (end key doesn't always work, but try capturing that as well?)
49
    // TODO: Keyboard shortcuts for navigation
50
    // TODO: Current/Total overall post navigation
51
    // TODO: Remap end key to always go to end of page
52
    // TODO: Check box for each post to mark as "read", "spam", ?
53
    // TODO: Autocorrect all-caps posts (50% threshold)?
54
    // TODO: Correct broken links but remove referral when clicked?
55
    // TODO: Make flood post fading non-linear to give leniency to posters just passing flood threshold
56
    // TODO: Penalize reposts in flood detection (if id's different, merge?) ?
57
    // TODO: Scorecard of posters ordered by post count (post rate, reply count, ...)?
58
    // TODO: Color/shade posts where there are no references and no question marks
59
    // TODO: If Q or trip used in name field, strike them out or replace with Anonymous?
60
    // TODO: embedded posts in Q posts don't have background-color and inherit Q color, fix?
61
};
62
 
63
(function( anonsw_main, $, undefined ) {
64
    // House keeping variables
65
    var qposts = [];
66
    var allqposts = [];
67
    var currq = -1;
68
    var youposts = [];
69
    var notableposts = [];
70
    var curryou = -1;
71
    var currnotable = -1;
72
    var qnavposts = [];
73
    var younavposts = [];
74
    var notablenavposts = [];
75
    var ctx;
76
    var borderSz;
77
    var scrollWd;
78
    var minheight;
79
    var ratehistory = [];
80
 
81
    // On scroll stop. SO #9144560
82
    (function ($) {
83
        var on = $.fn.on, timer;
84
        $.fn.on = function () {
85
            var args = Array.apply(null, arguments);
86
            var last = args[args.length - 1];
87
 
88
            if (isNaN(last) || (last === 1 && args.pop())) return on.apply(this, args);
89
 
90
            var delay = args.pop();
91
            var fn = args.pop();
92
 
93
            args.push(function () {
94
                var self = this, params = arguments;
95
                clearTimeout(timer);
96
                timer = setTimeout(function () {
97
                    fn.apply(self, params);
98
                }, delay);
99
            });
100
 
101
            return on.apply(this, args);
102
        };
103
    }(this.jQuery || this.Zepto));
104
 
105
    // Case insensitive contains selector for finding yous. SO #8746882
106
    $.expr[":"].icontains = jQuery.expr.createPseudo(function (arg) {
107
        return function (elem) {
108
            return jQuery(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
109
        };
110
    });
111
 
112
    // Get non-child text. SO #3442394
113
    function immediateText(el) {
114
        return el.contents().not(el.children()).text();
115
    }
116
 
117
    // Scroll to element
118
    function myScrollTo(el) {
119
        $('html, body').animate({
120
            scrollTop: $(el).offset().top - $('div.boardlist').height()
121
        }, anonsw.scrolltime);
122
    }
123
 
124
    // Highlight (you) posts/references
125
    function highlightYous() {
126
        $(youposts).each(function() {
127
            $(this).css('background-color', anonsw.youcolor);
128
        });
129
        return $.Deferred().resolve();
130
    }
131
    function highlightNotables() {
132
        $(notableposts).each(function() {
133
            $(this).css('background-color', anonsw.notablecolor);
134
        });
135
        return $.Deferred().resolve();
136
    }
137
    
138
    // Remove invalid (you)'s
139
    function removeInvalidYous() {
140
        $('div.body:icontains("(You)")').each(function() {
141
            $(this).find(':not(small)').contents().filter(function() { return this.nodeType == 3 }).each(function() {
142
                this.textContent = this.textContent.replace(/\(+ *You *\)+/ig, "you");
143
            });
144
        });
145
        return $.Deferred().resolve();
146
    }
147
 
148
    // Highlight Q posts
149
    function highlightQ() {
150
        $(allqposts).each(function(idx,val) {
151
            if($(val).css('background-color') !== anonsw.qcolor) {
152
                if(anonsw.qflair !== "") {
153
                    $(val).find('p.intro > label > span.trip').first().prepend(anonsw.qflair + " ");
154
                }
155
                $(val).css('background-color', anonsw.qcolor);
156
            }
157
        });
158
        return $.Deferred().resolve();
159
    }
160
 
161
    // Scroll to next Q
162
    anonsw_main.nextq = function() {
163
        if(qposts.length > 0) {
164
            if(currq < qposts.length-1) {
165
                currq++;
166
            }
167
            myScrollTo($(qposts).get(currq));
168
        }
169
    };
170
 
171
    // Scroll to last Q
172
    anonsw_main.lastq = function() {
173
        if(qposts.length > 0) {
174
            currq = qposts.length - 1;
175
            myScrollTo($(qposts).get(currq));
176
        }
177
    };
178
 
179
    // Scroll to previous Q
180
    anonsw_main.prevq = function() {
181
        if(qposts.length > 0) {
182
            if(currq > 0) {
183
                currq--;
184
            }
185
            myScrollTo($(qposts).get(currq));
186
        }
187
    };
188
 
189
    // Scroll to first Q
190
    anonsw_main.firstq = function() {
191
        if(qposts.length > 0) {
192
            currq = 0;
193
            myScrollTo($(qposts).get(currq));
194
        }
195
    };
196
 
197
    // Scroll to next (You)
198
    anonsw_main.nextyou = function() {
199
        if(youposts.length > 0) {
200
            if(curryou < youposts.length-1) {
201
                curryou++;
202
            }
203
            myScrollTo($(youposts).get(curryou));
204
        }
205
    };
206
    anonsw_main.nextnotable = function() {
207
        if(notableposts.length > 0) {
208
            if(currnotable < notableposts.length-1) {
209
                currnotable++;
210
            }
211
            myScrollTo($(notableposts).get(currnotable));
212
        }
213
    };
214
    
215
    // Scroll to last (You)
216
    anonsw_main.lastyou = function() {
217
        if(youposts.length > 0) {
218
            curryou = youposts.length - 1;
219
            myScrollTo($(youposts).get(curryou));
220
        }
221
    };
222
     anonsw_main.lastnotable = function() {
223
        if(notableposts.length > 0) {
224
            currnotable = notableposts.length - 1;
225
            myScrollTo($(notableposts).get(currnotable));
226
        }
227
    };
228
 
229
 
230
    // Scroll to previous (You)
231
    anonsw_main.prevyou = function() {
232
        if(youposts.length > 0) {
233
            if(curryou > 0) {
234
                curryou--;
235
            }
236
            myScrollTo($(youposts).get(curryou));
237
        }
238
    };
239
   anonsw_main.prevnotable = function() {
240
        if(notableposts.length > 0) {
241
            if(currnotable > 0) {
242
                currnotable--;
243
            }
244
            myScrollTo($(notableposts).get(currnotable));
245
        }
246
    };
247
 
248
    // Scroll to first (You)
249
    anonsw_main.firstyou = function() {
250
        if(youposts.length > 0) {
251
            curryou = 0;
252
            myScrollTo($(youposts).get(curryou));
253
        }
254
    };
255
     anonsw_main.firstnotable = function() {
256
        if(notableposts.length > 0) {
257
            currnotable = 0;
258
            myScrollTo($(notableposts).get(currnotable));
259
        }
260
    };
261
    // Inserts Q navigation links
262
    function qnav() {
263
        $('div.boardlist').append('<span>[ <a href="javascript:anonsw_main.firstq();"><i class="fa fa-step-backward"></i></a> <a href="javascript:anonsw_main.prevq();"><i class="fa fa-backward"></i></a> <span style="filter:brightness(70%);">Q</span> <span class="qcount">(?:?)</span> <a href="javascript:anonsw_main.nextq();"><i class="fa fa-forward"></i></a> <a href="javascript:anonsw_main.lastq();"><i class="fa fa-step-forward"></i></a> ]</span>');
264
    }
265
 
266
    // Inserts (You) navigation links
267
    function younav() {
268
        $('div.boardlist').append('<span>[ <a href="javascript:anonsw_main.firstyou();"><i class="fa fa-step-backward"></i></a> <a href="javascript:anonsw_main.prevyou();"><i class="fa fa-backward"></i></a> <span style="filter:brightness(70%);">(You)</span> <span class="youcount">(?:?)</span> </span><a href="javascript:anonsw_main.nextyou();"><i class="fa fa-forward"></i></a> <a href="javascript:anonsw_main.lastyou();"><i class="fa fa-step-forward"></i></a> ]</span>');
269
    }
270
     // Inserts notable navigation links
271
    function notablenav() {
272
        $('div.boardlist').append('<span>[ <a href="javascript:anonsw_main.firstnotable();"><i class="fa fa-step-backward"></i></a> <a href="javascript:anonsw_main.prevnotable();"><i class="fa fa-backward"></i></a> <span style="filter:brightness(70%);">Bakeables</span> <span class="notablecount">(?:?)</span> </span><a href="javascript:anonsw_main.nextnotable();"><i class="fa fa-forward"></i></a> <a href="javascript:anonsw_main.lastnotable();"><i class="fa fa-step-forward"></i></a> ]</span>');
273
    }
274
 
275
    // Inserts feature toggle links
276
    function togglenav() {
277
        $('div.boardlist').append('<span>[ <a href="javascript:anonsw_main.toggleFlood();">Turn Post Fading <span class="toggleFloodState">Off</span></a> ]</span>')
278
    }
279
 
280
    // Inserts post rate count/chart
281
    function postratenav() {
282
        var height = $('div.boardlist').height() - 1;
283
        $('div.boardlist').append('<span>[ Post Rate: <span class="postRate">0</span> posts/min <canvas class="postRateChart"></canvas>]</span>')
284
        $('.postRate').css('color', $('div.boardlist a').css('color'));
285
        var charts = $('.postRateChart');
286
        $(charts).each(function() {
287
            $(this).css('width', '100px');
288
            $(this).css('height', height);
289
            $(this).css('vertical-align', 'middle');
290
            //$(this).css('border', '1px solid');
291
            //$(this).css('border-color', $('div.boardlist').css('color'));
292
            var gctx = $(this).get(0).getContext('2d');
293
            gctx.canvas.height = 20;
294
            gctx.canvas.width = 100;
295
        });
296
    }
297
 
298
    // Inserts side navigation (bird's eye)
299
    function sidenav() {
300
        $('body').append('<canvas id="sidenav"></canvas>');
301
        var nav = $('#sidenav');
302
        $(nav).css('position', 'fixed');
303
        $(nav).css('top', $('div.boardlist').height());
304
        $(nav).css('right', 0);
305
        $(nav).css('width', anonsw.sidenavWidth);
306
        $(nav).css('height', $(window).height() - $('div.boardlist').height());
307
        $(nav).css('background-color', anonsw.scrollbackcolor);
308
        $('body').css('margin-right', anonsw.sidenavWidth);
309
        ctx = $('#sidenav').get(0).getContext('2d');
310
        //ctx.canvas.height = $(document).height() - $('div.boardlist').height();
311
        ctx.canvas.height = 2048;
312
        ctx.canvas.width = anonsw.sidenavWidth;
313
        borderSz = 1;
314
        scrollWd = ctx.canvas.width / 2;
315
    }
316
 
317
    // Update navigation counts
318
    function updateNavCounts() {
319
        var fontSize = -1;
320
        var lineHeight;
321
 
322
        if(currq > qposts.length) { currq = qposts.length; }
323
        if(curryou > youposts.length) { curryou = youposts.length; }
324
 
325
        if(currnotable > notableposts.length) { currnotable = notableposts.length; }
326
        
327
        for(i=0; i<qposts.length; i++) {
328
            var el = $(qposts).get(i);
329
            if(fontSize == -1) {
330
                fontSize = $(el).css('font-size');
331
                lineHeight = Math.floor(parseInt(fontSize.replace('px', '')) * 1.5);
332
            }
333
            if(($(el).offset().top + $(el).height() - 2.25*lineHeight) > $(window).scrollTop()) {
334
                currq = i;
335
                break;
336
            }
337
        }
338
 
339
        for(i=0; i<youposts.length; i++) {
340
            var el = $(youposts).get(i);
341
            if(fontSize == -1) {
342
                fontSize = $(el).css('font-size');
343
                lineHeight = Math.floor(parseInt(fontSize.replace('px', '')) * 1.5);
344
            }
345
            if(($(el).offset().top + $(el).height() - 2.25*lineHeight) > $(window).scrollTop()) {
346
                curryou = i;
347
                break;
348
            }
349
        }
350
        
351
         for(i=0; i<notableposts.length; i++) {
352
            var el = $(notableposts).get(i);
353
            if(fontSize == -1) {
354
                fontSize = $(el).css('font-size');
355
                lineHeight = Math.floor(parseInt(fontSize.replace('px', '')) * 1.5);
356
            }
357
            if(($(el).offset().top + $(el).height() - 2.25*lineHeight) > $(window).scrollTop()) {
358
                currnotable = i;
359
                break;
360
            }
361
        }
362
 
363
        // TODO: check for duplicates and remove from counts
364
        $('.qcount').text("(" + (currq+1) + ":" + qposts.length + ")");
365
        $('.youcount').text("(" + (curryou+1) + ":" + youposts.length + ")");
366
        $('.notablecount').text("(" + (currnotable+1) + ":" + notableposts.length + ")");
367
    }
368
 
369
    // Update navigation graphics
370
    function updateNavGraphics() {
371
        var sidenav = $('#sidenav');
372
        if(sidenav.length) {
373
            $(sidenav).css('height', $(window).height() - $('div.boardlist').height());
374
            minheight = ctx.canvas.height / ($(window).height() - $('div.boardlist').height()); // 1px
375
            ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
376
 
377
            // Draw nav q posts
378
            qnavposts = [];
379
            ctx.fillStyle = anonsw.qcolor;
380
            for (i = 0; i < qposts.length; i++) {
381
                // TODO: check if we have already added post, don't draw it again
382
                var el = $(qposts).get(i);
383
                var height = $(el).height() / $(document).height() * ctx.canvas.height;
384
                if(height < minheight) height = minheight;
385
                qnavposts[i] = {
386
                    x : borderSz,
387
                    y : $(el).offset().top / $(document).height() * ctx.canvas.height,
388
                    width : ctx.canvas.width - borderSz*2,
389
                    height : height
390
                };
391
                ctx.fillRect(qnavposts[i].x, qnavposts[i].y, qnavposts[i].width, qnavposts[i].height);
392
            }
393
 
394
            // Draw nav you posts
395
            younavposts = [];
396
            ctx.fillStyle = anonsw.youcolor;
397
            
398
            for (i = 0; i < youposts.length; i++) {
399
                // TODO: check if we have already added post, don't add it again
400
                var el = $(youposts).get(i);
401
                var height = $(el).height() / $(document).height() * ctx.canvas.height;
402
                if(height < minheight) height = minheight;
403
                younavposts[i] = {
404
                    x : borderSz,
405
                    y : $(el).offset().top / $(document).height() * ctx.canvas.height,
406
                    width : ctx.canvas.width - borderSz*2,
407
                    height : height
408
                };
409
                ctx.fillRect(younavposts[i].x, younavposts[i].y, younavposts[i].width, younavposts[i].height);
410
            }
411
            
412
            notablenavposts = [];
413
            ctx.fillStyle = anonsw.notablecolor;
414
            for (i = 0; i < notableposts.length; i++) {
415
                // TODO: check if we have already added post, don't add it again
416
                var el = $(notableposts).get(i);
417
                var height = $(el).height() / $(document).height() * ctx.canvas.height;
418
                if(height < minheight) height = minheight;
419
                notablenavposts[i] = {
420
                    x : borderSz,
421
                    y : $(el).offset().top / $(document).height() * ctx.canvas.height,
422
                    width : ctx.canvas.width - borderSz*2,
423
                    height : height
424
                };
425
                ctx.fillRect(notablenavposts[i].x, notablenavposts[i].y, notablenavposts[i].width, notablenavposts[i].height);
426
            }
427
            
428
            // Update nav window
429
            ctx.fillStyle = anonsw.scrollcolor;
430
            ctx.fillRect(
431
                scrollWd / 2,
432
                $(window).scrollTop() / $(document).height() * ctx.canvas.height,
433
                scrollWd,
434
                $(window).height() / $(document).height() * ctx.canvas.height
435
            );
436
 
437
            // Add red marker at bottom of >750 posts
438
            if($('#thread_stats_posts').text() > 750) {
439
                var barHeight = (4 * 2048) / ($(window).height() - $('div.boardlist').height());
440
                ctx.fillStyle = '#f66';
441
                ctx.fillRect(
442
                    0,
443
                    ctx.canvas.height - barHeight,
444
                    ctx.canvas.width,
445
                    barHeight
446
                );
447
            }
448
        }
449
    }
450
 
451
    // Updates post rate count/chart
452
    function updateNavPostRate() {
453
        var posts = $('div.post').not('.post-hover');
454
        var startPost = posts.length - (anonsw.rateHistoryLen + anonsw.rateAvgLen) + 1;
455
        if(startPost < 1) startPost = 1;
456
        var start = $($($(posts).get(0)).find('.intro time').get(0)).attr('unixtime'); //$('div.post:first .intro time').attr('unixtime');
457
        ratehistory = [];
458
        timehistory = [];
459
        for(var i=startPost; i<posts.length; i++) {
460
            // TODO: check if we have already added post, don't add it again
461
            var step = $($($(posts).get(i)).find('.intro time').get(0)).attr('unixtime'); //$($('div.post .intro time').get(i)).attr('unixtime');
462
            timehistory[timehistory.length] = step;
463
            if(timehistory.length - anonsw.rateAvgLen - 1 >= 0) {
464
                var avgend = timehistory[timehistory.length - 1];
465
                var avgstart = timehistory[timehistory.length - anonsw.rateAvgLen - 1];
466
                ratehistory[ratehistory.length] = anonsw.rateAvgLen / ((avgend - avgstart) / 60);
467
            } else {
468
                ratehistory[ratehistory.length] = 0;
469
            }
470
        }
471
        
472
        if (ratehistory.length)
473
        $('.postRate').text(ratehistory[ratehistory.length-1].toFixed(1));
474
 
475
        if(ratehistory.length > anonsw.rateAvgLen) {
476
            var maxRate = Math.max.apply(null, ratehistory);
477
            var minRate = Math.min.apply(null, ratehistory);
478
            //console.log("Max: " + maxRate);
479
            //console.log("Min: " + minRate);
480
            if(minRate > (maxRate - 0.5)) {
481
                minRate = maxRate - 0.5;
482
                maxRate = maxRate + 0.5;
483
            }
484
            if(minRate < 0) {
485
                minRate = 0;
486
            }
487
            var maxTime = timehistory[timehistory.length-1];
488
            var minTime = timehistory[anonsw.rateAvgLen];
489
            $('.postRateChart').each(function() {
490
                var gctx = $(this).get(0).getContext('2d');
491
                gctx.clearRect(0, 0, gctx.canvas.width, gctx.canvas.height);
492
                gctx.strokeStyle = $('div.boardlist a').css('color');
493
                gctx.beginPath();
494
                var x = 0;
495
                var y = gctx.canvas.height - (ratehistory[anonsw.rateAvgLen] - minRate)/(maxRate - minRate) * gctx.canvas.height;
496
                gctx.moveTo(x, y);
497
                for(var i=anonsw.rateAvgLen+1; i<ratehistory.length; i++) {
498
                    x = (timehistory[i] - minTime)/(maxTime - minTime) * gctx.canvas.width;
499
                    y = gctx.canvas.height - (ratehistory[i] - minRate)/(maxRate - minRate) * gctx.canvas.height;
500
                    gctx.lineTo(x, y);
501
                }
502
                gctx.stroke();
503
                gctx.closePath();
504
            });
505
        }
506
    }
507
 
508
    // Update navigation
509
    function updateNav() {
510
        updateNavCounts();
511
        updateNavGraphics();
512
        updateNavPostRate();
513
    }
514
 
515
    // Update nav when scrolling stops
516
    $(window).on('scroll', function(e) {
517
        updateNavCounts();
518
        updateNavGraphics();
519
    }, anonsw.updateDelay);
520
 
521
    // Update nav when resize stops
522
    $(window).on('resize', function(e) {
523
        updateNav();
524
    }, anonsw.updateDelay);
525
 
526
    // Set which posts are Q posts
527
    function setQPosts() {
528
        qposts = $.map($('div.post:not(.post-hover) > p.intro > label > span.trip:contains("!!Hs1Jq13jV6")'), function(el) {
529
            return $(el).closest('div.post');
530
        });
531
        allqposts = $.map($('div.post:not(.post-hover) > p.intro > label > span.trip:contains("!!Hs1Jq13jV6")'), function(el) {
532
            return $(el).closest('div.post');
533
        });
534
        return $.Deferred().resolve();
535
    }
536
 
537
    // Set which posts are (you) posts
538
    function setYouPosts() {
539
        youposts = $.map($('div.post:not(.post-hover) > p.intro > label span.name > span.own_post, div.post:not(.post-hover) > div.body > p.body-line > small:icontains("(You)")'), function(el) {
540
            return $(el).closest('div.post');
541
        });
542
        return $.Deferred().resolve();
543
    }
544
    function setNotablePosts() {
545
        notableposts = $.map($('div.post:not(.post-hover) > span, div.post:not(.post-hover) > div.body > p.body-line > span.heading:icontains("notable") , span.heading:icontains("baker") '), function(el) {
546
            return $(el).closest('div.post');
547
        });
548
        return $.Deferred().resolve();
549
    }
550
    
551
    // Set flood posts
552
    function setFloodPosts() {
553
        if(anonsw.floodEnabled) {
554
            var stats = {};
555
            var firstId = null;
556
            //console.log("==[ Name Fags ]=================================================");
557
            var posts = $('div.post:not(.post-hover)').not('.you');
558
            $(posts).each(function () {
559
                var id = $(this).find('p > span.poster_id').first().text();
560
                if(firstId != null) {
561
                    if (!(id in stats)) {
562
                        stats[id] = {count: 0, namefag: false, floodcount: 0};
563
                    }
564
                    stats[id].count++;
565
                    if(!stats[id].namefag) {
566
                        var name = immediateText($(this).find('p > label span.name').first());
567
                        var trip = $(this).find('p > label > span.trip').first().text();
568
                        stats[id].namefag = !anonsw.fadenametripregex.test(name+'-'+trip);
569
                        //if(stats[id].namefag) {
570
                        //  console.log(id + '=' + stats[id].namefag + ', ' + name + ', ' + trip);
571
                        //}
572
                    }
573
                    if(stats[id].namefag) {
574
                        if(anonsw.fadenametripfloodvalue < 0) {
575
                            stats[id].floodcount = anonsw.floodThreshold + stats[id].count;
576
                        } else {
577
                            stats[id].floodcount = anonsw.fadenametripfloodvalue;
578
                        }
579
                    } else {
580
                        stats[id].floodcount = stats[id].count;
581
                    }
582
                }
583
                if (firstId == null) {
584
                    firstId = id;
585
                }
586
            });
587
            $.each(stats, function (key, value) {
588
                if (key !== firstId) {
589
                    var ids = $('span.poster_id:contains("' + key + '")');
590
                    if (value.floodcount > anonsw.floodThreshold || value.namefag) {
591
                        if(anonsw.strikeThroughNameFags && value.namefag) {
592
                            $(ids).each(function() {
593
                                $(this).closest('div.post').find('p > label span.name').first().css('text-decoration','line-through');
594
                            });
595
                        }
596
                        if (anonsw.floodBehavior === 'fade') {
597
                            var intensity = value.floodcount;
598
                            if (intensity > anonsw.floodVanish) {
599
                                intensity = anonsw.floodVanish;
600
                            }
601
                            intensity = ((anonsw.floodVanish - anonsw.floodThreshold) - (intensity - anonsw.floodThreshold)) / (anonsw.floodVanish - anonsw.floodThreshold);
602
                            if (intensity < 0.1) {
603
                                intensity = 0.1;
604
                            }
605
                            $(ids).each(function () {
606
                                $(this).closest('div.post').css('opacity', intensity);
607
                                $(this).closest('div.post').hover(function () {
608
                                    $(this).animate({opacity: 1.0}, anonsw.updateDelay);
609
                                }, function () {
610
                                    $(this).animate({opacity: intensity}, anonsw.updateDelay);
611
                                });
612
                            });
613
                        } else if (anonsw.floodBehavior === 'hide') {
614
                            if (value.count >= anonsw.floodVanish) {
615
                                $(ids).each(function () {
616
                                    $(this).closest('div.post').hide();
617
                                });
618
                            }
619
                        }
620
                    } else {
621
                        $(ids).each(function () {
622
                            $(this).closest('div.post').css('opacity', 1.0);
623
                        });
624
                    }
625
                }
626
            });
627
        }
628
        return $.Deferred().resolve();
629
    }
630
 
631
    // Toggle post flooding
632
    anonsw_main.toggleFlood = function() {
633
        if(anonsw.floodEnabled) {
634
            anonsw.floodEnabled = false;
635
            $('.toggleFloodState').text('On');
636
            if(anonsw.floodBehavior === 'fade') {
637
                $('span.poster_id').each(function () {
638
                    $(this).closest('div.post').css('opacity', 1);
639
                    $(this).closest('div.post').off('mouseenter mouseleave');
640
                });
641
            } else if(anonsw.floodBehavior === 'hide') {
642
                $(this).closest('div.post').show();
643
            }
644
        } else {
645
            anonsw.floodEnabled = true;
646
            $('.toggleFloodState').text('Off');
647
            runq()
648
        }
649
    };
650
 
651
    // Helper to run snippets in the right order
652
    function runq() {
653
        setQPosts()
654
            .done(highlightQ)
655
            .done(removeInvalidYous)
656
            .done(setYouPosts)
657
            .done(setNotablePosts)
658
            .done(highlightYous)
659
            .done(setFloodPosts)
660
            .done(updateNav);
661
    }
662
 
663
    anonsw_main.Q = function() {
664
        qnav();
665
        younav();
666
        notablenav();
667
        togglenav();
668
        postratenav();
669
        sidenav();
670
        runq();
671
 
672
        // Select the node that will be observed for mutations
673
        var targetNode = $('div.thread')[0];
674
 
675
        // Options for the observer (which mutations to observe)
676
        var config = { childList: true };
677
 
678
        // Callback function to execute when mutations are observed
679
        var callback = function(mutationsList) {
680
            for(var mutation in mutationsList) {
681
                if (mutationsList[mutation].type == 'childList') {
682
                    runq();
683
                    break;
684
                }
685
            }
686
        };
687
 
688
        // Create an observer instance linked to the callback function
689
        var observer = new MutationObserver(callback);
690
 
691
        // Start observing the target node for configured mutations
692
        observer.observe(targetNode, config);
693
    };
694
}( window.anonsw_main = window.anonsw_main || {}, jQuery ));
695
 
696
// Attach snippets to ready/change events
697
$(document).ready(anonsw_main.Q);
698
699
700
701
//================================================================
702
//
703
// Toastmaster 2.5.6
704
// Finds the bread so you don't have to.
705
//
706
// Always look through the code to find shifty stuff.
707
//
708
//
709
//================================================================
710
//2345678901234567890123456789012345678901234567890123456789012345
711
/* 
712
these files can be extracted and saved as text and they should 
713
still be loadable
714
*/
715
var chatty = true; // set me to false if you don't want to hear me
716
window.t = 0;
717
var container;
718
/* this is literally just a picture of toast */
719
720
var toast = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABsAA"
721
          + "AAbCAMAAAC6CgRnAAAARVBMVEWZMwAAAABmMwBmMzNmZjOZZgCZ"
722
          + "ZjOZZmbMZgDMZjPMZmaZmTOZmWbMmTPMmWbMmZn/mWbMzGbMzJn"
723
          + "/zGb/zJn/zMz//8zDFCa2AAAAAXRSTlMAQObYZgAAAAlwSFlzAA"
724
          + "ALEwAACxMBAJqcGAAAAAd0SU1FB+IIBAI4ECHmtE4AAAFKSURBV"
725
          + "CjPVVIBcsMwCKubQuZb0J2xu/8/dRJJt5ZzcnGEhAy+3V7R3uL2"
726
          + "FtrfffN927a7P+7tDYEDuRiZ4II/LrQ5EQwQKVAp8HZCBu6Jrpm"
727
          + "5JpiST+ytBGFBovIrB5iDX3RECCKKh+SDSoxEYaYtWVEkhkdgCl"
728
          + "uBTmIO2kHwr015m6mCqROMkMwsOcjOurwERYbcpBDrgfyBsPpDM"
729
          + "VHLiVTYifJ5sEiWKs6FoLtRPo+ijXI4aazzvGEvrHJXnAcgyi9b"
730
          + "wiyrm8mKKUCS5IJnaPFfpXrHWt27xyqsV8Fuhu5yadHDIcy+7eK"
731
          + "xWVaaqKyz15IHaWFfTjkhvTQpEp1pxmWdc+aL7D/M1F1a57l6KI"
732
          + "GwNPuCrOZ5tlVvCsU4edX6+he8E+xY5bWaA0eX6+BgBq/SwfGz/"
733
          + "2EahAbLGgd8Z/92v0JD+rjQH/ELBU8elOTZkAQAAAAASUVORK5C"
734
          + "YII=";
735
736
/* this is an MP3 file. you should inspect it yourself */
737
var frog =  "data:audio/wav;base64,UklGRjkKAABXQVZFZm10IBAAAAABA"
738
          + "AEAQB8AAEAfAAABAAgAZGF0YRUKAAB9fn1+gIGDhIOAf4B/gH+B"
739
          + "goGCgYKBf4CAf4B/gIGDgoGCf4B+foGCgYKBfnx9f3+AgoGCgoK"
740
          + "Af35/gYB/f4B/foKDhIOEg398fYB+fH6BgoGCgX9+foGCgYKCgH"
741
          + "17e3yAhISCgYOEg4GAfHuAg4SDgH+BgoGBg4aEf31/f3x8foB9e"
742
          + "XuAgoCAg4aFgoF+e3p8f4B8foOBf4GEgn6Ag4N+f4SDe3d+gn1+"
743
          + "h4h8e4aLh4GDhoB4eoB+eX6HhXx8g4R8fIODgX+Cgnp3foF8fYS"
744
          + "Ggn+BgHp4en6Af4CBf4GEgoCCh4V+en2CgX6DiYh+eH6BfICMjo"
745
          + "J4eXl4gIuLhIGDfnV7hYeDhYh9b3F9gn+Bh4Z7dX+Ef3+Lint0f"
746
          + "YN8e4SFeniDiYB5g4d/foaEdnqJjH58iId4eIaGeHqIhXR1hYh6"
747
          + "dn+Ce3qFiod9d4CGgnp+hYF5e4WHgYGHhHd2goiDg4uNf3iBhHt"
748
          + "7iZCDdnl8dneGjYF3fHtzdIKKhH+Afnd0eoOFfXd+iIN7hY2Acn"
749
          + "aEiImPjn1rboCTlo+Gdm5veIuYmY59Z11shJaenIVnX2NqgZ2fi"
750
          + "315bGV4kIp2f457aH2UgmyDnodqe5WCaIKkjGVymIxjcaCdbWSN"
751
          + "l25gi6aFYXWUelx8p5RocJiKXWidqHdghp1zWIKumWlumJNiYJe"
752
          + "vfll9m3FTga2NWG+ce1F5sp5kaZiDV3avr3lohXVQZp6ynYmBal"
753
          + "xxhYSOoZRwbY6KYGiXlm1/r5RbZY95V4i+oF9hinJMe7mra2KFa"
754
          + "Ul6urBwZIpyTXu1omVxpIhYdq2RV26upGJjoJ1bWZ61d1SKqW1M"
755
          + "jsSVUG2jdUN8w6FQXpx7RXnAolhtoHRMgbyfZXqZZEByqJFniKl"
756
          + "+W3mcmXxodIeAfpmfeWJ6kIZ/lJl5a4WTeWuEknZmgZN6aIKPaF"
757
          + "WApI1uhplwW3ySfH6qsYBda3VoeKi1hmJ0fVxinrKCapScbGuil"
758
          + "1RUj5ZkdLqsWkR9lWhzvrlrVH99T2u2uHNeh4VXZaOhZWWel1xi"
759
          + "oZtWXa29dWChqVpSqs6DSoKlWDWLxoVIeJhOO5rYnFaDqGIzcLe"
760
          + "mboGwj19xloRedqKMYnmSX0WJwphnkK9sNXC+o15ynntdfpaLf3"
761
          + "yAhIF/gIOCfnt+gH9/gYKBgoF+e32BgX+Af4GCgYKBgoGBgoGCg"
762
          + "YKAf4B/gH+BgX+Af4CBg4SGhIKBgoF/gYKCgH1/gYKBgoGCfnuA"
763
          + "goB/gYJ+f3+BgoKEgoF/gH+AgoGCgoB/fX6Af4CCgn99f4B/gIG"
764
          + "CgX+BgoGAf4GCgYKBgoF/gYKDgYCDg397fYB/f4GFhoSBfnx7fX"
765
          + "+AgYODhIKBf4B/e32AgoF/gH97foGAgH+BgX+AgYKBgoSDgYKBg"
766
          + "oGAgoKAgYKAf4CDhYOCf319foCBgX1+gYF/gISGg4GBgn19gYB/"
767
          + "gIJ/e36BgYB+f35+gICCgoGAgYJ/e36CgH5/g4J/gYKEgn+Bg4O"
768
          + "AgIOEgX+BgoGCgYOBfH+CgHt9g4WBfICDg35/gYB/foGEg4B9e3"
769
          + "p9goGAhIiFe3d7gIOEg4GAf4GBfX+CgX9+gYF8foWGgHt/gn58g"
770
          + "IOBf4GBfH2DhYJ/gYSBe32AfnyChIKEhoN/gYKBf4KGgnp7fXp8"
771
          + "hYeBgIJ/en2Fgnl4g4eCg4R+eHh+goGCgoWBeHl/gHx/h4J3eIG"
772
          + "DgIOGgX6EiH58h42Een2CgHp4gIaAf4ySgW51h4h+goqDdnuJgW"
773
          + "1zjI97eIyPeXB6f3l5hox/dHuEfXeBh4J9gH55fYKDhIN9eoKDf"
774
          + "ICIgXd8iIZ6f4yOgnyChX17h4qCeYCGfnuChH13eX+Dg4F+f4B9"
775
          + "fYB8e4GGfnmAg3x4e3p0d4aHfnyCgXuAiIR4eoJ7dX+PlI6Ig3l"
776
          + "ydYGHhoyVi3dvdHZ3g5GUi4WFgXpyamx+j42CiJOEbGlxb3CKoJ"
777
          + "V9eXxpW22LkomPn5NxY292bG+Rr6qNfIJ8XU1qlaWXhpGcgllSc"
778
          + "4uIiZGIdXqAbnKQlXlrhZiBaniQh3J6jo57doGIgHZ7g4F6f4uM"
779
          + "gHJ5g4J8g4p8bnaGgXmEjHlqeox+b36RhG58kol0f5eLcHaPjnp"
780
          + "/lIxsYnWBfYuhoIFoZmVqg6GkkIB2ZGCAnY9xd5F+X3Gbl2xpjI"
781
          + "llcJ+gc2KEh2Jon7CBXX6WbVmJr4lfgKaAV3upiVd2rZpgZ6CUV"
782
          + "2GjomNblZFUY6mxb16YjlRprrR2aJKFVWCUooN6lIdfZYeNd3eP"
783
          + "jGtmiZd2ZIOYd1+GsZhgYpCOW2Kit4NagJ9zUYK2mmB1qYtQaKe" 
784
          + "TTlylrWhPjaVfSpHBi054pW1Hg76kZnadd0xroqZ/fJmEX2mIjo"
785
          + "iHgXl3eXl6hIyFeHV7d293hod6eIWGeHSFjoJ2foiBfIeQhnl7h"
786
          + "IJ/hIiGgn1ya3qTlYd/gHVibJCei3qHimhRbZOThJKihF1jgoBo"
787
          + "d5+fc2OIl2xUf6KAX4q4k1tnkn9VdLKscWeXkVRZmqtzYJ6saE+"
788
          + "JnFxNlb2FUH+naD+AxLFnb6J6QFibr4FslpZmYoWXj4J7gIZ8bG" 
789
          + "t8ioiFjZF5YW2Ff2p6m49nbpqVYFiFmHNporqEVW+PaVSUx6Bjd"
790
          + "aB4RW+xnF1yt6VXUpWcTkSYxotKeahkK2nDznpYlY9KRYSwlXOK"
791
          + "lnBgfZOPiIN7dneBioiCg4aAc292g4N4dYGIgHl9hH1ydIOLgny"
792
          + "GiXpzgY2BdoOZmYBvfI6MeHOEhWhbe52YhIOPfVlTb4WGjqGhe1"
793
          + "Zcen9zi66heHaQf1JVh5V2fq+yeFRjbFNjqsmgcoCDUE2QuI9sn"
794
          + "bp7RGCUdUBuv712Xo2HOz+e2KhfgqVhMWaxqXJ4n4BVbJGVhoKH"
795
          + "hHp3fIGEhoJ+fHx2cHJ2dnV+i46GhIuJd2pxfoCBjJiRgXx+end"
796
          + "9io+Dd4CSlIh5cnBjW26MlpGTloRhUWeHg3qXtJtpYHmAamqLm4"
797
          + "qEmJBlV298am2dwKZwZnprTWyzwpWBnpNSPXSbcFWb2adTUYVoJ"
798
          + "FzS8ZlVgY5AJXS7pG6Do31cdZeUhn55e4OLioODiYd9dXd7f4KF"
799
          + "hYSBenNxdnh3eH+Ki4WBgn54en6AgomSkIiDhIJ7dnd8f4KKlJe"
800
          + "Qf29pYVtke5ajnIRtYF9sgY2Up7amhG5tbGNpjq2lj4N1VzY9a4"
801
          + "yZtNzPgUtMUD5QpOXSloeFUjBelH1zvNOAQnKaPQV/9+GCf8Z7A"
802
          + "BOo5oNkoqVTRIejkn94e4aLiYSFjIt+cm5wdHV6hIaCg4iLgnV3"
803
          + "gn98jJuWhH+CfGtkeI+NfX2RnZJ7bWtjYX6aknqAmpd6Y2h2fYi"
804
          + "ZopN/eoB6aWiAjoiLnqGDZGZza197q7WYhox9T0F6rJh7nruGRF"
805
          + "mafCZM1emXa621OgBB39mPi6eeXE1vioV/gYGAf4CAgoF/gH+Bg"
806
          + "oB/";
807
          
808
function _i(o) {
809
   return (o) ? document.getElementById(o)        : null;
810
}
811
function _n(o) {
812
   return (o) ? document.getElementsByName(o)     : [];  
813
}
814
function _t(o) {
815
   return (o) ? document.getElementsByTagName(o)  : [];  
816
}
817
function _$(o) {
818
   return (o) ? document.getElementsByClassName(o): [];  
819
}
820
821
function _c(ob,id) {  
822
   switch(ob) {
823
      case 'DIV':
824
      case 'SPAN':
825
      case 'INPUT':      
826
         var ob = document.createElement(ob);      
827
         ob.id  = id;
828
         break;
829
      case 'LABEL':
830
         var ob = document.createElement(ob);  
831
         ob.setAttribute('for', id);  
832
         break;
833
      default:
834
         ob.appendChild(document.createTextNode(id));
835
   }        
836
   return ob;
837
}
838
   
839
function css(s, j) {
840
   for(var k in j) {
841
      s.style[k] = j[k];
842
   }
843
}
844
 
845
function filter_by_id() {
846
   var id   = _i('search_input').value;
847
   var list = _$('poster_id');
848
   var node;
849
   var valid;
850
   for(var i = 0; i < list.length; i++) {  
851
      node  = (list[i].parentNode.parentNode);    
852
      valid = (-1 == node.innerText.indexOf(id));    
853
      node.style.display=(valid)?'none':'inline-block';
854
      if (node.nextSibling) {
855
         node.nextSibling.style.display=(valid)?'none':'inline';
856
      }    
857
   }
858
}
859
 
860
function get_bread_number(text) {
861
   if (   (text.toLowerCase().indexOf('ebake')      != -1)
862
       || (text.toLowerCase().indexOf('q research general') != -1)) {
863
      var rx = /[^0-9]*([0-9]+)[^0-9]*/g;
864
      var arr = rx.exec(text);
865
866
      return arr && arr.length > 1 ? arr[1] : false;
867
  }
868
       
869
  return false;
870
}
871
window.colored = 0;
872
window.all_breads = {};
873
874
function make_toast(url, time) {
875
   
876
   var response;
877
   var x = new XMLHttpRequest();
878
   x.open('GET', url, true);  
879
  
880
   if (typeof window.all_breads[url] == 'undefined') {
881
      window.all_breads[url] = 0;
882
   }
883
   if (window.all_breads[url] > 751 || window.all_breads[url] == -1) {
884
    return;
885
   }
886
   if (url == '#') {
887
     var opt = _c('SPAN', "ribbit"); 
888
 
889
         var container = _i('dythreads');
890
 
891
         var colors = ["#fefefe", "green", "red"];
892
                      
893
        
894
         css(opt,{
895
            font           : 'normal normal bold 8px/15px '
896
                           + '"Courier New", Courier, Monospace',
897
            float          : 'right',
898
            color          : colors[1],
899
            cursor         : 'pointer',
900
            width          : '49px',
901
            height         : '13px',
902
            margin         : '1px',
903
            border         : '1px solid #b0b0b0',  
904
            display        : 'inline-block',
905
            filter         : 'brightness(100%)',  
906
            textAlign      : 'left',
907
            textIndent     : '9px', 
908
            borderRadius   : '3px',
909
            verticalAlign  : 'top',
910
            backgroundSize : '13px'
911
            });
912
 
913
         opt.innerHTML = "RIBBIT!"
914
                       + " <span style='font-weight:bold;color:"
915
                       + colors[2]
916
                       + ";'>" 
917
                       + "</span>";
918
  
919
 
920
         container.appendChild(opt);
921
      
922
         opt.onclick = function () {
923
             var snd = new Audio(frog); 
924
             snd.play(); 
925
         };
926
      return;
927
   }
928
   else x.onreadystatechange = function() {
929
      var that = url;
930
     
931
      if(x.readyState === 4 && x.status == 200) {
932
 
933
         response = JSON.parse(x.responseText);
934
           
935
         var container = _i('dythreads');
936
 
937
         var bread = response.posts[0];
938
         var posts = response.posts.length;
939
         var txt   = bread.sub;
940
         window.all_breads[url] = posts;
941
         if (typeof txt == 'undefined') {
942
            txt = bread.com;
943
            if (txt.length > 40) {
944
               txt = txt.substring(0,39) + '...';
945
            }
946
         } 
947
         var num = get_bread_number(txt);   
948
         window.breadno = num;
949
         // skip this bread forever         
950
         if (false == num) {
951
            window.all_breads[that] = -1;
952
            return;
953
         }
954
         
955
         var thread = _n('thread'); 
956
         var hrefs = _t('A');
957
         if (thread && thread.length)
958
         for(var i = window.colored; i < hrefs.length; i++) {
959
         
960
            if (-1 == hrefs[i].href.indexOf("res/" + thread[0].value+".html") &&
961
                -1 != hrefs[i].href.indexOf("qresearch")) {
962
               hrefs[i].style.color='#0077aa';
963
               window.colored = i; // don't color it twice.
964
            }
965
         }
966
         
967
          if (thread && thread.length && thread[0].value == bread.no) {
968
            var pfi = _i('post-form-inner');
969
           
970
            if (pfi && (posts > 750)) {
971
               css(pfi,{
972
                  border       :'3px solid red',
973
                  padding      :'3px',
974
                  opacity      : '0.7',
975
                  background   : 'url(data:image/png;base64,iVB'
976
                               + 'ORw0KGgoAAAANSUhEUgAAAAQAAAAE'
977
                               + 'CAYAAACp8Z5+AAAAGklEQVQIW2NkY'
978
                               + 'GD4D8SMQAwGcAY2AbBKDBUAVuYCBQ'
979
                               + 'Pd34sAAAAASUVORK5CYII=) repeat',
980
                  borderRadius : '10px',
981
               });
982
            }
983
         }
984
               
985
         var opts = _n('toast');
986
         if(! thread || ! thread.length) {
987
            var colors = ["#fefefe", "green", "red"];
988
         }
989
         else {
990
         var colors = ((thread[0].value == bread.no)
991
                    ? ((posts < 750)
992
                    ? ["#04ae04", "white", "black"]
993
                    : ["#ae0404", "white", "black"])
994
                    : ["#fefefe", "green", "red"]);
995
         }
996
         for(var i = 0; i < opts.length; i++) {
997
            if (opts[i].getAttribute('no') == bread.no) {
998
                  opts[i].innerHTML  = num
999
                  + " <span style='font-weight:bold;color:"
1000
                  + colors[2]  
1001
                  + "'>"
1002
                  + posts
1003
                  +"</span>";
1004
             
1005
                  opts[i].style.background = colors[0]
1006
                   + " url("
1007
                   + toast
1008
                   + ") 0px 0px/25px 25px no-repeat";  
1009
                   
1010
                  opts[i].style.backgroundSize = "13px";
1011
                 
1012
               return;
1013
            }
1014
               
1015
         }
1016
   
1017
         var opt = _c('SPAN', "" + bread.no);
1018
 
1019
         opt.setAttribute('no',bread.no);
1020
 
1021
         opt.addEventListener('mouseout',function() {
1022
            css(opt,{
1023
               cursor : 'pointer',
1024
               filter : 'brightness(100%)'
1025
            })
1026
         });
1027
         
1028
         opt.addEventListener('mouseover',function() {
1029
            css(opt,{
1030
               cursor : 'auto',
1031
               filter : 'brightness(80%)'
1032
            })          
1033
         });
1034
         
1035
         css(opt,{
1036
            font           : 'normal normal bold 8px/15px '
1037
                           + '"Courier New", Courier, Monospace',
1038
            float          : 'right',
1039
            color          : colors[1],
1040
            width          : '59px',
1041
            height         : '13px',
1042
            margin         : '1px',
1043
            border         : '1px solid #b0b0b0',  
1044
            display        : 'inline-block',
1045
            filter         : 'brightness(100%)',  
1046
            textAlign      : 'left',
1047
            textIndent     : '18px',
1048
            background     : colors[0] + ' url(' + toast
1049
                           + ') 0px 0px/25px 25px no-repeat',
1050
 
1051
            borderRadius   : '3px',
1052
            verticalAlign  : 'top',
1053
            backgroundSize : '13px'
1054
            });
1055
 
1056
         opt.innerHTML = num
1057
                       + " <span style='font-weight:bold;color:"
1058
                       + colors[2]
1059
                       + ";'>"
1060
                       + posts
1061
                       + "</span>";
1062
 
1063
         opt.id = "" + bread.no;
1064
 
1065
         container.appendChild(opt);
1066
     
1067
         opt.setAttribute('name','toast');
1068
 
1069
         opt.onclick = function () {
1070
            var no = bread.no;
1071
            if(typeof url != 'undefined') {
1072
               window.location.href =
1073
                  '/qresearch/res/' + no + '.html';
1074
            }  
1075
         };
1076
     
1077
          opt.setAttribute('old',false);
1078
        }    
1079
     };
1080
    x.send();
1081
 
1082
}
1083
 
1084
// every 60 seconds we reload from threads.json
1085
 
1086
function refresh() {
1087
   // prune expired breads and append new ones.
1088
   var opts = _n('toast');
1089
         
1090
   for(var i = 0; i < opts.length; i++) {
1091
      if (opts[i].getAttribute('old') == true) {  
1092
         container.removeChild(opts[i]);
1093
     
1094
      }
1095
      else {
1096
          opts[i].setAttribute('old',true);
1097
      }  
1098
   }
1099
     
1100
    var x = new XMLHttpRequest();
1101
    x.open('GET', "/qresearch/threads.json", true);  
1102
    x.onreadystatechange = function() {
1103
    if(x.readyState === 4 && x.status == 200) {
1104
1105
           var response = JSON.parse(x.responseText);
1106
           find_recent_bread(response);
1107
      }  
1108
    };
1109
    x.send();
1110
    trips();
1111
 
1112
        
1113
} 
1114
1115
// Count instances of Q with trips, mark untripped Q's as fakes
1116
function trips() {
1117
   var m = _i('notify');  
1118
   var t = 0;
1119
   var k, r;
1120
   var list = _$('trip');
1121
   for(var i = 0; i < list.length; i++) {
1122
   r = list[i].innerText.trim();
1123
   if (list[i].parentNode.parentNode.className !='intro') continue;
1124
   if (! r.length || r == 'FAKE') {
1125
      continue;
1126
   }
1127
   k = list[i].previousSibling.innerText.trim();
1128
      if (k == 'Q' || k == 'Q+') {
1129
      t++;      
1130
   
1131
      }
1132
   }  
1133
   if (t) {
1134
      m.innerHTML = "Q Posts (" + t + ")"; 
1135
     
1136
      if(window.t != t) {
1137
         if (window.announce) clearTimeout(window.announce);
1138
         var snd = new Audio(frog); 
1139
         snd.play();    
1140
         
1141
         window.announce = setTimeout(function() {
1142
            var z = t;
1143
            var synth = window.speechSynthesis;
1144
1145
           
1146
            var n = document.getElementsByClassName('subject')[0];
1147
            if(! n) {
1148
               window.t = z;
1149
               return;
1150
1151
            }
1152
            console.log(n);
1153
               var num = get_bread_number(n.innerHTML);
1154
    
1155
            if (chatty && synth && typeof window.breadno != 'undefined' && num ) {  
1156
               var utterance1 = new SpeechSynthesisUtterance("Q has posted in thread " + num);
1157
               synth.speak(utterance1); 
1158
            }
1159
            window.announce = 0;
1160
               m.animate([  
1161
                  { color: 'red' },
1162
                  { color: 'white' },
1163
               { color: 'blue' }
1164
               ], {  
1165
               duration: 500,
1166
               iterations: 17
1167
               });
1168
            window.t = z;
1169
         }, 3000);
1170
      }
1171
      
1172
   }
1173
  
1174
  
1175
   var list = _$('name');
1176
   for(var i = 0; i < list.length; i++) {
1177
      r = list[i].innerText.trim();
1178
      k = list[i].nextSibling;
1179
     
1180
      if (k && k.className!='trip') {
1181
         if (r == 'Q' || r == 'Q+') {
1182
            list[i].innerHTML = r
1183
            + " <span style='color:red'>[FAKE]</span>";
1184
         }
1185
      }
1186
   }
1187
   
1188
}
1189
 
1190
function find_recent_bread(board) {
1191
   var now = ~~((new Date).getTime() / 1000);
1192
   var thread;
1193
   for(var i = 0; i < board.length; i++) {
1194
      for(var j = 0; j < board[i].threads.length; j++) {
1195
         thread = board[i].threads[j];
1196
         // only show threads modified within the last 2 hours
1197
       
1198
         if (now - thread.last_modified < 7200) {
1199
            make_toast('/qresearch/res/'+thread.no + '.json',
1200
                       thread.last_modified);
1201
         }  
1202
      }  
1203
   }
1204
   
1205
}
1206
 
1207
// Post controls is loaded and we're already in a thread
1208
// append the controls at the top, but only once.
1209
var toast_init = function() {
1210
container = (_n('postcontrols'))[0]; 
1211
var dythreads = _i('dythreads');
1212
  
1213
if (! dythreads && typeof container != 'undefined') {  
1214
1215
var bl = _$('boardlist')[0];  
1216
1217
1218
   var box    = _c('DIV',   'notify');  
1219
   var bar    = _c('DIV',   'dythreads');    
1220
   var label  = _c('LABEL', 'search_input');    
1221
   var text   = _c(label,   'Search:');  
1222
   var search = _c('INPUT', 'search_input');
1223
 
1224
   container.appendChild(bar);
1225
   bar.appendChild(label);
1226
   bar.appendChild(search);  
1227
   bar.appendChild(box);      
1228
  
1229
   css(bar,{
1230
      top          : bl.clientHeight + 'px',
1231
      width        : 'calc(100% - 8px)',
1232
      height       : '16px',
1233
      margin       : '0 0 0 -16px',
1234
      zIndex       : '100',
1235
      display      : 'block',      
1236
      padding      : '0 8px 0 16px',
1237
      position     : 'fixed',
1238
      textAlign    : 'left',
1239
      background   : '#eef2ff url(/stylesheets/img/fade-blue.png)'
1240
                   + ' repeat-x 50% 0%',
1241
      borderBottom : '1px solid #b0b0b0'
1242
   });
1243
 
1244
   css(search,{
1245
      font      : 'normal normal bold 8px/13px "Courier New", '
1246
                + 'Courier, Monospace',
1247
      float     :'left',
1248
      height    :'9px',
1249
      border    :'none',
1250
      marginTop :'2px'
1251
   });
1252
 
1253
   css(label,{
1254
      font   : 'normal normal bold 8px/15px "Courier New", '
1255
             + 'Courier, Monospace',
1256
      float  :'left',
1257
      height : '13px',
1258
   });
1259
 
1260
   css(box,{
1261
      font   : 'normal normal bold 8px/13px "Courier New", '
1262
             + 'Courier, Monospace',
1263
      color  : 'red',
1264
      width  : '105px',
1265
      float  : 'left',
1266
      height : '15px',      
1267
      margin : '2px 0 0 5px'
1268
   });
1269
     
1270
 
1271
  
1272
   setInterval("refresh();", 5000);
1273
   search.onkeyup   =
1274
   search.oninput   =
1275
   search.onchange  =
1276
   search.onkeydown = function(e) {
1277
      var c;
1278
      e = e || event;
1279
      c = (e.keyCode || e.which || e.charCode || 0)
1280
      if (c == 13) e.stopPropagation();
1281
      if (window.to) clearTimeout(window.to);
1282
      window.to = setTimeout(function() {
1283
                    filter_by_id();
1284
                  }, 1000);
1285
 
1286
      return c !== 13;
1287
   };
1288
   var auto = _i('auto_update_status');
1289
   if (auto) {
1290
   
1291
      auto.setAttribute('checked',true);
1292
      //auto.setPropertyuchecked = true;
1293
   }
1294
   refresh();  
1295
   make_toast('#',0);  
1296
}
1297
}
1298
$(document).ready(toast_init);