MediaWiki:BibleGet.js: Difference between revisions

From Seeds of the Word, the encyclopedia of the influence of the Gospel on culture
No edit summary
No edit summary
 
(48 intermediate revisions by the same user not shown)
Line 1: Line 1:
//avoid duplicate bibleQuote divs
let bibleQuoteCollection = [];
let domCheckInterval = [];
let ajaxCount = 0;
let BibleQuotesDomElements = [];
(function($,mw){
(function($,mw){
$(document).ready(function(){
$(document).ready(function(){
if( $('.bibleQuoteRef').length > 0 ){
if( $('.bibleQuoteRef').length > 0 ){
console.log("There are bible quotes on this page!");
console.log("There are " + $('.bibleQuoteRef').length + " bible quotes on this page");
$('.bibleQuoteRef').each(function(){
$('.bibleQuoteRef').each(function(){
let $span = $(this);
let $el = $(this);
let version = $(this).attr('data-version');
let version = $(this).attr('data-version');
let ref = $(this).attr('data-ref');
let ref = $(this).attr('data-ref');
let tmp = (version + '/' + ref).replace(/\s/g,'');
let inline = ($(this).attr('data-inline') == "true");
let key = md5(tmp);
console.log("data-ref = " + ref + " data-inline = " + inline);
let obj = new mw.Message( mw.messages, key );
if(bibleQuoteCollection.includes(version+"/"+ref)){
if(obj.exists()){
//we already have an instance of this bible quote, avoid creating new div
console.log('Bible Quote message with key = ' + key + ' and corresponding with version/ref = ' + version + '/' + ref + ' was found');
//This will also save us an ajax call
let $bGetTIP = $('<div>', {
console.log('We seem to have already dealt with the same bible quote on this page: '+version+'/'+ref);
"class": "bibleGetQuote",
//however since the ajax calls are asynchronous, we probably won't have the actual div at the bottom of the page yet
"data-ref": ref,
//so let's look for it inside the mouseover event
"html": obj.text()
if(inline){
});
$el.on('mouseenter', function(){
$bGetTIP.append($('<p>',{"text": " — powered by BibleGet I/O","css":{"font-size":".9em","text-align":"right","font-style":"italic","font-weight":"bold","color":"gray"}}));
let $bGetTIP = $("div[data-version='"+version+"'][data-ref='"+ref+"']");
$('body').append($bGetTIP);
console.log('I found ' + $bGetTIP.length + ' div(s) at the bottom of the page with this bible quote');
$bGetTIP.removeClass('hidden');
$span.on('mouseenter', function(){
let top = $el.offset().top;
$bGetTIP.show();
let left = $el.offset().left + $el.outerWidth() + 15;
let top = $span.offset().top;
$bGetTIP.css({"top":top,"left":left});
let left = $span.offset().left + $span.outerWidth() + 15;
if($bGetTIP.hasClass('sticky') || $bGetTIP.is(':offscreen') ){
$bGetTIP.css({"top":top,"left":left});
console.log('This element would have been offscreen!');
});
//how far off the bottom of the screen are we?
/*
let rect = $bGetTIP[0].getBoundingClientRect();
$span.on('mousemove', function(){
let excessHeight = (rect.y + rect.height) - window.innerHeight;
let top = $span.offset().top;
let excessWidth = (rect.x + rect.width) - window.innerWidth;
let left = $span.offset().left + $span.outerWidth();
//if this amount is less than the distance from the top of the screen,
$bGetTIP.css({"top":top,"left":left});
// then let's just move our div up by that much
});
if(!$bGetTIP.hasClass('sticky')){
*/
if(excessWidth > 0 && excessWidth < rect.x){
$span.on('mouseleave', function(){
console.log('This element was off the right hand side of the screen');
$bGetTIP.fadeOut('slow');
let newLeft;
});
if($span.offset().left > rect.width){
newLeft = $span.offset().left - rect.width;
} else {
newLeft = $span.offset().left - rect.width / 2; //center it on the span as a last resort!
}
$bGetTIP.css({"left":newLeft});
}
if(excessHeight > 0 && excessHeight < rect.y){
console.log('This element was off the bottom of the screen');
let newTop = top - excessHeight;
$bGetTIP.css({"top":newTop});
} else if (excessHeight > rect.y){
$bGetTIP.addClass('sticky');
$bGetTIP.append($('<div>',{class:'closeButton',text:'x'}));
$bGetTIP.on('click','.closeButton',function(){
$bGetTIP.addClass('hidden');
$bGetTIP.css({"top":'',"left":''});
});
//distance of the top of the current window from the top of the document
let newTop = (window.pageYOffset || (document.documentElement || document.body.parentNode || document.body).scrollTop) + 20;
$bGetTIP.css({"top":newTop});
}
}
}
});
/*
$el.on('mousemove', function(){
let top = $span.offset().top;
let left = $span.offset().left + $span.outerWidth();
$bGetTIP.css({"top":top,"left":left});
});
*/
$el.on('mouseleave', function(){
let $bGetTIP = $("div[data-version='"+version+"'][data-ref='"+ref+"']");
//console.log('I found ' + $bGetTIP.length + ' div(s) at the bottom of the page with this bible quote');
if(!$bGetTIP.hasClass('sticky') ){
setTimeout(function(){
$bGetTIP.addClass('hidden');
$bGetTIP.css({"top":'',"left":''});
},500);
}
});
} else {
//if it's not inline we do have to deal with it again
$.ajax({
method: 'POST',
url: '../w/bgetHelper.php',
data: {
"version": version,
"ref": ref
},
success: function(data){
if(data.hasOwnProperty('html')){
$el.empty();
$el.css({"background-color":"white"});
$el.append(data.html);
$el.append($('<p>',{"text": " — powered by BibleGet I/O","css":{"font-size":".9em","text-align":"right","font-style":"italic","font-weight":"bold","color":"gray"}}));
}
},
error: function(jqXHR, textStatus, errorThrown){
console.log("There was an error while trying to communicate with the BibleGet server:")
console.log(errorThrown + ' ' + textStatus + ': ' + jqXHR.responseText);
}
}); //END ajax
}
} else {
} else {
bibleQuoteCollection.push(version+"/"+ref);
$.ajax({
$.ajax({
method: 'POST',
method: 'POST',
url: 'https://query.bibleget.io/',
url: '../w/bgetHelper.php',
data: {
data: {
"version": version,  
"version": version,  
"query": ref,
"ref": ref
"appid": 'SeminaVerbi',
"return": 'html'
},
},
success: function(data){
success: function(data){
mw.messages.set( {
console.log("data returned from ajax request:");
    key: data,
} );
let $bGetTIP = $('<div>', {
"class": "bibleGetQuote",
"data-ref": ref,
"html": data
});
$bGetTIP.append($('<p>',{"text": " — powered by BibleGet I/O","css":{"font-size":".9em","text-align":"right","font-style":"italic","font-weight":"bold","color":"gray"}}));
$('body').append($bGetTIP);
$span.on('mouseenter', function(){
$bGetTIP.show();
let top = $span.offset().top;
let left = $span.offset().left + $span.outerWidth() + 15;
$bGetTIP.css({"top":top,"left":left});
});
/*
$span.on('mousemove', function(){
let top = $span.offset().top;
let left = $span.offset().left + $span.outerWidth();
$bGetTIP.css({"top":top,"left":left});
});
*/
$span.on('mouseleave', function(){
$bGetTIP.fadeOut('slow');
});
console.log("Injected Bible quote for ref = " + ref + " with value obtained from BibleGet service:");
console.log(data);
console.log(data);
if(data.hasOwnProperty('html')){
if(inline){
let $bGetTIP = $('<div>', {
"class": "bibleGetQuote",
"data-version": version,
"data-ref": ref,
"html": data.html
});
$bGetTIP.append($('<p>',{"text": " — powered by BibleGet I/O","css":{"font-size":".9em","text-align":"right","font-style":"italic","font-weight":"bold","color":"gray"}}));
//$('body').append($bGetTIP);
BibleQuotesDomElements.push($bGetTIP);
$el.on('mouseenter', function(){
$bGetTIP.removeClass('hidden');
let top = $el.offset().top;
let left = $el.offset().left + $el.outerWidth() + 15;
$bGetTIP.css({"top":top,"left":left});
if($bGetTIP.hasClass('sticky') || $bGetTIP.is(':offscreen') ){
//are we off the bottom or the right side of the screen, and how much?
let rect = $bGetTIP[0].getBoundingClientRect();
let excessHeight = (rect.y + rect.height) - window.innerHeight;
let excessWidth = (rect.x + rect.width) - window.innerWidth;
//if this amount is less than the distance from the top of the screen,
// then let's just move our div up by that much
if(!$bGetTIP.hasClass('sticky')){
if(excessWidth > 0 && excessWidth < rect.x){
console.log('This element was off the right hand side of the screen');
let newLeft;
if($span.offset().left > rect.width){
newLeft = $span.offset().left - rect.width;
} else {
newLeft = $span.offset().left - rect.width / 2; //center it on the span as a last resort!
}
$bGetTIP.css({"left":newLeft});
}
if(excessHeight > 0 && excessHeight < rect.y){
console.log('This element was off the bottom of the screen');
let newTop = top - excessHeight;
$bGetTIP.css({"top":newTop});
} else if (excessHeight >= rect.y){
$bGetTIP.addClass('sticky');
$bGetTIP.append($('<div>',{class:'closeButton',text:'x'}));
$bGetTIP.on('click','.closeButton',function(){
$bGetTIP.addClass('hidden');
$bGetTIP.css({"top":'',"left":''});
});
//distance of the top of the current window from the top of the document
let newTop = (window.pageYOffset || (document.documentElement || document.body.parentNode || document.body).scrollTop) + 20;
$bGetTIP.css({"top":newTop});
}
}
}
});
/*
$el.on('mousemove', function(){
let top = $span.offset().top;
let left = $span.offset().left + $span.outerWidth();
$bGetTIP.css({"top":top,"left":left});
});
*/
$el.on('mouseleave', function(){
if(!$bGetTIP.hasClass('sticky') ){
setTimeout(function(){
$bGetTIP.addClass('hidden');
$bGetTIP.css({"top":'',"left":''});
},500);
}
});
} else {
$el.empty();
$el.css({"background-color":"white"});
$el.append(data.html);
$el.append($('<p>',{"text": " — powered by BibleGet I/O","css":{"font-size":".9em","text-align":"right","font-style":"italic","font-weight":"bold","color":"gray"}}));
}
}
//console.log("Injected Bible quote for ref = " + ref + " with value obtained from BibleGet service:");
},
},
error: function(jqXHR, textStatus, errorThrown){
error: function(jqXHR, textStatus, errorThrown){
Line 82: Line 203:
console.log(errorThrown + ' ' + textStatus + ': ' + jqXHR.responseText);
console.log(errorThrown + ' ' + textStatus + ': ' + jqXHR.responseText);
}
}
});
}); //END ajax
}
}); //END for each
$(document).ajaxStop(function(){
console.log("ajaxStop has fired " + ++ajaxCount + " time(s)");
//let's create a check for all elements before doing any further manipulation
if(domCheckInterval.length === 0){
//We have decided not to append anything to the document during the ajax calls
//We have simply collected the elements to append in an array
//So let's append them now...
$('body').append(BibleQuotesDomElements);
domCheckInterval.push(setInterval(onBGetDomElementsReady,100));
}
}
});
}); //END document ajaxStop
}
}
});
})(jQuery,mw);


(function (global) {
}); //END document ready


  var md5cycle = function (x, k) {
})(jQuery,mw);
    var a = x[0],
let unicodeChrClass = /^([0-9])([A-Za-z\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B4\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC].*)$/;
      b = x[1],
let checkDomElements = function(){
      c = x[2],
let domElementsReady = true;
      d = x[3];
let version,ref = null;
 
for(let el of bibleQuoteCollection){
    a = ff(a, b, c, d, k[0], 7, -680876936);
let [version,ref] = el.split("/");
    d = ff(d, a, b, c, k[1], 12, -389564586);
if($("div[data-version='"+version+"'][data-ref='"+ref+"']").length === 0){
    c = ff(c, d, a, b, k[2], 17, 606105819);
console.log("expected dom element [data-version='"+version+"'][data-ref='"+ref+"'] does not exist yet...");
    b = ff(b, c, d, a, k[3], 22, -1044525330);
return false;
    a = ff(a, b, c, d, k[4], 7, -176418897);
}
    d = ff(d, a, b, c, k[5], 12, 1200080426);
}
    c = ff(c, d, a, b, k[6], 17, -1473231341);
return domElementsReady;
    b = ff(b, c, d, a, k[7], 22, -45705983);
};
    a = ff(a, b, c, d, k[8], 7, 1770035416);
let onBGetDomElementsReady = function(){
    d = ff(d, a, b, c, k[9], 12, -1958414417);
if(checkDomElements() === true){
    c = ff(c, d, a, b, k[10], 17, -42063);
console.log('All expected dom elements are now accounted for!');
    b = ff(b, c, d, a, k[11], 22, -1990404162);
for(let interval of domCheckInterval){
    a = ff(a, b, c, d, k[12], 7, 1804603682);
clearInterval(interval);
    d = ff(d, a, b, c, k[13], 12, -40341101);
}
    c = ff(c, d, a, b, k[14], 17, -1502002290);
//However we still seem to be running into issues with being able to do calculations on elements
    b = ff(b, c, d, a, k[15], 22, 1236535329);
//So let's maybe wait just a little bit before doing our calculations?
 
setTimeout(doFurtherDomManipulation,300);
    a = gg(a, b, c, d, k[1], 5, -165796510);
}
    d = gg(d, a, b, c, k[6], 9, -1069501632);
};
    c = gg(c, d, a, b, k[11], 14, 643717713);
let doFurtherDomManipulation = function(){
    b = gg(b, c, d, a, k[0], 20, -373897302);
jQuery('.bibleGetQuote').each(function(){
    a = gg(a, b, c, d, k[5], 5, -701558691);
console.log("Now manipulating contents of div [data-version='" + jQuery(this).attr('data-version') + "'] [data-ref='" + jQuery(this).attr('data-ref') + "']");
    d = gg(d, a, b, c, k[10], 9, 38016083);
    c = gg(c, d, a, b, k[15], 14, -660478335);
jQuery(this).find('.versesParagraph .verseText').each(function(){
    b = gg(b, c, d, a, k[4], 20, -405537848);
jQuery(this).contents().first().filter(function(){
    a = gg(a, b, c, d, k[9], 5, 568446438);
return (
    d = gg(d, a, b, c, k[14], 9, -1019803690);
this.nodeType === 1 && (  
    c = gg(c, d, a, b, k[3], 14, -187363961);
jQuery(this).hasClass('pof') || jQuery(this).hasClass('po') || jQuery(this).hasClass('pol') || jQuery(this).hasClass('pos') || jQuery(this).hasClass('poif') || jQuery(this).hasClass('poi') || jQuery(this).hasClass('poil')  
    b = gg(b, c, d, a, k[8], 20, 1163531501);
)
    a = gg(a, b, c, d, k[13], 5, -1444681467);
)  
    d = gg(d, a, b, c, k[2], 9, -51403784);
}).css({"display":"inline-block","position":"relative","left":function(index){ return "-"+jQuery(this).parent('.verseText').prev('.verseNum').outerWidth(true)+"px"; } });  
    c = gg(c, d, a, b, k[7], 14, 1735328473);
//HERE IS THE LOGIC:
    b = gg(b, c, d, a, k[12], 20, -1926607734);
//IF the (first node) following a .verseText node is not a text node,
 
//AND it IS an element node with class pof,poif,po,poi,poil...  
    a = hh(a, b, c, d, k[5], 4, -378558);
    d = hh(d, a, b, c, k[8], 11, -2022574463);
//THEN change the css display of that (first node) to "inline-block" and left position it removing the width of the span with the verse number
    c = hh(c, d, a, b, k[11], 16, 1839030562);
//TODO: shouldn't we do this any time it's the first node within a verseText node, since it follows a verseNum?
    b = hh(b, c, d, a, k[14], 23, -35309556);
    a = hh(a, b, c, d, k[1], 4, -1530992060);
jQuery(this).contents().first().filter(function(){
    d = hh(d, a, b, c, k[4], 11, 1272893353);
return (
    c = hh(c, d, a, b, k[7], 16, -155497632);
this.nodeType === 1 && (
    b = hh(b, c, d, a, k[10], 23, -1094730640);
( jQuery(this).hasClass('pof') || jQuery(this).hasClass('po') || jQuery(this).hasClass('pol') || jQuery(this).hasClass('pos') || jQuery(this).hasClass('poif') || jQuery(this).hasClass('poi') || jQuery(this).hasClass('poil') )
    a = hh(a, b, c, d, k[13], 4, 681279174);
&& jQuery(this).parent('.verseText').prevAll('.verseText').length > 0
    d = hh(d, a, b, c, k[0], 11, -358537222);
&& (
    c = hh(c, d, a, b, k[3], 16, -722521979);
(jQuery(this).parent('.verseText').prevAll('.verseText:first').contents().last()[0].nodeType === 1
    b = hh(b, c, d, a, k[6], 23, 76029189);
  && jQuery(this).parent('.verseText').prevAll('.verseText:first').contents().last().css('display') == 'inline-block'
    a = hh(a, b, c, d, k[9], 4, -640364487);
)
    d = hh(d, a, b, c, k[12], 11, -421815835);
||
    c = hh(c, d, a, b, k[15], 16, 530742520);
jQuery(this).parent('.verseText').prevAll('.verseText:first').contents().last()[0].nodeType === 3
    b = hh(b, c, d, a, k[2], 23, -995338651);
)
 
)
    a = ii(a, b, c, d, k[0], 6, -198630844);
)
    d = ii(d, a, b, c, k[7], 10, 1126891415);
}).parent('.verseText').prev('.verseNum').before('<br>');  
    c = ii(c, d, a, b, k[14], 15, -1416354905);
//HERE IS THE LOGIC:
    b = ii(b, c, d, a, k[5], 21, -57434055);
//IF the (first node) following a .verseText node is not a text node,
    a = ii(a, b, c, d, k[12], 6, 1700485571);
//AND it IS an element node with class po  
    d = ii(d, a, b, c, k[3], 10, -1894986606);
//AND this is not the first .verseText node of a chapter
    c = ii(c, d, a, b, k[10], 15, -1051523);
//AND the last node of the previous .verseText node has css display:inline-block
    b = ii(b, c, d, a, k[1], 21, -2054922799);
//THEN add a newline before the preceding .verseNum node containing the verse number
    a = ii(a, b, c, d, k[8], 6, 1873313359);
    d = ii(d, a, b, c, k[15], 10, -30611744);
//HERE INSTEAD WE REMOVE ANY EXTRA SPACES AT THE BEGINNING OF A VERSE...
    c = ii(c, d, a, b, k[6], 15, -1560198380);
jQuery(this).html( jQuery(this).html().replace( /^\s/, '' ) );
    b = ii(b, c, d, a, k[13], 21, 1309151649);
    a = ii(a, b, c, d, k[4], 6, -145523070);
});
    d = ii(d, a, b, c, k[11], 10, -1120210379);
//Let's also make the poetic verses that have speaker tags line up a little better by removing a tad bit of the indent...
    c = ii(c, d, a, b, k[2], 15, 718787259);
jQuery(this).find(".pof,.po,.pol,.pos,.poif,.poi,.poil").filter(function(){ return jQuery(this).children('.speaker').length !== 0 })
    b = ii(b, c, d, a, k[9], 21, -343485551);
.css("left",function(i,current){
 
return (parseInt(current) - 4 || -15 );
    x[0] = add32(a, x[0]);
}).css("position","relative");
    x[1] = add32(b, x[1]);
    x[2] = add32(c, x[2]);
//AND HERE WE ADD A SPACE BETWEEN NUMBER AND REST OF BOOK NAME TO THOSE BIBLE BOOKS THAT HAVE AN INITIAL NUMBER
    x[3] = add32(d, x[3]);
jQuery(this).find('.bookChapter').each(function(){
 
if( unicodeChrClass.test( jQuery(this).html() ) ){
  }
jQuery(this).html( jQuery(this).html().replace( unicodeChrClass, '$1 $2' ) );
 
}
  var cmn = function (q, a, b, x, s, t) {
});
    a = add32(add32(a, q), add32(x, t));
    return add32((a << s) | (a >>> (32 - s)), b);
jQuery(this).addClass('ready hidden');
  }
});
 
};
  var ff = function (a, b, c, d, x, s, t) {
    return cmn((b & c) | ((~b) & d), a, b, x, s, t);
  }
 
  var gg = function (a, b, c, d, x, s, t) {
    return cmn((b & d) | (c & (~d)), a, b, x, s, t);
  }
 
  var hh = function (a, b, c, d, x, s, t) {
    return cmn(b ^ c ^ d, a, b, x, s, t);
  }
 
  var ii = function (a, b, c, d, x, s, t) {
    return cmn(c ^ (b | (~d)), a, b, x, s, t);
  }
 
  var md51 = function (s) {
    var txt = '',
      n = s.length,
      state = [1732584193, -271733879, -1732584194, 271733878],
      i;
    for (i = 64; i <= s.length; i += 64) {
      md5cycle(state, md5blk(s.substring(i - 64, i)));
    }
    s = s.substring(i - 64);
    var tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
    for (i = 0; i < s.length; i++)
      tail[i >> 2] |= s.charCodeAt(i) << ((i % 4) << 3);
    tail[i >> 2] |= 0x80 << ((i % 4) << 3);
    if (i > 55) {
      md5cycle(state, tail);
      for (i = 0; i < 16; i++) tail[i] = 0;
    }
    tail[14] = n * 8;
    md5cycle(state, tail);
    return state;
  }
 
  /* there needs to be support for Unicode here,
  * unless we pretend that we can redefine the MD-5
  * algorithm for multi-byte characters (perhaps
  * by adding every four 16-bit characters and
  * shortening the sum to 32 bits). Otherwise
  * I suggest performing MD-5 as if every character
  * was two bytes--e.g., 0040 0025 = @%--but then
  * how will an ordinary MD-5 sum be matched?
  * There is no way to standardize text to something
  * like UTF-8 before transformation; speed cost is
  * utterly prohibitive. The JavaScript standard
  * itself needs to look at this: it should start
  * providing access to strings as preformed UTF-8
  * 8-bit unsigned value arrays.
  */
  var md5blk = function (s) { /* I figured global was faster.   */
    var md5blks = [],
      i; /* Andy King said do it this way. */
    for (i = 0; i < 64; i += 4) {
      md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24);
    }
    return md5blks;
  }
 
  var hex_chr = '0123456789abcdef'.split('');
 
  var rhex = function (n) {
    var s = '',
      j = 0;
    for (; j < 4; j++)
      s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] + hex_chr[(n >> (j * 8)) & 0x0F];
    return s;
  }
 
  var hex = function (x) {
    for (var i = 0; i < x.length; i++)
      x[i] = rhex(x[i]);
    return x.join('');
  }
 
  var md5 = global.md5 = function (s) {
    return hex(md51(s));
  }
 
  /* this function is much faster,
  so if possible we use it. Some IEs
  are the only ones I know of that
  need the idiotic second function,
  generated by an if clause. */
 
  var add32 = function (a, b) {
    return (a + b) & 0xFFFFFFFF;
  }
 
  if (md5('hello') != '5d41402abc4b2a76b9719d911017c592') {
    add32 = function (x, y) {
      var lsw = (x & 0xFFFF) + (y & 0xFFFF),
        msw = (x >> 16) + (y >> 16) + (lsw >> 16);
      return (msw << 16) | (lsw & 0xFFFF);
    }
  }


})(window);
jQuery.expr.filters.offscreen = function(el) {
  let rect = el.getBoundingClientRect();
  return ( rect.x < 0 || rect.y < 0 ||
          (rect.x + rect.width) > window.innerWidth ||
          (rect.y + rect.height) > window.innerHeight );
};

Latest revision as of 10:15, September 26, 2020

//avoid duplicate bibleQuote divs
let bibleQuoteCollection = [];
let domCheckInterval = [];
let ajaxCount = 0;
let BibleQuotesDomElements = [];
(function($,mw){
	$(document).ready(function(){
		if( $('.bibleQuoteRef').length > 0 ){
			console.log("There are " + $('.bibleQuoteRef').length + " bible quotes on this page");
			$('.bibleQuoteRef').each(function(){
				let $el = $(this);
				let version = $(this).attr('data-version');
				let ref = $(this).attr('data-ref');
				let inline = ($(this).attr('data-inline') == "true");
				console.log("data-ref = " + ref + " data-inline = " + inline);
				if(bibleQuoteCollection.includes(version+"/"+ref)){
					//we already have an instance of this bible quote, avoid creating new div
					//This will also save us an ajax call
					console.log('We seem to have already dealt with the same bible quote on this page: '+version+'/'+ref);
					//however since the ajax calls are asynchronous, we probably won't have the actual div at the bottom of the page yet
					//so let's look for it inside the mouseover event
					if(inline){
						$el.on('mouseenter', function(){
							let $bGetTIP = $("div[data-version='"+version+"'][data-ref='"+ref+"']");
							console.log('I found ' + $bGetTIP.length + ' div(s) at the bottom of the page with this bible quote');
							$bGetTIP.removeClass('hidden');
							let top = $el.offset().top;
							let left = $el.offset().left + $el.outerWidth() + 15;
							$bGetTIP.css({"top":top,"left":left});
							if($bGetTIP.hasClass('sticky') || $bGetTIP.is(':offscreen') ){
								console.log('This element would have been offscreen!');
								//how far off the bottom of the screen are we?
								let rect = $bGetTIP[0].getBoundingClientRect();
								let excessHeight = (rect.y + rect.height) - window.innerHeight;
								let excessWidth = (rect.x + rect.width) - window.innerWidth;
								//if this amount is less than the distance from the top of the screen,
								// then let's just move our div up by that much
								if(!$bGetTIP.hasClass('sticky')){
									if(excessWidth > 0 && excessWidth < rect.x){
										console.log('This element was off the right hand side of the screen');
										let newLeft;
										if($span.offset().left > rect.width){
											newLeft = $span.offset().left - rect.width;
										} else {
											newLeft = $span.offset().left - rect.width / 2; //center it on the span as a last resort!
										}
										$bGetTIP.css({"left":newLeft});
									}
									if(excessHeight > 0 && excessHeight < rect.y){
										console.log('This element was off the bottom of the screen');
										let newTop = top - excessHeight;
										$bGetTIP.css({"top":newTop});
									} else if (excessHeight > rect.y){
										$bGetTIP.addClass('sticky');
										$bGetTIP.append($('<div>',{class:'closeButton',text:'x'}));
										$bGetTIP.on('click','.closeButton',function(){
											$bGetTIP.addClass('hidden');
											$bGetTIP.css({"top":'',"left":''});
										});
										//distance of the top of the current window from the top of the document
										let newTop = (window.pageYOffset || (document.documentElement || document.body.parentNode || document.body).scrollTop) + 20;
										$bGetTIP.css({"top":newTop});
									}
								}
							}
						});
						
						/*
						$el.on('mousemove', function(){
							let top = $span.offset().top;
							let left = $span.offset().left + $span.outerWidth();
							$bGetTIP.css({"top":top,"left":left});
						});
						*/
						
						$el.on('mouseleave', function(){
							let $bGetTIP = $("div[data-version='"+version+"'][data-ref='"+ref+"']");
							//console.log('I found ' + $bGetTIP.length + ' div(s) at the bottom of the page with this bible quote');
							if(!$bGetTIP.hasClass('sticky') ){
								setTimeout(function(){ 
									$bGetTIP.addClass('hidden');
									$bGetTIP.css({"top":'',"left":''});
								},500);
							}
						});
					} else {
						//if it's not inline we do have to deal with it again
						$.ajax({
							method: 'POST',
							url: '../w/bgetHelper.php',
							data: {
								"version": version, 
								"ref": ref
							},
							success: function(data){
								if(data.hasOwnProperty('html')){
									$el.empty();
									$el.css({"background-color":"white"});
									$el.append(data.html);
									$el.append($('<p>',{"text": " — powered by BibleGet I/O","css":{"font-size":".9em","text-align":"right","font-style":"italic","font-weight":"bold","color":"gray"}}));
								}
							},
							error: function(jqXHR, textStatus, errorThrown){
								console.log("There was an error while trying to communicate with the BibleGet server:")
								console.log(errorThrown + ' ' + textStatus + ': ' + jqXHR.responseText);
							}
						}); //END ajax
					}
				} else {
					bibleQuoteCollection.push(version+"/"+ref);
					$.ajax({
						method: 'POST',
						url: '../w/bgetHelper.php',
						data: {
							"version": version, 
							"ref": ref
						},
						success: function(data){
							console.log("data returned from ajax request:");
							console.log(data);
							if(data.hasOwnProperty('html')){
								if(inline){
									let $bGetTIP = $('<div>', {
										"class": "bibleGetQuote",
										"data-version": version,
										"data-ref": ref,
										"html": data.html
									});
									$bGetTIP.append($('<p>',{"text": " — powered by BibleGet I/O","css":{"font-size":".9em","text-align":"right","font-style":"italic","font-weight":"bold","color":"gray"}}));
									
									//$('body').append($bGetTIP);
									BibleQuotesDomElements.push($bGetTIP);
									
									$el.on('mouseenter', function(){
										$bGetTIP.removeClass('hidden');
										let top = $el.offset().top;
										let left = $el.offset().left + $el.outerWidth() + 15;
										$bGetTIP.css({"top":top,"left":left});
										if($bGetTIP.hasClass('sticky') || $bGetTIP.is(':offscreen') ){
											//are we off the bottom or the right side of the screen, and how much?
											let rect = $bGetTIP[0].getBoundingClientRect();
											let excessHeight = (rect.y + rect.height) - window.innerHeight;
											let excessWidth = (rect.x + rect.width) - window.innerWidth;
											//if this amount is less than the distance from the top of the screen,
											// then let's just move our div up by that much
											if(!$bGetTIP.hasClass('sticky')){
												if(excessWidth > 0 && excessWidth < rect.x){
													console.log('This element was off the right hand side of the screen');
													let newLeft;
													if($span.offset().left > rect.width){
														newLeft = $span.offset().left - rect.width;
													} else {
														newLeft = $span.offset().left - rect.width / 2; //center it on the span as a last resort!
													}
													$bGetTIP.css({"left":newLeft});
												}
												if(excessHeight > 0 && excessHeight < rect.y){
													console.log('This element was off the bottom of the screen');
													let newTop = top - excessHeight;
													$bGetTIP.css({"top":newTop});
												} else if (excessHeight >= rect.y){
													$bGetTIP.addClass('sticky');
													$bGetTIP.append($('<div>',{class:'closeButton',text:'x'}));
													$bGetTIP.on('click','.closeButton',function(){
														$bGetTIP.addClass('hidden');
														$bGetTIP.css({"top":'',"left":''});
													});
													//distance of the top of the current window from the top of the document
													let newTop = (window.pageYOffset || (document.documentElement || document.body.parentNode || document.body).scrollTop) + 20;
													$bGetTIP.css({"top":newTop});
												}
											}
										}
									});
									
									/*
									$el.on('mousemove', function(){
										let top = $span.offset().top;
										let left = $span.offset().left + $span.outerWidth();
										$bGetTIP.css({"top":top,"left":left});
									});
									*/
									
									$el.on('mouseleave', function(){
										if(!$bGetTIP.hasClass('sticky') ){
											setTimeout(function(){ 
												$bGetTIP.addClass('hidden');
												$bGetTIP.css({"top":'',"left":''});
											},500);
										}
									});
								} else {
									$el.empty();
									$el.css({"background-color":"white"});
									$el.append(data.html);
									$el.append($('<p>',{"text": " — powered by BibleGet I/O","css":{"font-size":".9em","text-align":"right","font-style":"italic","font-weight":"bold","color":"gray"}}));
								}
							}
							//console.log("Injected Bible quote for ref = " + ref + " with value obtained from BibleGet service:");
						},
						error: function(jqXHR, textStatus, errorThrown){
							console.log("There was an error while trying to communicate with the BibleGet server:")
							console.log(errorThrown + ' ' + textStatus + ': ' + jqXHR.responseText);
						}
					}); //END ajax
				}
			}); //END for each
			
			$(document).ajaxStop(function(){
				console.log("ajaxStop has fired " + ++ajaxCount + " time(s)");
				
				//let's create a check for all elements before doing any further manipulation
				if(domCheckInterval.length === 0){
					//We have decided not to append anything to the document during the ajax calls
					//We have simply collected the elements to append in an array
					//So let's append them now...
					$('body').append(BibleQuotesDomElements);
					domCheckInterval.push(setInterval(onBGetDomElementsReady,100));
				}
			}); //END document ajaxStop
		}

	}); //END document ready

})(jQuery,mw);
let unicodeChrClass = /^([0-9])([A-Za-z\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B4\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FD5\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AD\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC].*)$/;
let checkDomElements = function(){
	let domElementsReady = true;
	let version,ref = null;
	for(let el of bibleQuoteCollection){
		let [version,ref] = el.split("/");
		if($("div[data-version='"+version+"'][data-ref='"+ref+"']").length === 0){
			console.log("expected dom element [data-version='"+version+"'][data-ref='"+ref+"'] does not exist yet...");
			return false;
		}
	}
	return domElementsReady;
};
let onBGetDomElementsReady = function(){
	if(checkDomElements() === true){
		console.log('All expected dom elements are now accounted for!');
		for(let interval of domCheckInterval){
			clearInterval(interval);
		}
		//However we still seem to be running into issues with being able to do calculations on elements
		//So let's maybe wait just a little bit before doing our calculations?
		setTimeout(doFurtherDomManipulation,300);
	}
};
let doFurtherDomManipulation = function(){
	jQuery('.bibleGetQuote').each(function(){
		console.log("Now manipulating contents of div [data-version='" + jQuery(this).attr('data-version') + "'] [data-ref='" + jQuery(this).attr('data-ref') + "']");
		
		jQuery(this).find('.versesParagraph .verseText').each(function(){
			jQuery(this).contents().first().filter(function(){ 
				return ( 
					this.nodeType === 1 && ( 
						jQuery(this).hasClass('pof') || jQuery(this).hasClass('po') || jQuery(this).hasClass('pol') || jQuery(this).hasClass('pos') || jQuery(this).hasClass('poif') || jQuery(this).hasClass('poi') || jQuery(this).hasClass('poil') 
					)
				) 
			}).css({"display":"inline-block","position":"relative","left":function(index){ return "-"+jQuery(this).parent('.verseText').prev('.verseNum').outerWidth(true)+"px"; } });    
			//HERE IS THE LOGIC:
			//IF the (first node) following a .verseText node is not a text node,
			//AND it IS an element node with class pof,poif,po,poi,poil...	  
	
			//THEN change the css display of that (first node) to "inline-block" and left position it removing the width of the span with the verse number 
			//TODO: shouldn't we do this any time it's the first node within a verseText node, since it follows a verseNum?
	
			jQuery(this).contents().first().filter(function(){
				return (
						this.nodeType === 1 && (
								( jQuery(this).hasClass('pof') || jQuery(this).hasClass('po') || jQuery(this).hasClass('pol') || jQuery(this).hasClass('pos') || jQuery(this).hasClass('poif') || jQuery(this).hasClass('poi') || jQuery(this).hasClass('poil') ) 
								&& jQuery(this).parent('.verseText').prevAll('.verseText').length > 0
								&& (
									(jQuery(this).parent('.verseText').prevAll('.verseText:first').contents().last()[0].nodeType === 1
									  && jQuery(this).parent('.verseText').prevAll('.verseText:first').contents().last().css('display') == 'inline-block'
									)
									||
									jQuery(this).parent('.verseText').prevAll('.verseText:first').contents().last()[0].nodeType === 3
								)
						)
				)
			}).parent('.verseText').prev('.verseNum').before('<br>'); 
			//HERE IS THE LOGIC:
			//IF the (first node) following a .verseText node is not a text node,
			//AND it IS an element node with class po	  
			//AND this is not the first .verseText node of a chapter
			//AND the last node of the previous .verseText node has css display:inline-block	
			//THEN add a newline before the preceding .verseNum node containing the verse number 
	
			//HERE INSTEAD WE REMOVE ANY EXTRA SPACES AT THE BEGINNING OF A VERSE...
			jQuery(this).html( jQuery(this).html().replace( /^\s/, '' ) );
					
		});	
		//Let's also make the poetic verses that have speaker tags line up a little better by removing a tad bit of the indent...
		jQuery(this).find(".pof,.po,.pol,.pos,.poif,.poi,.poil").filter(function(){ return jQuery(this).children('.speaker').length !== 0 })
		.css("left",function(i,current){
			return (parseInt(current) - 4 || -15 );
		}).css("position","relative");
	
		//AND HERE WE ADD A SPACE BETWEEN NUMBER AND REST OF BOOK NAME TO THOSE BIBLE BOOKS THAT HAVE AN INITIAL NUMBER
		jQuery(this).find('.bookChapter').each(function(){
			if( unicodeChrClass.test( jQuery(this).html() ) ){
				jQuery(this).html( jQuery(this).html().replace( unicodeChrClass, '$1 $2' ) );
			}
		});
		
		jQuery(this).addClass('ready hidden');
	});
};

jQuery.expr.filters.offscreen = function(el) {
  let rect = el.getBoundingClientRect();
  return ( rect.x < 0 || rect.y < 0 ||
          (rect.x + rect.width) > window.innerWidth ||
          (rect.y + rect.height) > window.innerHeight );
};