pimeyesJS

Mods to make pimeyes.com work better for both premium and free users

当前为 2022-05-10 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name pimeyesJS
  3. // @namespace https://github.com/deltabravozulu/usefulUserScripts
  4. // @match *://pimeyes.com/en/search/*
  5. // @grant none
  6. // @version 9.6.9_420.1
  7. // @author DeltaBravoZulu
  8. // @description Mods to make pimeyes.com work better for both premium and free users
  9. // @description 2022-05-09T18:04:20
  10. // @require https://cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js
  11. // @run-at document-idle
  12. // @license PayMe
  13. // ==/UserScript==
  14. ///////////////////////////////////////////////////////////////////////////////////
  15. ///////////////////////////////////////////////////////////////////////////////////
  16. //// A script to allow automatic image loading, page improvements via CSS, ////
  17. //// explicit result isolation, and other neat stuff on pimeyes.com ////
  18. //// by DeltaBravoZulu ////
  19. ///////////////////////////////////////////////////////////////////////////////////
  20. ///////////////////////////////////////////////////////////////////////////////////
  21.  
  22. ///////////////////////////////////////
  23. // Script Initialization //
  24. ///////////////////////////////////////
  25. /*
  26. ** Invokes injection of buttons
  27. ** Sets initial variables and gathers stats
  28. */
  29.  
  30. //Make sure page loads before starting
  31. new MutationObserver(check).observe(document, {
  32. childList: true,
  33. subtree: true,
  34. });
  35.  
  36. function check(changes, observer) {
  37. if (
  38. document.querySelector(
  39. "#results > div > div > div.top-slot > div > div > div > button:nth-child(5) > img"
  40. )
  41. ) {
  42. observer.disconnect();
  43. explicitButts();
  44. scrollButts();
  45. importButts();
  46. exportButts();
  47. explicitCount = 0;
  48. explicitStats();
  49. scrolled = 0;
  50. //Gets the Open Graph url which was removed in June
  51. var ogUrl=document.querySelectorAll('meta[property="og:url"]')[0].content.replace('https://pimeyes.com/en','')
  52. //Adds the URL to the URL bar so you can copypaste it
  53. var newurl = window.location.protocol + "//" + window.location.host + window.location.pathname + ogUrl;
  54. window.history.pushState({path:newurl},'',newurl);
  55. //Adds scroll explicit counter
  56. scrollResultsUpdateListener();
  57. //Adds mousedown event listener to highlight text during popup for copying
  58. clickThumb = document.querySelector("div.results-grid");
  59. clickThumb.addEventListener("mousedown", highlightUrl);
  60. //Removes the 'Pay 299/month' overlay if hitting the Deep Search button
  61. document.querySelector("div[data-v-69882821]").remove();
  62. //Makes rows wider and shows images better
  63. //This is broken//document.querySelector("div.results-grid").style.width="90";
  64. document.querySelector("div.results-grid").style.minWidth="60%";
  65. document.querySelector("div.results-grid").style.maxWidth="100%";
  66. document.querySelector("div.results-grid").style.gridTemplateColumns = "repeat(5,20%)";
  67. document.querySelector("div.results-grid").style.gridAutoRows = "auto";
  68.  
  69. }
  70. }
  71.  
  72. //Alternative way of doing it
  73. /*
  74. var observer = new MutationObserver(resetTimer);
  75. var timer = setTimeout(action, 2000, observer); // wait for the page to stay still for 2 seconds
  76. observer.observe(document, {childList: true, subtree: true});
  77. function resetTimer(changes, observer) {
  78. clearTimeout(timer);
  79. timer = setTimeout(action, 2000, observer);
  80. }
  81.  
  82. function action(o) {
  83. o.disconnect();
  84. observer.disconnect();
  85. explicitButts();
  86. scrollButts();
  87. explicitCount = 0;
  88. explicitStats();
  89. scrolled = 0;
  90. scrollResultsUpdateListener();
  91. }
  92. */
  93.  
  94. ///////////////////////////////////////
  95. // Button Injections //
  96. ///////////////////////////////////////
  97. /*
  98. ** Adds buttons to invoke scrolling and removal
  99. ** Sets initial variable and gathers stats
  100. */
  101.  
  102. //Injects a button that, when pressed, will scroll to the bottom of the page to load all images, then remove all images that are not explicit
  103. function explicitButts() {
  104. console.log("Adding 18+ Button");
  105. var oldButtons = document.querySelector(
  106. "#results > div > div > div.top-slot > div > div > div > button:last-child"
  107. );
  108. var explicitButtons = oldButtons.parentElement;
  109. var iconHtml =
  110. '<button data-v-4ccff48d="" type="button" class="default icon-only" data-v-46dbee4d="" id="18Button" title="Scroll to the bottom and remove non-explicit images"><img data-v-4ccff48d="" src="data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMzEwLjkgMzEwLjkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTk1IDIxMS40di04OS4zSDc0LjRWOTkuMmg0OS4xdjExMi4yem0xMzUuNi04My4yYzAgOS44LTUuMyAxOC40LTE0LjEgMjMuMiAxMi4zIDUuMSAyMCAxNS44IDIwIDI4LjMgMCAyMC4yLTE3LjkgMzMtNDUuOSAzM3MtNDUuOS0xMi42LTQ1LjktMzIuNWMwLTEyLjggOC4zLTIzLjcgMjEuMy0yOC44LTkuNC01LjMtMTUuNS0xNC4yLTE1LjUtMjQgMC0xNy45IDE1LjctMjkuMyA0MC0yOS4zIDI0LjUuMSA0MC4xIDExLjcgNDAuMSAzMC4xem0tNTkuMSA0OS4yYzAgOS40IDYuNyAxNC43IDE5IDE0LjdzMTkuMi01LjEgMTkuMi0xNC43YzAtOS4zLTYuOS0xNC42LTE5LjItMTQuNnMtMTkgNS4zLTE5IDE0LjZ6bTIuOS00Ny42YzAgOCA1LjggMTIuNSAxNi4yIDEyLjVzMTYuMi00LjUgMTYuMi0xMi41YzAtOC4zLTUuOC0xMy0xNi4yLTEzLTEwLjUuMS0xNi4yIDQuNy0xNi4yIDEzeiIvPjxwYXRoIGQ9Ik0xNTUuNCAzMTAuOUM2OS43IDMxMC45IDAgMjQxLjEgMCAxNTUuNFM2OS43IDAgMTU1LjQgMGMxMS42IDAgMjMuMiAxLjMgMzQuNSAzLjlWMTVjLTExLjItMi44LTIyLjgtNC4xLTM0LjUtNC4xLTc5LjcgMC0xNDQuNiA2NC45LTE0NC42IDE0NC42czY0LjkgMTQ0LjYgMTQ0LjYgMTQ0LjZTMzAwIDIzNS4yIDMwMCAxNTUuNWMwLTExLjctMS40LTIzLjMtNC4xLTM0LjVIMzA3YzIuNiAxMS4zIDMuOSAyMi44IDMuOSAzNC41IDAgODUuNi02OS44IDE1NS40LTE1NS41IDE1NS40eiIvPjxwYXRoIGQ9Ik0yNzUuNyAzNS4xVjMuNkgyNTN2MzEuNWgtMzEuNHYyMi43SDI1M3YzMS41aDIyLjdWNTcuOGgzMS41VjM1LjF6Ii8+PC9zdmc+"> <span data-v-4ccff48d="">View Explicit</span></button>';
  111. explicitButtons.insertAdjacentHTML("beforeend", iconHtml);
  112. document.getElementById("18Button").addEventListener("click", explicitJS);
  113. console.log("Added 18+ Button");
  114. }
  115.  
  116. //Injects a scroll button which will allow one to load all images on the page automatically
  117. function scrollButts() {
  118. console.log("Adding Scroll Button");
  119. var oldButtons = document.querySelector(
  120. "#results > div > div > div.top-slot > div > div > div > button:last-child"
  121. );
  122. var scrollButton = oldButtons.parentElement;
  123. var scrollIconHtml =
  124. '<button data-v-4ccff48d="" type="button" class="default icon-only" data-v-46dbee4d="" id="scrollButton" title="Scroll to the bottom"><img data-v-4ccff48d="" src="data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNDkwLjcgNDkwLjciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTQ3Mi4zIDIxNi41LTIyNy4xIDIyNy4yLTIyNy4xLTIyNy4yYy00LjItNC4xLTExLTQtMTUuMS4zLTQgNC4xLTQgMTAuNyAwIDE0LjhsMjM0LjcgMjM0LjdjNC4yIDQuMiAxMC45IDQuMiAxNS4xIDBsMjM0LjctMjM0LjdjNC4xLTQuMiA0LTExLS4zLTE1LjEtNC4yLTQtMTAuNy00LTE0LjkgMHoiIGZpbGw9IiM2MDdkOGIiLz48cGF0aCBkPSJtNDcyLjMgMjQuNS0yMjcuMSAyMjcuMi0yMjcuMS0yMjcuMmMtNC4yLTQuMS0xMS00LTE1LjEuMy00IDQuMS00IDEwLjcgMCAxNC44bDIzNC43IDIzNC43YzQuMiA0LjIgMTAuOSA0LjIgMTUuMSAwbDIzNC42LTIzNC43YzQuMi00LjEgNC40LTEwLjguMy0xNS4xLTQuMS00LjItMTAuOC00LjQtMTUuMS0uMy0uMS4yLS4yLjItLjMuM3oiIGZpbGw9IiM2MDdkOGIiLz48cGF0aCBkPSJtMjQ1LjIgNDY5LjRjLTIuOCAwLTUuNS0xLjEtNy42LTMuMWwtMjM0LjYtMjM0LjdjLTQuMS00LjItNC0xMSAuMy0xNS4xIDQuMS00IDEwLjctNCAxNC44IDBsMjI3LjEgMjI3LjEgMjI3LjEtMjI3LjFjNC4yLTQuMSAxMS00IDE1LjEuMyA0IDQuMSA0IDEwLjcgMCAxNC44bC0yMzQuNyAyMzQuN2MtMiAyLTQuNyAzLjEtNy41IDMuMXoiLz48cGF0aCBkPSJtMjQ1LjIgMjc3LjRjLTIuOCAwLTUuNS0xLjEtNy42LTMuMWwtMjM0LjYtMjM0LjdjLTQuMS00LjItNC0xMSAuMy0xNS4xIDQuMS00IDEwLjctNCAxNC44IDBsMjI3LjEgMjI3LjEgMjI3LjEtMjI3LjFjNC4xLTQuMiAxMC44LTQuNCAxNS4xLS4zczQuNCAxMC44LjMgMTUuMWMtLjEuMS0uMi4yLS4zLjNsLTIzNC43IDIzNC43Yy0yIDItNC43IDMuMS03LjUgMy4xeiIvPjwvc3ZnPg=="> <span data-v-4ccff48d="">Scroll Button</span></button>';
  125. scrollButton.insertAdjacentHTML("beforeend", scrollIconHtml);
  126. document.getElementById("scrollButton").addEventListener("click", betterScroller);
  127. console.log("Added Scroll Button");
  128. }
  129.  
  130. //Injects a button that, when pressed, will copy the Open Graph index to the clipboard
  131. function exportButts() {
  132. console.log("Adding OG URL Export Button");
  133. var oldButtons = document.querySelector(
  134. "#results > div > div > div.top-slot > div > div > div > button:last-child"
  135. );
  136. var exportButton = oldButtons.parentElement;
  137. var exportIconHtml =
  138. '<button data-v-4ccff48d="" type="button" class="default icon-only" data-v-46dbee4d="" id="exportButton" title="Export Open Graph URL to clipboard"><img data-v-4ccff48d="" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0ODguMyA0ODguMyI+PHBhdGggZD0iTTMxNC4yNSA4NS40aC0yMjdjLTIxLjMgMC0zOC42IDE3LjMtMzguNiAzOC42djMyNS43YzAgMjEuMyAxNy4zIDM4LjYgMzguNiAzOC42aDIyN2MyMS4zIDAgMzguNi0xNy4zIDM4LjYtMzguNlYxMjRjLS4xLTIxLjMtMTcuNC0zOC42LTM4LjYtMzguNnptMTEuNSAzNjQuMmMwIDYuNC01LjIgMTEuNi0xMS42IDExLjZoLTIyN2MtNi40IDAtMTEuNi01LjItMTEuNi0xMS42VjEyNGMwLTYuNCA1LjItMTEuNiAxMS42LTExLjZoMjI3YzYuNCAwIDExLjYgNS4yIDExLjYgMTEuNnYzMjUuNnoiLz48cGF0aCBkPSJNNDAxLjA1IDBoLTIyN2MtMjEuMyAwLTM4LjYgMTcuMy0zOC42IDM4LjYgMCA3LjUgNiAxMy41IDEzLjUgMTMuNXMxMy41LTYgMTMuNS0xMy41YzAtNi40IDUuMi0xMS42IDExLjYtMTEuNmgyMjdjNi40IDAgMTEuNiA1LjIgMTEuNiAxMS42djMyNS43YzAgNi40LTUuMiAxMS42LTExLjYgMTEuNi03LjUgMC0xMy41IDYtMTMuNSAxMy41czYgMTMuNSAxMy41IDEzLjVjMjEuMyAwIDM4LjYtMTcuMyAzOC42LTM4LjZWMzguNmMwLTIxLjMtMTcuMy0zOC42LTM4LjYtMzguNnoiLz48L3N2Zz4="> <span data-v-4ccff48d="">Export Button</span></button>';
  139. scrollButton.insertAdjacentHTML("afterend", exportIconHtml);
  140. document.getElementById("exportButton").addEventListener("click", exporter);
  141. console.log("Added Export Button");
  142. }
  143.  
  144. //Injects a button that, when pressed, will paste the Open Graph index from the clipboard to the URL bar
  145. function importButts() {
  146. console.log("Adding OG URL Import Button");
  147. var oldButtons = document.querySelector(
  148. "#results > div > div > div.top-slot > div > div > div > button:last-child"
  149. );
  150. var importButton = oldButtons.parentElement;
  151. var importIconHtml =
  152. '<button data-v-4ccff48d="" type="button" class="default icon-only" data-v-46dbee4d="" id="importButton" title="Import Open Graph URL from clipboard"><img data-v-4ccff48d="" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MTIiIGhlaWdodD0iNTEyIiB2aWV3Qm94PSIwIDAgMTYgMTYiPjxsaW5lYXJHcmFkaWVudCB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGlkPSJhIiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KC05LjUgOSAtOSAtOS41IDc0LjUzNiA4OCkiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4Mj0iMSI+PHN0b3Agb2Zmc2V0PSIuMDA3Ii8+PHN0b3Agb2Zmc2V0PSIxIi8+PC9saW5lYXJHcmFkaWVudD48cGF0aCBkPSJNNjMuNTU2IDkzLjQ4OHYyLjVhMi41IDIuNSAwIDAgMCAyLjUgMi41aDEwYTIuNSAyLjUgMCAwIDAgMi41LTIuNXYtMi4wNmEuNS41IDAgMCAwLTEgMHYyLjA2YTEuNSAxLjUgMCAwIDEtMS41IDEuNWgtMTBhMS41IDEuNSAwIDAgMS0xLjUtMS41di0yLjVhLjUuNSAwIDAgMC0xIDB6bTcuMDAxLjM1NWwtMS4yNjktMS4yNjlhLjUuNSAwIDAgMC0uNzA3LjcwN2wyLjEyMSAyLjEyMWEuNDk5LjQ5OSAwIDAgMCAuNzA3IDBsMi4xMjItMi4xMjFhLjUuNSAwIDAgMC0uNzA3LS43MDdsLTEuMjY3IDEuMjY3LjAwNy03LjgyOWEuNS41IDAgMCAwLTEtLjAwMXoiIGZpbGw9InVybCgjYSkiIGRhdGEtb3JpZ2luYWw9InVybCgjX0xpbmVhcjEpIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNjMuMDM2IC04NCkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIvPjwvc3ZnPg=="> <span data-v-4ccff48d="">Import Button</span></button>';
  153. scrollButton.insertAdjacentHTML("afterend", importIconHtml);
  154. document.getElementById("importButton").addEventListener("click", importer);
  155. console.log("Added Import Button");
  156. }
  157.  
  158.  
  159. ///////////////////////////////////////
  160. // Export/Import OpenGraph Url //
  161. ///////////////////////////////////////
  162. /*
  163. ** Includes a scroller to load the page, stats, and sleep timers
  164. */
  165.  
  166. //Copies the open graph url to the clipboard
  167.  
  168. ogUrl=document.querySelectorAll('meta[property="og:url"]')[0].content.replace('https://pimeyes.com/en','')
  169. ogUrlCut=ogUrl.substring(0, ogUrl.lastIndexOf('?')).replace('/search/','')
  170.  
  171. function exporter() {
  172. executeCopy = function() {
  173. var copyhelper = document.createElement("input");
  174. copyhelper.className = 'copyhelper'
  175. document.body.appendChild(copyhelper);
  176. copyhelper.value = ogUrlCut;
  177. copyhelper.select();
  178. document.execCommand("copy");
  179. document.body.removeChild(copyhelper);
  180. };
  181. executeCopy();
  182. console.log("ogURLCut is " + ogUrlCut)
  183. }
  184.  
  185. async function importer() {
  186. oldPage=window.location.href;
  187. oldPageIndex=oldPage.indexOf(ogUrlCut)
  188. ogUrlImport= await navigator.clipboard.readText();
  189. newPage=oldPage.substr(0, oldPageIndex) + ogUrlImport + "_" + oldPage.substr(oldPageIndex)
  190. console.log("oldPage is " + oldPage)
  191. console.log("newPage is " + newPage)
  192. window.history.pushState({path:newPage},'',newPage);
  193. window.location.href=newPage
  194. }
  195.  
  196.  
  197.  
  198. ///////////////////////////////////////
  199. // Removal Prerequisites //
  200. ///////////////////////////////////////
  201. /*
  202. ** Includes a scroller to load the page, stats, and sleep timers
  203. */
  204.  
  205. //Scrolls down the page as fast as possible
  206. function scrollDown() {
  207. window.scrollBy(0, 10000);
  208. window.scrollTo(0, document.body.scrollHeight);
  209. }
  210.  
  211. //Scrolls to the top of the page
  212. function scrollUp() {
  213. window.scrollBy(0, -50000);
  214. window.scrollTo(0, 0);
  215. }
  216.  
  217. //Scrolls all the way to the bottom of the page to load all results, then scrolls back to the top
  218. async function scroller() {
  219. if (document.querySelectorAll("div.results-end").length === 1) {
  220. scrolled = 1;
  221. } else if (document.querySelectorAll("div.results-end").length === 0) {
  222. scrolled = 0;
  223. }
  224. while (scrolled < 1) {
  225. console.log("Scrolling to the bottom of the results");
  226. var scrollCount = 1;
  227. do {
  228. scrollDown();
  229. console.log("Sleeping 1000ms");
  230. await sleep(1000);
  231. console.log("Still scrolling (" + scrollCount + "x)");
  232. scrollCount++;
  233. } while (document.querySelectorAll("div.results-end").length === 0);
  234. console.log("Done scrolling");
  235. console.log("Sleeping 1000ms");
  236. await sleep(1000);
  237. console.log("Scrolling to top of page");
  238. scrollUp();
  239. console.log("We reached the top");
  240. console.log("Sleeping 1000ms");
  241. await sleep(1000);
  242. scrolled = 1;
  243. }
  244. }
  245.  
  246. //Scrolls but lets you control it
  247. function betterScroller() {
  248. var a = document.body.clientHeight,
  249. b = document.documentElement.scrollHeight,
  250. c = document.documentElement.clientHeight,
  251. d = innerHeight,
  252. e = document.height;
  253. if (console.log("document.body.clientHeight:\t\t\t\t\t" + a + ";\ndocument.documentElement.scrollHeight:\t\t" + b + ";\ndocument.documentElement.clientHeight:\t\t" + c + ";\ninnerHeight:\t\t\t\t\t\t\t\t" + d + ";\ndocument.height:\t\t\t\t\t\t\t" + e), document.URL.includes("facebook.com")) ! function() {
  254. var e = null,
  255. t = 0,
  256. s = function() {
  257. console.log("Clicked; stopping autoscroll"), clearInterval(e), document.body.removeEventListener("click", s)
  258. };
  259. document.body.addEventListener("click", s), e = setInterval(function() {
  260. var o = document.body.scrollHeight - document.body.scrollTop - window.innerHeight;
  261. o > 0 ? (window.scrollBy(0, o), t > 0 && (t = 0), console.log("scrolling down more")) : t >= 3 ? (console.log("reached bottom of page; stopping"), clearInterval(e), document.body.removeEventListener("click", s)) : (console.log("[apparenty] hit bottom of page; retrying: " + (t + 1)), t++)
  262. }, 1e3)
  263. }();
  264. else {
  265. let e, t = 1,
  266. s = [
  267. [0, 0],
  268. [25, 200],
  269. [36, 120],
  270. [49, 72],
  271. [64, 43.2],
  272. [81, 25.9],
  273. [100, 31],
  274. [121, 37.2],
  275. [144, 44.8],
  276. [169, 26.4],
  277. [196, 32]
  278. ],
  279. o = document.onkeypress;
  280. _ss_stop = function() {
  281. clearTimeout(e)
  282. }, _ss_start = function() {
  283. _ss_abs_speed = Math.abs(t), _ss_direction = t / _ss_abs_speed, _ss_speed_pair = s[_ss_abs_speed], e = setInterval("scrollBy(0," + _ss_direction * _ss_speed_pair[0] + "); if((pageYOffset<=1)||(pageYOffset==document.documentElement.scrollHeight-innerHeight)) _ss_speed=0;", _ss_speed_pair[1])
  284. }, _ss_adj = function(e) {
  285. t += e, Math.abs(t) >= s.length && (t = (s.length - 1) * (t / Math.abs(t)))
  286. }, _ss_quit = function() {
  287. _ss_stop(), document.onkeypress = o
  288. }, document.onkeypress = function(e) {
  289. if (113 != e.charCode && 27 != e.keyCode) {
  290. if (e.charCode >= 48 && e.charCode <= 57) t = e.charCode - 48;
  291. else switch (e.charCode) {
  292. case 95:
  293. _ss_adj(-2);
  294. case 45:
  295. _ss_adj(-1);
  296. break;
  297. case 43:
  298. _ss_adj(2);
  299. case 61:
  300. _ss_adj(1)
  301. }
  302. _ss_stop(), _ss_start()
  303. } else _ss_quit()
  304. }, _ss_stop(), _ss_start()
  305. }
  306. }
  307.  
  308. //Lets script sleep after functions to allow page a bit of time to catch up
  309. function sleep(ms) {
  310. return new Promise((resolve) => setTimeout(resolve, ms));
  311. }
  312.  
  313. //Helper script to update the count of explicit results
  314. function expResultsUpdater() {
  315. explicitCount = document.querySelectorAll(
  316. "#results div.results-grid div.result div.thumbnail span.explicit-result"
  317. ).length;
  318. console.log(explicitCount + " potentially explicit results so far");
  319. document.getElementById("expResults").innerHTML = explicitCount;
  320. }
  321.  
  322. //Injects an explicit results running total at the top of the page
  323. function explicitStats() {
  324. console.log("Inserting Stats Counter");
  325. var oldResults = document.querySelector(
  326. "#results > div.container > div > div.top-slot > div > div.container > span.stats > span:nth-child(1)"
  327. );
  328. var explicitResults = oldResults;
  329. var resultsHtml =
  330. '<span data-v-26e5f418="">' +
  331. '<bdi id="expResults">' +
  332. explicitCount +
  333. "</bdi>" +
  334. " potentially explicit results so far</span>";
  335. explicitResults.insertAdjacentHTML("beforebegin", resultsHtml);
  336. expResultsUpdater();
  337. }
  338.  
  339. //Updates the explicit results count that was injected at the top of the page then stops doing anything after page-end is reached
  340. function scrollResultsUpdateListener() {
  341. addEventListener("scroll", function () {
  342. if (document.querySelectorAll("div.results-end").length === 0) {
  343. expResultsUpdater();
  344. scrolled = 0;
  345. }
  346. });
  347. }
  348.  
  349.  
  350.  
  351. //Highlights and generates url to go to site where image is hosted
  352. async function highlightUrl() {
  353. console.log("Waiting to highlight");
  354. await sleep(200);
  355. var spanUrl = document.querySelector(
  356. "div.modal-content div.thumbnail span.url"
  357. );
  358. if (typeof spanUrl != "undefined" && spanUrl != null) {
  359. spanUrl = document.querySelector(
  360. "div.modal-content div.thumbnail span.url"
  361. );
  362. spanUrl.innerHTML =
  363. `<a href="` + spanUrl.innerHTML + `">` + spanUrl.innerHTML + `</a>`;
  364.  
  365. function selectText(node) {
  366. node = spanUrl;
  367.  
  368. if (document.body.createTextRange) {
  369. const range = document.body.createTextRange();
  370. range.moveToElementText(node);
  371. range.select();
  372. } else if (window.getSelection) {
  373. const selection = window.getSelection();
  374. const range = document.createRange();
  375. range.selectNodeContents(node);
  376. selection.removeAllRanges();
  377. selection.addRange(range);
  378. } else {
  379. console.warn(
  380. "Could not select text in node: Unsupported browser."
  381. );
  382. }
  383. }
  384. selectText("spanUrl");
  385. } else {
  386. console.log(
  387. "Tried to highlight URL because of highlightUrl mousedown event listener but popup does not exist!"
  388. );
  389. }
  390. }
  391.  
  392. ///////////////////////////////////////
  393. // Removal Scripts //
  394. ///////////////////////////////////////
  395. /*
  396. **Pure Javascript based removal scripts
  397. */
  398.  
  399. //Script to remove nonexplicit images using jQuery
  400. function jsRemover() {
  401. console.log("Running removal script (Pure JavaScript)");
  402. document
  403. .querySelectorAll("#results div.results-grid div.result div.thumbnail")
  404. .forEach(function (element) {
  405. if (!element.querySelector("span.explicit-result")) {
  406. element.parentNode.remove();
  407. }
  408. });
  409. console.log("Finished removal script");
  410. }
  411.  
  412. //jsRemover helper script
  413. async function explicitJS() {
  414. console.log("Starting the removal process");
  415. await scroller();
  416. jsRemover();
  417. console.log("Finished the removal process");
  418. }
  419.  
  420. /*
  421. **jQuery based removal scripts
  422. */
  423.  
  424. //Script to remove nonexplicit images using jQuery
  425. function jqRemover() {
  426. console.log("Running removal service (jQuery)");
  427. jQuery(
  428. "#results div.results-grid div.result div.thumbnail:has(span):not(:has(.explicit-result))"
  429. )
  430. .parent()
  431. .remove();
  432. console.log("Finished removal script");
  433. }
  434.  
  435. //jqRemover helper script
  436. async function explicitJQ() {
  437. jqGetter();
  438. console.log("Starting the removal process");
  439. await scroller();
  440. jsRemover();
  441. console.log("Finished the removal process");
  442. }
  443.  
  444. //Downloads jQuery to the page
  445. function jqGetter() {
  446. console.log("Downloading jQuery to page");
  447. var el = document.createElement("div"),
  448. b = document.getElementsByTagName("body")[0],
  449. otherlib = !1,
  450. msg = "";
  451. (el.style.position = "fixed"),
  452. (el.style.height = "32px"),
  453. (el.style.width = "220px"),
  454. (el.style.marginLeft = "-110px"),
  455. (el.style.top = "0"),
  456. (el.style.left = "50%"),
  457. (el.style.padding = "5px 10px"),
  458. (el.style.zIndex = 1001),
  459. (el.style.fontSize = "12px"),
  460. (el.style.color = "#222"),
  461. (el.style.backgroundColor = "#f99");
  462.  
  463. function showMsg() {
  464. var txt = document.createTextNode(msg);
  465. el.appendChild(txt),
  466. b.appendChild(el),
  467. window.setTimeout(function () {
  468. (txt = null),
  469. typeof jQuery == "undefined"
  470. ? b.removeChild(el)
  471. : (jQuery(el).fadeOut("slow", function () {
  472. jQuery(this).remove();
  473. }),
  474. otherlib && (window.$jq = jQuery.noConflict()));
  475. }, 2500);
  476. }
  477. if (typeof jQuery != "undefined")
  478. return (
  479. (msg = "This page already using jQuery v" + jQuery.fn.jquery),
  480. showMsg()
  481. );
  482. typeof $ == "function" && (otherlib = !0);
  483.  
  484. function getScript(url, success) {
  485. var script = document.createElement("script");
  486. script.src = url;
  487. var head = document.getElementsByTagName("head")[0],
  488. done = !1;
  489. (script.onload = script.onreadystatechange = function () {
  490. !done &&
  491. (!this.readyState ||
  492. this.readyState == "loaded" ||
  493. this.readyState == "complete") &&
  494. ((done = !0),
  495. success(),
  496. (script.onload = script.onreadystatechange = null),
  497. head.removeChild(script));
  498. }),
  499. head.appendChild(script);
  500. }
  501. getScript("//code.jquery.com/jquery.min.js", function () {
  502. return (
  503. typeof jQuery == "undefined"
  504. ? (msg = "Sorry, but jQuery was not able to load")
  505. : ((msg =
  506. "This page is now jQuerified with v" +
  507. jQuery.fn.jquery),
  508. otherlib &&
  509. (msg += " and noConflict(). Use $jq(), not $().")),
  510. showMsg()
  511. );
  512. });
  513. console.log("jQuery downloaded to page");
  514. }
  515.  
  516. ///////////////////////////////////////
  517. // CSS Mods/Page Improvement //
  518. ///////////////////////////////////////
  519. /**
  520. * Utility function to add CSS in multiple passes.
  521. * @param {string} styleString
  522. * From http://stackoverflow.com/a/15506705
  523. **/
  524. function addStyle(styleString) {
  525. const style = document.createElement("style");
  526. style.textContent = styleString;
  527. document.head.append(style);
  528. }
  529.  
  530. //From https://greasyfork.org/scripts/406062
  531. addStyle(`
  532. /*Un-blur the URLs*/
  533. .blurred-source-url {
  534. user-select: all !important;
  535. ;
  536. }
  537. `);
  538.  
  539. //From https://greasyfork.org/scripts/406062
  540. /*div.modal-content>div.thumbnail>span.url*/
  541.  
  542. addStyle(`
  543. /*Make the URLs selectable, and visible*/
  544. *.url {
  545. filter: none !important;
  546. ;
  547. overflow: visible !important;
  548. ;
  549. user-select: initial !important;
  550. ;
  551. max-width: initial !important;
  552. ;
  553. pointer-events: none !important;
  554. ;
  555. position: initial !important;
  556. }
  557. `);
  558.  
  559. //From https://greasyfork.org/scripts/406062
  560. addStyle(`
  561. /*Remove the Buy Premium overlay on images*/
  562. .zoom {
  563. display: none !important;
  564. ;
  565. }
  566. `);
  567.  
  568. //From https://greasyfork.org/scripts/406062
  569. addStyle(`
  570. /*Remove the 'Get access to archival results and Deep search for $299.99/mo overlay on images*/
  571. .promo {
  572. display: none !important;
  573. ;
  574. }
  575. `);
  576.  
  577. //From https://greasyfork.org/scripts/406062
  578. addStyle(`
  579. /*Remove the actions menu, so we can select the image*/
  580. .actions {
  581. display: none !important;
  582. ;
  583. }
  584. `);
  585.  
  586. //From https://greasyfork.org/scripts/406062
  587. /*
  588. addStyle(`
  589. /*Hide UNLOCK buttons*\/
  590. button[type="button"] {
  591. display: none !important;
  592. ;
  593. }
  594. `);
  595. */
  596.  
  597. //From https://greasyfork.org/scripts/406062
  598. addStyle(`
  599. /*un-hide add picture button*/
  600. button[class="spacer"] {
  601. display: inherit !important;
  602. ;
  603. }
  604. `);
  605.  
  606. //From https://greasyfork.org/scripts/406062
  607. addStyle(`
  608. /*Remove events from image*/
  609. div.thumbnail {
  610. pointer-events: none !important;
  611. ;
  612. }
  613. `);
  614.  
  615. addStyle(`
  616. /*Hide the unlock popup/buttons if it appears*/
  617. #app > div:nth-child(4) > div > div.mask {
  618. display: none !important;
  619. ;
  620. }
  621. `);
  622.  
  623. addStyle(`
  624. /*Hide the unlock popup/buttons if it appears*/
  625. #app > div:nth-child(4) > div.wrapper {
  626. display: none !important;
  627. ;
  628. }
  629. `);
  630.  
  631. //Hide the unlock popup if it appears in another way (e.g. hitting Deep search on a paid account)
  632. //Prevent block-scroll from impacting the body if one hits "Deep search" or any button which causes an overlay
  633. addStyle(`
  634. /*Hide the unlock popup if it appears in another way#1*/
  635. /*Prevent block-scroll from impacting the body if one hits "Deep search" or any button which causes an overlay*/
  636. .block-scroll {
  637. touch-action: auto !important;
  638. -webkit-overflow-scrolling: touch!important;
  639. overflow: visible!important;
  640. -ms-scroll-chaining: none!important;
  641. overscroll-behavior: unset!important;
  642. }
  643. `);
  644.  
  645.  
  646. //Stops the button sizes from changing if one happens to hit the Deep Search button or cause an overlay
  647. addStyle(`
  648. /*Hide the unlock popup if it appears in another way #2*/
  649. /*Stops the button sizes from changing if one happens to hit the Deep Search button or cause an overlay*/
  650. *, :after, :before {
  651. box-sizing: revert !important;
  652. }
  653. `);
  654.  
  655. addStyle(`
  656. /*Hide the Formspring payment request*/
  657. #fscCanvas {
  658. display: none !important;
  659. ;
  660. }
  661. `);
  662.  
  663. addStyle(`
  664. /*Prevent the overlays from blocking scrolling*
  665. body {
  666. overflow: visible !important;
  667. ;
  668. }
  669. `);
  670.  
  671. /*
  672. ** bookmarklet
  673. javascript:(function()%7Beval(function(p%2Ca%2Cc%2Ck%2Ce%2Cr)%7Be%3Dfunction(c)%7Breturn(c%3Ca%3F''%3Ae(parseInt(c%2Fa)))%2B((c%3Dc%25a)%3E35%3FString.fromCharCode(c%2B29)%3Ac.toString(36))%7D%3Bif(!''.replace(%2F%5E%2F%2CString))%7Bwhile(c--)r%5Be(c)%5D%3Dk%5Bc%5D%7C%7Ce(c)%3Bk%3D%5Bfunction(e)%7Breturn%20r%5Be%5D%7D%5D%3Be%3Dfunction()%7Breturn'%5C%5Cw%2B'%7D%3Bc%3D1%7D%3Bwhile(c--)if(k%5Bc%5D)p%3Dp.replace(new%20RegExp('%5C%5Cb'%2Be(c)%2B'%5C%5Cb'%2C'g')%2Ck%5Bc%5D)%3Breturn%20p%7D('b%201q()%7B7.8(%221r%2018%2B%20u%22)%3B5.k(%22%23c%20%3E%203%20%3E%203%20%3E%203.w-Z%20%3E%203%20%3E%203%20%3E%203%20%3E%20g%3A1s-y%22).1t.10(%221u%22%2C%5C'%3Cg%20h-v-m%3D%22%22%201v%3D%22g%22%2011%3D%221w%201x-1y%22%20h-v-1z%3D%22%22%2012%3D%221A%22%3E%3C1B%20h-v-m%3D%22%22%201C%3D%22h%3AH%2F1D%2B1E%3B1F%2C2q%2B2r%2B2s%2B%22%3E%20%3Cf%20h-v-m%3D%22%22%3E2t%202u%3C%2Ff%3E%3C%2Fg%3E%5C')%2C5.13(%221A%22).I(%221G%22%2C1H)%2C7.8(%221I%2018%2B%20u%22)%7Db%201J()%7B7.8(%221r%2014%20u%22)%3B5.k(%22%23c%20%3E%203%20%3E%203%20%3E%203.w-Z%20%3E%203%20%3E%203%20%3E%203%20%3E%20g%3A1s-y%22).1t.10(%221u%22%2C%5C'%3Cg%20h-v-m%3D%22%22%201v%3D%22g%22%2011%3D%221w%201x-1y%22%20h-v-1z%3D%22%22%2012%3D%221K%22%3E%3C1B%20h-v-m%3D%22%22%201C%3D%22h%3AH%2F1D%2B1E%3B1F%2C2v%2B2w%3D%3D%22%3E%20%3Cf%20h-v-m%3D%22%22%3E14%20u%3C%2Ff%3E%3C%2Fg%3E%5C')%2C5.13(%221K%22).I(%221G%22%2C15)%2C7.8(%221I%2014%20u%22)%7Db%201L()%7Bo.1M(0%2C2x)%2Co.1N(0%2C5.J.2y)%7Db%201O()%7Bo.1M(0%2C-2z)%2Co.1N(0%2C0)%7D16%20b%2015()%7B1P(1%3D%3D%3D5.p(%223.c-K%22).z%3Fq%3D1%3A0%3D%3D%3D5.p(%223.c-K%22).z%26%26(q%3D0)%3Bq%3C1%3B)%7B7.8(%221Q%20r%209%202A%2017%209%20c%22)%3B19%20e%3D1%3B2B%7B1L()%2C7.8(%221a%201b%22)%2CA%20B(1c)%2C7.8(%222C%20L%20(%22%2Be%2B%22x)%22)%2Ce%2B%2B%7D2D(0%3D%3D%3D5.p(%223.c-K%22).z)%3B7.8(%222E%20L%22)%2C7.8(%221a%201b%22)%2CA%20B(1c)%2C7.8(%221Q%20r%20w%2017%202F%22)%2C1O()%2C7.8(%222G%202H%209%20w%22)%2C7.8(%221a%201b%22)%2CA%20B(1c)%2Cq%3D1%7D%7Db%20B(e)%7B2I%202J%202K(t%3D%3E2L(t%2Ce))%7Db%201d()%7BC%3D5.p(%22%23c%203.c-1e%203.M%203.s%20f.N-M%22).z%2C7.8(C%2B%22%201R%20N%20c%201f%201S%22)%2C5.13(%221T%22).O%3DC%7Db%201U()%7B7.8(%222M%202N%202O%22)%3B19%20e%3D5.k(%22%23c%20%3E%203%20%3E%203%20%3E%203.w-Z%20%3E%203%20%3E%203%20%3E%20f%20%3E%20f%3A1g-y(2)%22)%2Ct%3D%5C'%3Cf%20h-v-2P%3D%22%22%3E%3C1V%2012%3D%221T%22%3E%5C'%2BC%2B%22%3C%2F1V%3E%201R%20N%20c%201f%201S%3C%2Ff%3E%22%3Be.10(%222Q%22%2Ct)%2C1d()%7Db%201W()%7BI(%22P%22%2Cb()%7B0%3D%3D%3D5.p(%223.c-K%22).z%26%26(1d()%2Cq%3D0)%7D)%7D16%20b%201h()%7B7.8(%222R%20r%201X%22)%2CA%20B(2S)%3B19%20e%3D5.k(%223.1i-1j%203.s%20f.D%22)%3Bj(2T%200!%3D%3De%26%262U!%3De)%7B(e%3D5.k(%223.1i-1j%203.s%20f.D%22)).O%3D%5C'%3Ca%202V%3D%22%5C'%2Be.O%2B%5C'%22%3E%5C'%2Be.O%2B%22%3C%2Fa%3E%22%2Cb(t)%7Bj(t%3De%2C5.J.1Y)%7B1k%20e%3D5.J.1Y()%3Be.2W(t)%2Ce.E()%7D1l%20j(o.1Z)%7B1k%20e%3Do.1Z()%2Cn%3D5.2X()%3Bn.2Y(t)%2Ce.2Z()%2Ce.30(n)%7D1l%207.31(%2232%2020%20E%2033%201m%2034%3A%2035%2036.%22)%7D(%2237%22)%7D1l%207.8(%2238%20r%201X%2039%203a%2017%201h%2021%203b%203c%203d%20F%203e%2020%203f!%22)%7Db%2022()%7B7.8(%223g%20Q%2023%20(3h%203i)%22)%2C5.p(%22%23c%203.c-1e%203.M%203.s%22).3j(b(e)%7Be.k(%22f.N-M%22)%7C%7Ce.3k.24()%7D)%2C7.8(%2225%20Q%2023%22)%7D16%20b%201H()%7B7.8(%223l%209%20Q%2026%22)%2CA%2015()%2C22()%2C7.8(%2225%209%20Q%2026%22)%7Db%20d(e)%7B1k%20t%3D5.3m(%223n%22)%3Bt.3o%3De%2C5.3p.3q(t)%7D1q()%2C1J()%2CC%3D0%2C1U()%2Cq%3D0%2C1W()%2C27%3D5.k(%223.c-1e%22)%2C27.I(%2221%22%2C1h)%2Cd(%22%5C%5Cn%2F*3r-3s%209%2028*%2F%5C%5Cn.3t-3u-D%20%7B%5C%5Cn%20%20%20%2029-E%3A%203v%20!6%3B%5C%5Cn%20%20%20%20%3B%5C%5Cn%7D%5C%5Cn%22)%2Cd(%22%5C%5Cn%2F*3w%209%2028%203x%2C%202a%20R*%2F%5C%5Cn%2F*3.1i-1j%3E3.s%3Ef.D*%2F%5C%5Cn*.D%20%7B%5C%5Cn%20%20%20%203y%3A%20i%20!6%3B%5C%5Cn%20%20%20%20%3B%5C%5Cn%20%20%20%20S%3A%20R%20!6%3B%5C%5Cn%20%20%20%20%3B%5C%5Cn%20%20%20%2029-E%3A%201n%20!6%3B%5C%5Cn%20%20%20%20%3B%5C%5Cn%20%20%20%203z-3A%3A%201n%20!6%3B%5C%5Cn%20%20%20%20%3B%5C%5Cn%20%20%20%202b-1o%3A%20i%20!6%3B%5C%5Cn%20%20%20%20%3B%5C%5Cn%20%20%20%203B%3A%201n%20!6%3B%5C%5Cn%7D%5C%5Cn%22)%2Cd(%22%5C%5Cn%2F*T%209%203C%203D%20U%202c%202d*%2F%5C%5Cn.3E%20%7B%5C%5Cn%20%20%20%20l%3A%20i%20!6%3B%5C%5Cn%20%20%20%20%3B%5C%5Cn%7D%5C%5Cn%22)%2Cd(%22%5C%5Cn%2F*T%209%20%5C'3F%203G%20r%203H%20c%202a%201p%202e%201P%20%243I.3J%2F3K%20U%202c%202d*%2F%5C%5Cn.3L%20%7B%5C%5Cn%20%20%20%20l%3A%20i%20!6%3B%5C%5Cn%20%20%20%20%3B%5C%5Cn%7D%5C%5Cn%22)%2Cd(%22%5C%5Cn%2F*T%209%202f%203M%2C%201f%203N%203O%20E%209%20H*%2F%5C%5Cn.2f%20%7B%5C%5Cn%20%20%20%20l%3A%20i%20!6%3B%5C%5Cn%20%20%20%20%3B%5C%5Cn%7D%5C%5Cn%22)%2Cd(%5C'%5C%5Cn%2F*3P-3Q%203R%203S%20g*%2F%5C%5C3T%5B11%3D%223U%22%5D%20%7B%5C%5Cn%20%20%20%20l%3A%203V%20!6%3B%5C%5Cn%20%20%20%20%3B%5C%5Cn%7D%5C%5Cn%5C')%2Cd(%22%5C%5Cn%2F*T%201o%20V%20H*%2F%5C%5C3W.s%20%7B%5C%5Cn%20%20%20%202b-1o%3A%20i%20!6%3B%5C%5Cn%20%20%20%20%3B%5C%5Cn%7D%5C%5Cn%22)%2Cd(%22%5C%5Cn%2F*G%209%20W%20F%2F2g%20j%20X%20Y*%2F%5C%5Cn%232h%20%3E%203%3A1g-y(4)%20%3E%203%20%3E%203.3X%20%7B%5C%5Cn%20%20%20%20l%3A%20i%20!6%3B%5C%5Cn%20%20%20%20%3B%5C%5Cn%7D%5C%5Cn%22)%2Cd(%22%5C%5Cn%2F*G%209%20W%20F%2F2g%20j%20X%20Y*%2F%5C%5Cn%232h%20%3E%203%3A1g-y(4)%20%3E%203.3Y%20%7B%5C%5Cn%20%20%20%20l%3A%20i%20!6%3B%5C%5Cn%20%20%20%20%3B%5C%5Cn%7D%5C%5Cn%22)%2Cd(%5C'%5C%5Cn%2F*G%209%20W%20F%20j%20X%20Y%201m%202i%202j%231*%2F%5C%5Cn%2F*2k%202l-P%20V%203Z%209%20J%20j%202m%2040%20%221p%202e%22%202n%2041%20g%2042%2043%202o%20U*%2F%5C%5Cn.2l-P%20%7B%5C%5Cn%20%20%20%202p-44%3A%2045%20!6%3B%5C%5Cn%20%20%20%20-46-S-L%3A%202p!6%3B%5C%5Cn%20%20%20%20S%3A%20R!6%3B%5C%5Cn%20%20%20%20-47-P-48%3A%20i!6%3B%5C%5Cn%20%20%20%2049-4a%3A%204b!6%3B%5C%5Cn%7D%5C%5Cn%5C%5Ct%5C')%2C5.k(%223%5Bh-v-4c%5D%22).24()%2Cd(%22%5C%5Cn%2F*G%209%20W%20F%20j%20X%20Y%201m%202i%202j%20%232*%2F%5C%5Cn%2F*4d%209%20g%204e%20V%204f%20j%202m%204g%20r%204h%209%201p%204i%20g%202n%204j%202o%20U*%2F%5C%5Cn*%2C%20%3A4k%2C%20%3A4l%20%7B%5C%5Cn%20%20%20%204m-4n%3A%204o%20!6%3B%5C%5Cn%7D%5C%5Cn%22)%2Cd(%22%5C%5Cn%2F*G%209%204p%204q%204r*%2F%5C%5Cn%234s%20%7B%5C%5Cn%20%20%20%20l%3A%20i%20!6%3B%5C%5Cn%20%20%20%20%3B%5C%5Cn%7D%5C%5Cn%22)%2Cd(%22%5C%5Cn%2F*2k%209%204t%20V%204u%20L*%5C%5C4v%20%7B%5C%5Cn%20%20%20%20S%3A%20R%20!6%3B%5C%5Cn%20%20%20%20%3B%5C%5Cn%7D%5C%5Cn%22)%3B'%2C62%2C280%2C'%7C%7C%7Cdiv%7C%7Cdocument%7Cimportant%7Cconsole%7Clog%7Cthe%7C%7Cfunction%7Cresults%7CaddStyle%7C%7Cspan%7Cbutton%7Cdata%7Cnone%7Cif%7CquerySelector%7Cdisplay%7C4ccff48d%7C%7Cwindow%7CquerySelectorAll%7Cscrolled%7Cto%7Cthumbnail%7C%7CButton%7C%7Ctop%7C%7Cchild%7Clength%7Cawait%7Csleep%7CexplicitCount%7Curl%7Cselect%7Cpopup%7CHide%7Cimage%7CaddEventListener%7Cbody%7Cend%7Cscrolling%7Cresult%7Cexplicit%7CinnerHTML%7Cscroll%7Cremoval%7Cvisible%7Coverflow%7CRemove%7Coverlay%7Cfrom%7Cunlock%7Cit%7Cappears%7Cslot%7CinsertAdjacentHTML%7Cclass%7Cid%7CgetElementById%7CScroll%7Cscroller%7Casync%7Cof%7C%7Cvar%7CSleeping%7C1000ms%7C1e3%7CexpResultsUpdater%7Cgrid%7Cso%7Cnth%7ChighlightUrl%7Cmodal%7Ccontent%7Cconst%7Celse%7Cin%7Cinitial%7Cevents%7CDeep%7CexplicitButts%7CAdding%7Clast%7CparentElement%7Cbeforeend%7Ctype%7Cdefault%7Cicon%7Conly%7C46dbee4d%7C18Button%7Cimg%7Csrc%7Csvg%7Cxml%7Cbase64%7Cclick%7CexplicitJS%7CAdded%7CscrollButts%7CscrollButton%7CscrollDown%7CscrollBy%7CscrollTo%7CscrollUp%7Cfor%7CScrolling%7Cpotentially%7Cfar%7CexpResults%7CexplicitStats%7Cbdi%7CscrollResultsUpdateListener%7Chighlight%7CcreateTextRange%7CgetSelection%7Cnot%7Cmousedown%7CjsRemover%7Cscript%7Cremove%7CFinished%7Cprocess%7CclickThumb%7CURLs%7Cuser%7Cand%7Cpointer%7Con%7Cimages%7Csearch%7Cactions%7Cbuttons%7Capp%7Canother%7Cway%7CPrevent%7Cblock%7Cone%7Cor%7Can%7Ctouch%7CPHN2ZyB2aWV3Qm94PSIwIDAgMzEwLjkgMzEwLjkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI%7CPHBhdGggZD0iTTk1IDIxMS40di04OS4zSDc0LjRWOTkuMmg0OS4xdjExMi4yem0xMzUuNi04My4yYzAgOS44LTUuMyAxOC40LTE0LjEgMjMuMiAxMi4zIDUuMSAyMCAxNS44IDIwIDI4LjMgMCAyMC4yLTE3LjkgMzMtNDUuOSAzM3MtNDUuOS0xMi42LTQ1LjktMzIuNWMwLTEyLjggOC4zLTIzLjcgMjEuMy0yOC44LTkuNC01LjMtMTUuNS0xNC4yLTE1LjUtMjQgMC0xNy45IDE1LjctMjkuMyA0MC0yOS4zIDI0LjUuMSA0MC4xIDExLjcgNDAuMSAzMC4xem0tNTkuMSA0OS4yYzAgOS40IDYuNyAxNC43IDE5IDE0LjdzMTkuMi01LjEgMTkuMi0xNC43YzAtOS4zLTYuOS0xNC42LTE5LjItMTQuNnMtMTkgNS4zLTE5IDE0LjZ6bTIuOS00Ny42YzAgOCA1LjggMTIuNSAxNi4yIDEyLjVzMTYuMi00LjUgMTYuMi0xMi41YzAtOC4zLTUuOC0xMy0xNi4yLTEzLTEwLjUuMS0xNi4yIDQuNy0xNi4yIDEzeiIvPjxwYXRoIGQ9Ik0xNTUuNCAzMTAuOUM2OS43IDMxMC45IDAgMjQxLjEgMCAxNTUuNFM2OS43IDAgMTU1LjQgMGMxMS42IDAgMjMuMiAxLjMgMzQuNSAzLjlWMTVjLTExLjItMi44LTIyLjgtNC4xLTM0LjUtNC4xLTc5LjcgMC0xNDQuNiA2NC45LTE0NC42IDE0NC42czY0LjkgMTQ0LjYgMTQ0LjYgMTQ0LjZTMzAwIDIzNS4yIDMwMCAxNTUuNWMwLTExLjctMS40LTIzLjMtNC4xLTM0LjVIMzA3YzIuNiAxMS4zIDMuOSAyMi44IDMuOSAzNC41IDAgODUuNi02OS44IDE1NS40LTE1NS41IDE1NS40eiIvPjxwYXRoIGQ9Ik0yNzUuNyAzNS4xVjMuNkgyNTN2MzEuNWgtMzEuNHYyMi43SDI1M3YzMS41aDIyLjdWNTcuOGgzMS41VjM1LjF6Ii8%7CPC9zdmc%7CView%7CExplicit%7CPHN2ZyB2aWV3Qm94PSIwIDAgNDkwLjcgNDkwLjciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI%7CPHBhdGggZD0ibTQ3Mi4zIDIxNi41LTIyNy4xIDIyNy4yLTIyNy4xLTIyNy4yYy00LjItNC4xLTExLTQtMTUuMS4zLTQgNC4xLTQgMTAuNyAwIDE0LjhsMjM0LjcgMjM0LjdjNC4yIDQuMiAxMC45IDQuMiAxNS4xIDBsMjM0LjctMjM0LjdjNC4xLTQuMiA0LTExLS4zLTE1LjEtNC4yLTQtMTAuNy00LTE0LjkgMHoiIGZpbGw9IiM2MDdkOGIiLz48cGF0aCBkPSJtNDcyLjMgMjQuNS0yMjcuMSAyMjcuMi0yMjcuMS0yMjcuMmMtNC4yLTQuMS0xMS00LTE1LjEuMy00IDQuMS00IDEwLjcgMCAxNC44bDIzNC43IDIzNC43YzQuMiA0LjIgMTAuOSA0LjIgMTUuMSAwbDIzNC42LTIzNC43YzQuMi00LjEgNC40LTEwLjguMy0xNS4xLTQuMS00LjItMTAuOC00LjQtMTUuMS0uMy0uMS4yLS4yLjItLjMuM3oiIGZpbGw9IiM2MDdkOGIiLz48cGF0aCBkPSJtMjQ1LjIgNDY5LjRjLTIuOCAwLTUuNS0xLjEtNy42LTMuMWwtMjM0LjYtMjM0LjdjLTQuMS00LjItNC0xMSAuMy0xNS4xIDQuMS00IDEwLjctNCAxNC44IDBsMjI3LjEgMjI3LjEgMjI3LjEtMjI3LjFjNC4yLTQuMSAxMS00IDE1LjEuMyA0IDQuMSA0IDEwLjcgMCAxNC44bC0yMzQuNyAyMzQuN2MtMiAyLTQuNyAzLjEtNy41IDMuMXoiLz48cGF0aCBkPSJtMjQ1LjIgMjc3LjRjLTIuOCAwLTUuNS0xLjEtNy42LTMuMWwtMjM0LjYtMjM0LjdjLTQuMS00LjItNC0xMSAuMy0xNS4xIDQuMS00IDEwLjctNCAxNC44IDBsMjI3LjEgMjI3LjEgMjI3LjEtMjI3LjFjNC4xLTQuMiAxMC44LTQuNCAxNS4xLS4zczQuNCAxMC44LjMgMTUuMWMtLjEuMS0uMi4yLS4zLjNsLTIzNC43IDIzNC43Yy0yIDItNC43IDMuMS03LjUgMy4xeiIvPjwvc3ZnPg%7C1e4%7CscrollHeight%7C5e4%7Cbottom%7Cdo%7CStill%7Cwhile%7CDone%7Cpage%7CWe%7Creached%7Creturn%7Cnew%7CPromise%7CsetTimeout%7CInserting%7CStats%7CCounter%7C26e5f418%7Cbeforebegin%7CWaiting%7C200%7Cvoid%7Cnull%7Chref%7CmoveToElementText%7CcreateRange%7CselectNodeContents%7CremoveAllRanges%7CaddRange%7Cwarn%7CCould%7Ctext%7Cnode%7CUnsupported%7Cbrowser%7CspanUrl%7CTried%7CURL%7Cbecause%7Cevent%7Clistener%7Cbut%7Cdoes%7Cexist%7CRunning%7CPure%7CJavaScript%7CforEach%7CparentNode%7CStarting%7CcreateElement%7Cstyle%7CtextContent%7Chead%7Cappend%7CUn%7Cblur%7Cblurred%7Csource%7Call%7CMake%7Cselectable%7Cfilter%7Cmax%7Cwidth%7Cposition%7CBuy%7CPremium%7Czoom%7CGet%7Caccess%7Carchival%7C299%7C99%7Cmo%7Cpromo%7Cmenu%7Cwe%7Ccan%7Cun%7Chide%7Cadd%7Cpicture%7Cnbutton%7Cspacer%7Cinherit%7Cndiv%7Cmask%7Cwrapper%7Cimpacting%7Chits%7Cany%7Cwhich%7Ccauses%7Caction%7Cauto%7Cwebkit%7Cms%7Cchaining%7Coverscroll%7Cbehavior%7Cunset%7C69882821%7CStops%7Csizes%7Cchanging%7Chappens%7Chit%7CSearch%7Ccause%7Cafter%7Cbefore%7Cbox%7Csizing%7Crevert%7CFormspring%7Cpayment%7Crequest%7CfscCanvas%7Coverlays%7Cblocking%7Cnbody'.split('%7C')%2C0%2C%7B%7D))%7D)()%3B
  674. */