Sleazy Fork is available in English.

Chaturbate reloaded

Ladroop is back

От 30.07.2024. Виж последната версия.

  1. // ==UserScript==
  2. // @name Chaturbate reloaded
  3. // @description Ladroop is back
  4. // @version 1.2.5
  5. // @namespace chaturbate_goes_Ladroop
  6. // @match https://*.chaturbate.com/*
  7. // @exclude https://secure.chaturbate.com/*
  8. // @exclude https://*chaturbate.com/apps/*
  9. // @exclude https://*chaturbate.com/b/*
  10. // @grant none
  11. // @run-at document-end
  12. // @license MIT
  13. // @copyright 2024 Ladroop
  14. // ==/UserScript==
  15.  
  16.  
  17. (function() {
  18. 'use strict';
  19. var version = "1.2.5"
  20. var scriptname="Chaturbate reloaded";
  21. var i=0;
  22. var n=0;
  23. var currpage=document.location.href;
  24. var roomname= currpage.split("/")[3];
  25. if (roomname =="p"){
  26. roomname=currpage.split("/")[4];
  27. }
  28. var allow_private_shows = false;
  29. var hls_source = "";
  30. var fetching=0;
  31. var loggedin=false;
  32. var username="";
  33. var br="";
  34. var vfilter="";
  35. var ofils="";
  36. var vmirror="";
  37. var pos1=0;
  38. var pos2=0;
  39. var pos3=0;
  40. var pos4=0;
  41. var vareaid="";
  42.  
  43. var observer= new MutationObserver(subsel); // observer for the subselector
  44. var observerConfig = {subtree: true, characterData: true, childList: true };
  45. var observer4=new MutationObserver(adjusthumbs); // observer for the thump
  46. var observerConfig4 ={attributes : true, attributeFilter : ['class'] };
  47. var observer41=new MutationObserver(adjusthumbs); // for 2nd list in spy on pvt
  48. var observer5=new MutationObserver(adjustbiohumbs); // observer for the thump on bio
  49. var observerConfig5 ={attributes : true, attributeFilter : ['style'] };
  50. var observer6=new MutationObserver(adjustfollowhumbs); // observer for the thump on followed popout
  51. var observerConfig6 ={attributes : true, attributeFilter : ['style'] };
  52. var observer7=new MutationObserver(nextcam);//observer if next cam is used
  53. var observerConfig7 ={attributes : true, attributeFilter : ['title'] };
  54. var observer3 = new MutationObserver(varea); // reset the filters if video area is changed
  55. var observerConfig3 = {childList: true, subtree: true }; // changes if video area is changed
  56.  
  57. var pmobserver = new MutationObserver(tabpm); // to be called if pm is recieved classic mode
  58. var pmobserver2 = new MutationObserver(tabpm); // to be called if pm is recieved theatre mode
  59. var pmobserverConfig = {childList: true}; // changes if pm
  60. var pmobservenode="";// node to observe if pm is recieved classic mode
  61. var pmobservenode2="";// node to observe if pm is recieved theatre mode
  62.  
  63. var tabblink=false;
  64. var ctitle=document.title;
  65. var container="";
  66. var bio=false;
  67.  
  68. var thisfap="";
  69. var fapbr="";
  70. var cimg = new Image();
  71. var pimg = new Image();
  72.  
  73. var usernoteslist = "";
  74. var tour="https://chaturbate.com/in/?tour=4uT2&campaign=hgg5k&track=default"
  75. var note='<svg style="height: 2.0em; width: 2.0em;" viewBox="0 0 12 12" xmlns="https://www.w3.org/2000/svg"><path fill="hsla(0, 100%, 50%, 0.8)" d="M5.5 2.00002H2C1.73478 2.00002 1.48043 2.10537 1.29289 2.29291C1.10536 2.48044 1 2.7348 1 3.00002V10C1 10.2652 1.10536 10.5196 1.29289 10.7071C1.48043 10.8947 1.73478 11 2 11H9C9.26522 11 9.51957 10.8947 9.70711 10.7071C9.89464 10.5196 10 10.2652 10 10V6.50002" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M9.25 1.24985C9.44891 1.05094 9.7187 0.939194 10 0.939194C10.2813 0.939194 10.5511 1.05094 10.75 1.24985C10.9489 1.44877 11.0607 1.71855 11.0607 1.99985C11.0607 2.28116 10.9489 2.55094 10.75 2.74985L6 7.49985L4 7.99985L4.5 5.99985L9.25 1.24985Z" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg>'
  76. var nonote='<svg style="height: 2.0em; width: 2.0em;" viewBox="0 0 12 12" xmlns="https://www.w3.org/2000/svg"><path fill="hsla(197, 10%, 98%, 0.3)" d="M5.5 2.00002H2C1.73478 2.00002 1.48043 2.10537 1.29289 2.29291C1.10536 2.48044 1 2.7348 1 3.00002V10C1 10.2652 1.10536 10.5196 1.29289 10.7071C1.48043 10.8947 1.73478 11 2 11H9C9.26522 11 9.51957 10.8947 9.70711 10.7071C9.89464 10.5196 10 10.2652 10 10V6.50002" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M9.25 1.24985C9.44891 1.05094 9.7187 0.939194 10 0.939194C10.2813 0.939194 10.5511 1.05094 10.75 1.24985C10.9489 1.44877 11.0607 1.71855 11.0607 1.99985C11.0607 2.28116 10.9489 2.55094 10.75 2.74985L6 7.49985L4 7.99985L4.5 5.99985L9.25 1.24985Z" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg>'
  77. var notegrey='<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="none" viewBox="0 0 12 12" role="img"><path stroke="#48484E" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M5.5 2H2a1 1 0 0 0-1 1v7a1 1 0 0 0 1 1h7a1 1 0 0 0 1-1V6.5"></path><path stroke="#48484E" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9.25 1.25a1.06 1.06 0 0 1 1.5 1.5L6 7.5 4 8l.5-2z"></path></svg>';
  78.  
  79. var discoverpage=false;
  80. var thumbpage=false;
  81. var tagspage=false;
  82. var online=false;
  83. var openthumbname="";
  84. var opennote="";
  85. var data="";
  86. var room_status="";
  87. var hidurl="https://chaturbate.com/api/ts/roomlist/room-list/?&hidden=true&limit=90&offset=";
  88. var hprom=false;
  89. var hidoffset=0;
  90. var hiddenarray=[];
  91. var noaccess=false;
  92. var c1=0;
  93. var c2=0;
  94. var c3=0;
  95. var c4=0;
  96. var c5=0;
  97. var c6=0;
  98. var c7=0;
  99. var c7a=100;
  100. var c8=0;
  101.  
  102. // to skip agree screen
  103. if (!readCookie("agreeterms")){untrace();createCookie("agreeterms","1",30);window.location.reload(true);}
  104. if (document.getElementsByClassName("dismiss_notice_tfa_and_email").length>0){
  105. document.getElementsByClassName("dismiss_notice_tfa_and_email")[0].click();
  106. }
  107. setadstyle();
  108. if (roomname!="discover"){
  109. setstyles();
  110. }
  111. //======== these are specials
  112. if (currpage.split("/")[3]=="my_collection"){
  113. if (document.getElementsByTagName("video").length>0){
  114. savedprvdownload();
  115. }
  116. return;
  117. }
  118.  
  119. if (currpage.split("/")[3]=="photo_videos"){
  120. collectiondownload();
  121. return;
  122. }
  123. //=== get status and pagetype
  124. var supporter=true;
  125. var login=true;
  126. if (document.querySelector('[class="upgrade"]')){
  127. supporter=false;
  128. }
  129. if (document.querySelector('[href="/auth/login/"]')){
  130. supporter=false;
  131. login=false;
  132. }
  133. aff();
  134. noadd();
  135. if (document.querySelector('[data-testid="denied-notice"]')){
  136. noaccess=true;
  137. bannedroom();
  138. return;
  139. }
  140. //==============get pagetype
  141. if (roomname=="roomlogin"){
  142. roomname=currpage.split("/")[4];
  143. passwordfollow();
  144. return;
  145. }
  146. if (roomname=="discover"){discoverpage=true}
  147. if (roomname=="tags"){tagspage=true}
  148. if (document.getElementById("roomlist_root")){thumbpage=true}
  149.  
  150. if (tagspage){setupfollowmove()}
  151. if (discoverpage){dothumbpagethings()}
  152. if (thumbpage){dothumbpagethings()}
  153.  
  154. //========= from here model page
  155. if (document.getElementById('main')){
  156. test();
  157. }
  158.  
  159. //========= wait till container is created
  160. function test(){
  161. if(document.getElementsByClassName("BioContents").length>0){
  162. container=document.getElementsByClassName("BioContents")[0];
  163. n=0;
  164. setTimeout(function(){test2();}, 100);
  165. }else{
  166. n++;
  167. if (n==100){
  168. return;
  169. }
  170. setTimeout(function(){test();}, 100);
  171. }
  172. }
  173.  
  174. function test2(){
  175. if (n==100){return;}
  176. if (container.innerHTML.indexOf("Loading…")!=-1){
  177. n++;
  178. setTimeout(function(){test2();}, 100);
  179. }else{
  180. n=0;
  181. test3();
  182. }
  183. }
  184.  
  185. function test3(){
  186. n++;
  187. if (n==100){return;}
  188. var biocont=container.innerHTML;
  189. setTimeout(function(){
  190. if (biocont == container.innerHTML){
  191. observer7.observe(document.querySelector('[data-paction-name="ActiveRoom"]'),observerConfig7);
  192. dobiothings()
  193. }else{
  194. test3();
  195. }
  196. }, 100);
  197. }
  198.  
  199. // ============nextcam , cleanup first
  200. function nextcam(){
  201. observer7.disconnect();
  202. observer3.disconnect();
  203. if (document.getElementById("notepop")){
  204. document.getElementById("notepop").remove();
  205. }
  206. if (document.getElementById("vcontr")){
  207. document.getElementById("vcontr").remove();
  208. }
  209. if (document.getElementById("ccontr")){
  210. document.getElementById("ccontr").remove();
  211. }
  212. if (document.getElementById("clean")){
  213. document.getElementById("clean").remove();
  214. }
  215. if (document.getElementById("infore")){
  216. document.getElementById("infore").remove();
  217. }
  218. if (document.getElementById("controls")){
  219. document.getElementById("controls").remove();
  220. }
  221. if (document.getElementById("chatcontrols")){
  222. document.getElementById("chatcontrols").remove();
  223. }
  224. if (document.getElementById("rulespop")){
  225. document.getElementById("rulespop").remove();
  226. }
  227. roomname=document.querySelector('[data-paction-name="ActiveRoom"]').innerHTML.split("'")[0].toLowerCase();
  228. test();
  229. }
  230. //==========bio things
  231. function dobiothings(){
  232. bio=true;
  233. var toptext = document.querySelector('[data-testid="bio-header"]').innerHTML;
  234. if(currpage.split("/")[3]=="p"){
  235. document.querySelector('[data-testid="bio-header"]').innerHTML="<a href='https://chaturbate.com/"+roomname+"?tab=bio' id=biotop>"+toptext+"</a>"
  236. }else{
  237. document.querySelector('[data-testid="bio-header"]').innerHTML="<a href='https://chaturbate.com/p/"+roomname+"?tab=bio' id=biotop>"+toptext+"</a>"
  238. }
  239. document.getElementById("biotop").addEventListener("click", function(event){window.location.replace(this.href);event.stopPropagation();event.preventDefault();return false});
  240. makevidcontrol();
  241. cleaninit();
  242. linkfix();
  243. info();
  244. buildnotepop();
  245. getnoteslist();
  246. if (document.getElementsByTagName("video").length>0){
  247. getvid();
  248. vreset();
  249. document.getElementsByClassName('cbLogo')[0].style.display="none";
  250. pmlistner();
  251. iagree();
  252. }
  253. }
  254.  
  255. //===========thumpage things
  256. function dothumbpagethings(){
  257. if (!discoverpage){
  258. observer.observe(document.querySelector('title'),observerConfig);
  259. subsel();
  260. refresher();
  261. }
  262. buildnotepop();
  263. getnoteslist();// goes on to setupmove
  264. return;
  265. }
  266.  
  267. //========== agree room rules
  268. function iagree(){
  269. if (document.getElementsByClassName("acceptRulesButton").length>0){
  270. document.getElementsByClassName("acceptRulesButton")[0].click();
  271. }
  272. }
  273.  
  274. //==============set styles
  275. function setstyles(){
  276. var style = document.createElement('style');
  277. style.setAttribute('type', 'text/css');
  278. style.textContent = ".content{overflow: visible; !important ;margin-right:33px !important;margin-left:33px !important}"+
  279. ".list{overflow: visible !important}"+
  280. ".MoreRooms{overflow: visible !important}"+
  281. ".BioContents{position:relative !important}"+
  282. ".followedDropdown{z-index:50 !important}"+
  283. ".userUpload img{display:none}"+
  284. ".lockOverlayBg {background-color:rgba(0, 0, 0, 0) !important;top:50% !important}"+
  285. ".lockOverlayBg img{display:none}"+
  286. ".userUpload div{background-color:rgba(0, 0, 0, 0) !important}"+
  287. ".previewBorder {display:block !important}"+
  288. ".previewText {color:black !important}"+
  289. ".photoVideoDetailSection img{filter: blur(0px) !important;height:auto !important;width:auto !important; margin-left: auto;margin-right: auto;display:block;min-width:50%;min-height:50%;max-width:100%;max-height:100%}"+
  290. ".roomCard {transition: transform .3s}"+
  291. ".roomCard:hover {transform: scale(1.37);border-color:red;z-index:20}";
  292. document.getElementsByTagName('head')[0].appendChild(style);
  293. }
  294.  
  295. function setadstyle(){
  296. var style = document.createElement('style');
  297. style.setAttribute('type', 'text/css');
  298. style.textContent = ".ad {background-image:linear-gradient(to right,white 1%, darkred 1%);background-size:220% 100%;background-position:2%;padding:8px;color:white;height:40px !important;font-weight: bold;border-radius:5px}"+
  299. ".ad {transition: 1.0s ease-in-out;}"+
  300. ".ad:hover {background-position: 200% }";
  301. document.getElementsByTagName('head')[0].appendChild(style);
  302. }
  303.  
  304. //================ get usernotelist , continues to setupmove
  305. function getnoteslist(){
  306. if(!login){usernoteslist="";whatpage();return}
  307. var url="https://chaturbate.com/api/notes/usernames/";
  308. fetch(url,{ credentials: "same-origin"}).then(
  309. function(response) {
  310. if (response.status !== 200){
  311. return;
  312. }
  313. response.json().then(function(data) {
  314. usernoteslist=data;
  315. }).then(whatpage);
  316. });
  317. }
  318.  
  319. function whatpage(){
  320. setupfollowmove();
  321. if (thumbpage){setupmove()}
  322. if (bio){setupbiomove()}
  323. if (discoverpage){
  324. setInterval(addevent2,5000);
  325. }
  326. }
  327.  
  328. //===============observer on followed thumbs
  329. function setupfollowmove(){
  330. var observenode=document.getElementsByClassName("followedDropdown")[0];
  331. observer6.observe(observenode,observerConfig6); // calls adjustfollowthumbs
  332. }
  333.  
  334. function adjustfollowhumbs(){
  335. if (document.getElementsByClassName("followedDropdown")[0].style.display!="block"){return}
  336. addevent2();
  337. }
  338.  
  339. //================= observer on the page thumbnails
  340. function setupmove(){
  341. var observenode=document.getElementsByClassName("list")[0];
  342. observer4.observe(observenode,observerConfig4); // calls adjustthumbs
  343. adjusthumbs();
  344. addevent2();
  345. }
  346.  
  347. //============= adjust thumbs on a thumbnail page - call again if changed extra list can be added if spy on cams<< observer4 calls this
  348. function adjusthumbs(){
  349. if (document.getElementsByClassName("list")[0].classList.contains("loading")){return};
  350. document.getElementById("notepop").style.display="none";
  351. if (document.getElementsByClassName("list").length>1){
  352. //=========== 2 list so add evend to the second one too but only once
  353. var observenode=document.getElementsByClassName("list")[1];
  354. observer41.observe(observenode,observerConfig4);
  355. setTimeout(addevent2, 1000);
  356. }else{
  357. addevent2();
  358. }
  359. }
  360.  
  361. //============== adjust thumbs on bio more rooms like this
  362. function setupbiomove(){
  363. var observenode=document.querySelector('[data-testid="more-rooms-like-this-tab-contents"]').firstChild;
  364. observer5.observe(observenode,observerConfig5);
  365. addevent2();
  366. }
  367.  
  368. function adjustbiohumbs(){
  369. if(document.querySelector('[data-testid="more-rooms-like-this-tab-contents"]').firstChild.style.display=="block"){return};
  370. addevent2();
  371. }
  372.  
  373. //====== put event and note symbol in the thumbnails
  374. function addevent2(){
  375. if (currpage!=document.location.href){
  376. document.getElementById("notepop").style.display="none";
  377. }
  378. currpage=document.location.href;
  379. var tags=document.querySelectorAll('[data-testid="room-card-image"]');
  380. for (n=0; n<tags.length; n++){
  381. if(!tags[n].name){
  382. tags[n].parentNode.href=tags[n].parentNode.href+"?tab=bio";
  383. tags[n].parentNode.addEventListener("click", function(event){document.location.href=this.href;event.stopPropagation();event.preventDefault();return false});
  384. tags[n].name="Camslut";
  385. if (!supporter){
  386. tags[n].parentNode.parentNode.addEventListener("mouseenter", moveimg);
  387. tags[n].parentNode.parentNode.addEventListener("mouseleave", moveimgstop);
  388. }
  389. var name=tags[n].parentNode.parentNode.querySelector('[data-testid="room-card-username"]');
  390. var thumbroomname=name.innerHTML;
  391. name.href="https://chaturbate.com/p/"+thumbroomname+"/?tab=bio";
  392. name.addEventListener("click", function(event){document.location.href=this.href;event.stopPropagation();event.preventDefault();return false});
  393.  
  394. if (usernoteslist!=""){ // not loggedin
  395. if (tags[n].parentNode.parentNode.className=="roomCard camBgColor"){
  396. var newelem=document.createElement('div');
  397. if (usernoteslist.usernames.indexOf(thumbroomname)!=-1){
  398. newelem.innerHTML=note;
  399. }else{
  400. newelem.innerHTML=nonote;
  401. }
  402. newelem.style.position="absolute";
  403. newelem.style.top="0px";
  404. newelem.style.left="0px";
  405. newelem.addEventListener("click", shownote );
  406. newelem.style.cursor="pointer";
  407. newelem.setAttribute("name", thumbroomname);
  408. newelem.name=thumbroomname;
  409. newelem.title="User notes";
  410. tags[n].parentNode.parentNode.appendChild(newelem);
  411. }
  412. }
  413. }
  414. }
  415. showhidden();
  416. }
  417.  
  418. //======================================== hidden tag in followed rooms
  419. function showhidden(){
  420. if (document.location.href.split("/")[3]=="spy-on-cams"){showhidden4();return;}
  421. if (document.location.href.split("/")[3]!="followed-cams"){return;}
  422. if (document.location.href.split("/")[4]=="offline"){return;}
  423. if (!document.querySelector('[data-testid="room-card-image"]')){return;}
  424. if (document.querySelector('[data-testid="room-card-image"]').name=="hid"){return};
  425. document.querySelector('[data-testid="room-card-image"]').name="hid";
  426. hidoffset=0;
  427. hiddenarray=[];
  428. showhidden2();
  429. }
  430.  
  431. function showhidden2(){
  432. if (hprom){return}
  433. hprom=true;
  434. var url=hidurl+hidoffset*90;
  435. fetch(url,{ credentials: "same-origin"}).then(
  436. function(response) {
  437. if (response.status !== 200) {
  438. hprom=false;
  439. return;
  440. }
  441. response.json().then(function(data){
  442. if (data.rooms != null){
  443. var hiddenlist=data.rooms;
  444. for (n=0; n<hiddenlist.length; n++){
  445. hiddenarray.push(hiddenlist[n].username);
  446. }
  447. var pages=Math.ceil(data.total_count/90);//1.....
  448. hidoffset++;//0.....
  449. if (hidoffset!=pages){
  450. hprom=false;
  451. showhidden2();
  452. }else{
  453. hprom=false;
  454. showhidden3();
  455. }
  456. }
  457. });
  458. });
  459. }
  460.  
  461. function showhidden3(){
  462. var tags=document.querySelector('[data-testid="room-list-container"]').querySelectorAll('[data-testid="room-card"]');
  463. for (n=0; n<tags.length; n++){
  464. var name=tags[n].querySelector('[data-testid="room-card-username"]').innerHTML;
  465. if (hiddenarray.indexOf(name)!=-1){
  466. tags[n].querySelector('[data-testid="thumbnail-label"]').innerHTML=tags[n].querySelector('[data-testid="thumbnail-label"]').innerHTML+" HIDDEN ";
  467. tags[n].querySelector('[data-testid="thumbnail-label"]').style.backgroundColor = "blue";
  468. }
  469. }
  470. }
  471. function showhidden4(){//useless ;-)
  472. if (document.querySelectorAll('[data-testid="room-list-container"]')[1].querySelector('[data-testid="room-card-image"]').name=="hid"){return};
  473. document.querySelectorAll('[data-testid="room-list-container"]')[1].querySelector('[data-testid="room-card-image"]').name="hid";
  474. var tags=document.querySelectorAll('[data-testid="room-list-container"]')[1].querySelectorAll('[data-testid="room-card"]');
  475. for (n=0; n<tags.length; n++){
  476. tags[n].querySelector('[data-testid="thumbnail-label"]').innerHTML=tags[n].querySelector('[data-testid="thumbnail-label"]').innerHTML+" HIDDEN ";
  477. tags[n].querySelector('[data-testid="thumbnail-label"]').style.backgroundColor = "blue";
  478. }
  479. }
  480.  
  481. //================= show note
  482. function shownote(e){
  483. if(( document.getElementById("notepop").style.display=="block")&&(openthumbname==this.name)){
  484. document.getElementById("notepop").style.display="none";
  485. openthumbname="";
  486. return;
  487. }
  488. document.getElementById("notepop").style.height="170px";
  489. document.getElementById("notearea").value="";
  490. document.getElementById("notenote").innerHTML=notegrey + " Note";
  491. opennote="";
  492. openthumbname=this.name;
  493. var xpos=e.pageX;
  494. document.getElementById("notearea").innerHTML="";
  495. document.getElementById("notepop").style.top=e.pageY+100+"px";
  496. document.getElementById("notepop").style.left=xpos+20+"px";
  497. document.getElementById("notepop").style.display="block";
  498. document.getElementById("notepopName").innerHTML=openthumbname;
  499.  
  500. if (usernoteslist.usernames.indexOf(openthumbname)!=-1){
  501. var url="https://chaturbate.com/api/notes/for_user/"+openthumbname+"/";
  502. fetch(url,{ credentials: "same-origin"}).then(
  503. function(response) {
  504. if (response.status !== 200) {
  505. return;
  506. }
  507. response.json().then(function(data){
  508. if (data.text != null){
  509. document.getElementById("notearea").value=data.text;
  510. opennote=data.text;
  511. }
  512. });
  513. });
  514. }
  515. }
  516.  
  517. //==========make pop up notes
  518. function buildnotepop(){
  519. var newelem=document.createElement('span');
  520. newelem.id="notepop";
  521. newelem.style.display="none";
  522. newelem.style.position="absolute";
  523. newelem.style.overflow="hidden"
  524. newelem.style.backgroundColor="rgb(255, 255, 255)";
  525. newelem.style.border="1px solid rgb(221, 221, 221)";
  526. newelem.style.borderRadius="4px";
  527. newelem.style.width="188px";
  528. newelem.style.height="170px";
  529. newelem.style.zIndex="999";
  530. newelem.style.boxShadow="0px 0px 32px rgba(0, 0, 0, 0.32)";
  531. document.getElementById("footer-holder").appendChild(newelem);
  532.  
  533. newelem=document.createElement('div');
  534. newelem.style.backgroundColor = "#dddddd";
  535. newelem.style.color="grey";
  536. newelem.style.fontWeight="bold";
  537. newelem.style.height="15px";
  538. newelem.style.fontSize="15px";
  539. newelem.style.padding="8px";
  540. newelem.style.textAlign="left"
  541. newelem.innerHTML='<span id="notepopName" style="text-Overflow: ellipsis; overflow:hidden; width:150px; height:20px; display:inline-block" ></span><span><img src="https://web.static.mmcdn.com/tsdefaultassets/close-gray.svg" style="position: absolute; height: 13px; width: 13px; right: 8px;" title="Close" id="noteclose"></span>';
  542. document.getElementById("notepop").appendChild(newelem);
  543.  
  544. document.getElementById("noteclose").addEventListener("click", notepopclose);
  545.  
  546. newelem=document.createElement('div');
  547. newelem.style.backgroundColor = "white";
  548. newelem.style.border="1px solid rgb(221, 221, 221)";
  549. newelem.style.color="grey";
  550. newelem.style.height="15px";
  551. newelem.style.fontSize="12px";
  552. newelem.style.padding="8px";
  553. newelem.style.textAlign="left"
  554. newelem.style.cursor="pointer";
  555. newelem.addEventListener("click", function(){opendm2(document.getElementById("notepopName").innerHTML)} );
  556. newelem.id="notepopLink";
  557. newelem.innerHTML='<img src="https://web.static.mmcdn.com/tsdefaultassets/popout-grey-d.svg" height="12px" width="12px"> Popout in new window';
  558. document.getElementById("notepop").appendChild(newelem);
  559.  
  560. newelem=document.createElement('div');
  561. newelem.style.backgroundColor = "white";
  562. newelem.style.color="grey";
  563. newelem.style.height="10px";
  564. newelem.style.fontSize="12px";
  565. newelem.style.padding="8px";
  566. newelem.style.textAlign="left"
  567. newelem.id="notenote";
  568. newelem.innerHTML=notegrey + " Note";
  569. document.getElementById("notepop").appendChild(newelem);
  570.  
  571. newelem=document.createElement('textarea');
  572. newelem.id="notearea";
  573. newelem.style.height="60px";
  574. newelem.style.fontSize="12px";
  575. newelem.style.border="1px solid rgb(172, 172, 172)";
  576. newelem.style.borderRadius="4px";
  577. newelem.style.backgroundColor="rgb(255, 255, 255)";
  578. newelem.style.resize="none";
  579. newelem.style.padding="5px";
  580. newelem.style.width="85%";
  581. newelem.setAttribute("placeholder", "Enter notes about this user (only seen by you)");
  582. newelem.setAttribute("spellcheck", false);
  583. newelem.addEventListener("input",openbutton);
  584. newelem.id="notearea";
  585. document.getElementById("notepop").appendChild(newelem);
  586.  
  587. newelem=document.createElement('div');
  588. newelem.id="notecancelsubmit";
  589. document.getElementById("notepop").appendChild(newelem);
  590.  
  591. newelem=document.createElement("span");
  592. newelem.style.position="relative";
  593. newelem.style.top="12px";
  594. newelem.style.left="-15px";
  595. newelem.addEventListener("click",closebutton);
  596. newelem.innerHTML='<a href="#" >Cancel</a>';
  597. document.getElementById("notecancelsubmit").appendChild(newelem);
  598.  
  599. var subbutstyle="color: rgb(255, 255, 255); background: rgba(0, 0, 0, 0) linear-gradient(rgb(255, 151, 53) 0%, rgb(255, 158, 54) 50%, rgb(255, 112, 2) 60%) repeat scroll 0% 0%; font-family: UbuntuMedium, Helvetica, Arial, sans-serif; font-size: 12px; padding: 4px 10px 5px; position: relative; right: 40px; top:10px; float: right; border-radius: 4px; cursor: pointer;";
  600.  
  601. newelem=document.createElement("span");
  602. newelem.setAttribute("style", subbutstyle);
  603. newelem.addEventListener("click",savenote);
  604. newelem.innerHTML="Save"
  605. document.getElementById("notecancelsubmit").appendChild(newelem);
  606. }
  607. //============= save note
  608. function savenote(){
  609. var notetext=document.getElementById("notearea").value;
  610. var url="https://chaturbate.com/api/notes/for_user/"+openthumbname+"/";
  611. var csrftoken= readCookie("csrftoken");
  612. var data = new FormData();
  613. data.append( "text", notetext );
  614. fetch(url,
  615. {
  616. method: "POST",
  617. headers: {
  618. 'x-csrftoken': csrftoken,
  619. 'x-requested-with': 'XMLHttpRequest'
  620. },
  621. body: data
  622. }).then(aftersave)
  623. }
  624.  
  625. function aftersave(){
  626. var notetext=document.getElementById("notearea").value;
  627. var doupdate=false;
  628. if ((opennote=="")||(notetext=="")){
  629. doupdate=true;
  630. }
  631. opennote=notetext;
  632. closebutton();
  633. if (doupdate){updatedm()}
  634. }
  635.  
  636. function notepopclose(){
  637. document.getElementById("notepop").style.display="none"
  638. }
  639.  
  640. function openbutton(){
  641. document.getElementById("notepop").style.height="215px";
  642. document.getElementById("notenote").innerHTML=notegrey + " Note (unsaved)";
  643. document.getElementById("notearea").value=document.getElementById("notearea").value.replace("$"," "+new Date().toLocaleDateString()+" ");
  644. if(opennote==document.getElementById("notearea").value){
  645. closebutton()
  646. }
  647. }
  648. function closebutton(){
  649. document.getElementById("notenote").innerHTML=notegrey + " Note";
  650. document.getElementById("notepop").style.height="170px";
  651. document.getElementById("notearea").value=opennote;
  652. }
  653. //=========== DM window
  654. function opendm2(that){
  655. var url="http://chaturbate.com/dm/"+that;
  656. var dmwindow=window.open(url,that,'toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=yes,width=800,height=800');
  657. dmwindow.onload = function(){
  658. this.addEventListener('unload', function(){setTimeout(function(){updatedm();},1000);})
  659. }
  660. }
  661.  
  662. function updatedm(){
  663. var url="https://chaturbate.com/api/notes/usernames/";
  664. fetch(url,{ credentials: "same-origin"}).then(
  665. function(response) {
  666. if (response.status !== 200){
  667. return;
  668. }
  669. response.json().then(function(data) {
  670. usernoteslist=data;
  671. }).then(updatedm2);
  672. });
  673. }
  674.  
  675. function updatedm2(){
  676. var tags=document.querySelectorAll('[title="User notes"]');
  677. for (n=0; n<tags.length; n++){
  678. if (usernoteslist.usernames.indexOf(tags[n].getAttribute("name"))!=-1){
  679. tags[n].innerHTML=note;
  680. }else{
  681. tags[n].innerHTML=nonote;
  682. }
  683. }
  684. }
  685.  
  686. //=========== animated thumbs
  687. function moveimg(){ //comes from holder
  688. thisfap=this;
  689. fapbr=thisfap.getElementsByTagName("img")[0].src.split("/")[4].split("?")[0];
  690. cimg.addEventListener("load",regetimg);
  691. cimg.src = "https://jpeg.live.mmcdn.com/minifwap/"+fapbr+"?f="+ new Date().getTime();
  692. }
  693.  
  694. function moveimgstop(){ // comes from holder
  695. cimg.removeEventListener("load",regetimg);
  696. }
  697.  
  698. function regetimg(){
  699. thisfap.getElementsByTagName("img")[0].src=cimg.src;
  700. setTimeout(function(){ cimg.src = "https://jpeg.live.mmcdn.com/minifwap/"+fapbr+"?f="+ new Date().getTime();}, 50);//~6fps at 100ms load time
  701. }
  702.  
  703. //========refresh after tab change
  704. function refresher(){
  705. if ((currpage.split("/")[3]=="followed-cams")||(currpage.split("/")[3]=="spy-on-cams")){
  706. document.addEventListener("visibilitychange", () => {
  707. if (!document.hidden) {
  708. location.reload();
  709. }
  710. });
  711. }
  712. }
  713. //=========adds and stuff
  714. function noadd(){
  715. if (document.getElementsByClassName('ad').length>0){
  716. var info=scriptname+" version "+version+" is active."
  717. if (!readCookie("goodboy")){
  718. if (!login){
  719. info=info+"<br>Support this script, <a href='"+tour+"'>create a new account.</a>";
  720. if(document.querySelector('[data-testid="sign-up-tab"]')){
  721. document.querySelector('[data-testid="sign-up-tab"]').href=tour;
  722. }
  723. }else{
  724. info=info+"<br>Support this script,<a href='https://chaturbate.com/auth/logout/'> log out </a>and create a new account.";
  725. }
  726. document.getElementsByClassName('ad')[0].innerHTML=info;
  727. }else{
  728. document.getElementsByClassName('ad')[0].innerHTML=info+"<br>Thank you for your support.";
  729. }
  730. }
  731. }
  732. function aff(){
  733. if (currpage=="https://chaturbate.com/accounts/welcome/"){createCookie("goodboy","1",14);return;}
  734. if (currpage.split("?").length>1){
  735. if (currpage.split("?")[1].indexOf("campaign=hgg5k")!=-1){// me as aff
  736. createCookie("agreeterms","1",30);
  737. if (!login){
  738. document.location.href="https://chaturbate.com/accounts/register/?src=header&auipsrc=navbar";// direct to signup if not loggedd in on my tour
  739. }
  740. return;
  741. }
  742. if (currpage.split("?")[1].indexOf("campaign=")!=-1){ // some other aff
  743. if(!login){
  744. untrace();
  745. document.location.href=tour;// go to my tour if not logged in
  746. }
  747. return;
  748. }
  749. }
  750. if (currpage.split("?")[0]=="https://chaturbate.com/auth/login/"){// clear traces of other accounts when you login
  751. localStorage.clear();
  752. sessionStorage.clear();
  753. }
  754. if (currpage.split("?")[0]=="https://chaturbate.com/accounts/register/"){// signup from my tour
  755. localStorage.clear();
  756. sessionStorage.clear();
  757. }
  758. }
  759. function untrace(){
  760. var cookies = document.cookie.split("; ");
  761. for (var c = 0; c < cookies.length; c++) {
  762. var d = window.location.hostname.split(".");
  763. while (d.length > 0) {
  764. var cookieBase = encodeURIComponent(cookies[c].split(";")[0].split("=")[0]) + '=; expires=Thu, 01-Jan-1970 00:00:01 GMT; domain=' + d.join('.') + ' ;path=';
  765. var p = location.pathname.split('/');
  766. document.cookie = cookieBase + '/';
  767. while (p.length > 0) {
  768. document.cookie = cookieBase + p.join('/');
  769. p.pop();
  770. };
  771. d.shift();
  772. }
  773. }
  774. localStorage.clear();
  775. sessionStorage.clear();
  776. }
  777.  
  778. //=======subselector
  779. function subsel(){
  780. createCookie("selected",currpage,1);
  781. if((document.location.href.indexOf("spy-on-cams")==-1)&&(document.location.href.indexOf("followed-cams")==-1)&&(document.location.href.indexOf("/current_app_use/")==-1)){
  782. var newelem=document.createElement('li');
  783. var data='<form><select id="subsel" style="margin: 0px 0px 0px 0px; background: #DDE9F5; color:#5E81A4; border-radius: 4px 4px 0px 0px;padding: 5px 1px 4px 12px; font-weight: 400; font-size: 13px; font-family: \'UbuntuMedium\',Arial,Helvetica,sans-serif;" >'+
  784. '<option value="/XX-cams">ALL CAMS IN CATEGORY</option>'+
  785. '<option value="/exhibitionist-cams/XX">EXHIBITIONIST CAMS</option>'+
  786. '<option value="/gaming-cams/XX">GAMING CAMS</option>'+
  787. '<option value="/new-cams/XX">NEW CAMS</option>'+
  788. '<option value="/teen-cams/XX">TEEN CAMS (18+)</option>'+
  789. '<option value="/18to21-cams/XX">18 TO 21 CAMS</option>'+
  790. '<option value="/21to35-cams/XX">21 TO 35 CAMS</option>'+
  791. '<option value="/30to50-cams/XX">30 TO 50 CAMS</option>'+
  792. '<option value="/mature-cams/XX">MATURE CAMS (50+)</option>'+
  793. '<option value="/north-american-cams/XX">NORTH AMERICAN CAMS</option>'+
  794. '<option value="/euro-russian-cams/XX">EURO RUSSIAN CAMS</option>'+
  795. '<option value="/south-american-cams/XX">SOUTH AMERICAN CAMS</option>'+
  796. '<option value="/asian-cams/XX">ASIAN CAMS</option>'+
  797. '<option value="/other-region-cams/XX">OTHER REGION CAMS</option>'+
  798. '<option value="/6-tokens-per-minute-private-cams/XX">6 TOKENS PER MINUTE</option>'+
  799. '<option value="/12-18-tokens-per-minute-private-cams/XX">12 - 18 TOKENS PER MINUTE</option>'+
  800. '<option value="/30-42-tokens-per-minute-private-cams/XX">30 - 42 TOKENS PER MINUTE</option>'+
  801. '<option value="/60-72-tokens-per-minute-private-cams/XX">60 - 72 TOKENS PER MINUTE</option>'+
  802. '<option value="/90-tokens-per-minute-private-cams/XX">90+ TOKENS PER MINUTE</option>'+
  803. '</select></form>';
  804. var uloc=document.location.href+"//";
  805. var loc=uloc.split("/");
  806. var check=loc[3]+loc[4];
  807. var gen="";
  808. if(check.indexOf("male") != -1){gen="male";}
  809. if(check.indexOf("female") != -1){gen="female";}
  810. if(check.indexOf("couple") != -1){gen="couple";}
  811. if(check.indexOf("trans") != -1){gen="trans";}
  812. data=data.replace(/XX/gi,gen);
  813. if (gen === ""){data=data.replace("-cams","");}
  814. data=data.replace('<option value="/'+loc[3],'<option selected value="/'+loc[3]);
  815. newelem.innerHTML=data;
  816. document.getElementsByClassName('sub-nav')[0].appendChild(newelem);
  817. document.getElementById("subsel").addEventListener('change',subselected);
  818. }
  819. }
  820.  
  821. //============go to the selected page
  822. function subselected(){
  823. document.location.href=document.getElementById("subsel").options[document.getElementById("subsel").selectedIndex].value;
  824. }
  825.  
  826. //==========see pm in chat
  827. function pmlistner(){
  828. setTimeout(function(){
  829. pmobservenode=document.getElementById('pm-tab-default');//split mode
  830. pmobservenode2=document.getElementById('pm-tab-fvm');// full video mode
  831. pmobserver.observe(pmobservenode, pmobserverConfig);
  832. pmobserver2.observe(pmobservenode2, pmobserverConfig);
  833. }, 2000);
  834. }
  835.  
  836. //=================PM in tab
  837. function tabpm(){
  838. if (document.visibilityState=="visible"){return;}//tab is in focus, do nothing
  839. if ((pmobservenode.getElementsByTagName("span")[0].innerHTML=="PM")||(pmobservenode2.getElementsByTagName("span")[0].innerHTML=="PM")){return;}// if 1 of 2 is only "PM" then pm tab is open
  840. if (tabblink==true){return;}// already blinking
  841. tabblink=true;
  842. tabblinker();
  843. }
  844.  
  845. function tabblinker(){
  846. if (document.title == "PM !! PM"){
  847. document.title = "!! PM !!";
  848. }else{
  849. document.title = "PM !! PM";
  850. }
  851. if (document.visibilityState!="visible"){ // tab out focus
  852. setTimeout(tabblinker,500);
  853. }else{// tab became in focus
  854. document.title=ctitle;
  855. tabblink=false;
  856. }
  857. }
  858.  
  859. //=================================== make all new buttons and sliders and set the video filter
  860. function makevidcontrol(){
  861. var slistyle="text-align: left; width: 310px;margin-right: 4px;color: rgb(255, 255, 255); background: rgba(0, 0, 0, 0) linear-gradient(rgb(255, 151, 53) 0%, rgb(255, 158, 54) 50%, rgb(255, 112, 2) 60%) repeat scroll 0% 0%; font-family: UbuntuMedium, Helvetica, Arial, sans-serif; font-size: 12px; text-shadow: rgb(241, 129, 18) 1px 1px 0px; padding: 4px 10px 3px; position: relative; top: 0px; right: 1px; float: right; border-radius: 4px; display: inline;";
  862. var butstyle="margin-right: 5px;color: rgb(255, 255, 255); background: rgba(0, 0, 0, 0) linear-gradient(rgb(255, 151, 53) 0%, rgb(255, 158, 54) 50%, rgb(255, 112, 2) 60%) repeat scroll 0% 0%; font-family: UbuntuMedium, Helvetica, Arial, sans-serif; font-size: 12px; text-shadow: rgb(241, 129, 18) 1px 1px 0px; padding: 4px 10px 3px; position: relative;right: 1px;top:-4px; float: right; border-radius: 4px; cursor: pointer; display: inline;";
  863. var cbutstyle="margin-right: 5px;color: rgb(255, 255, 255); background: rgba(0, 0, 0, 0) linear-gradient(rgb(255, 151, 53) 0%, rgb(255, 158, 54) 50%, rgb(255, 112, 2) 60%) repeat scroll 0% 0%; font-family: UbuntuMedium, Helvetica, Arial, sans-serif; font-size: 12px; text-shadow: rgb(241, 129, 18) 1px 1px 0px; padding: 4px 10px 3px; position: relative;right: 1px; float: right; border-radius: 4px; cursor: pointer; display: inline;";
  864.  
  865. if (document.getElementById("satisfactionScore")){
  866. var place=document.getElementById("satisfactionScore");
  867. }else{
  868. place=document.getElementsByClassName("gradient SatisfactionRating")[0];
  869. }
  870.  
  871. var newelem=document.createElement('span');
  872. newelem.setAttribute("style", butstyle);
  873. newelem.innerHTML="VIDEO CONTROLS ON/OFF";
  874. newelem.addEventListener("click", vcontrol);
  875. newelem.id="vcontr";
  876. document.querySelector('[data-testid="room-tab-bar"]').insertBefore(newelem,place.nextSibling);
  877.  
  878. newelem=document.createElement('span');
  879. newelem.setAttribute("style", butstyle);
  880. newelem.style.display="none";
  881. newelem.innerHTML="CHAT CONTROLS ON/OFF";
  882. newelem.addEventListener("click", ccontrol);
  883. newelem.id="ccontr";
  884. document.querySelector('[data-testid="room-tab-bar"]').insertBefore(newelem,place.nextSibling);
  885.  
  886. newelem=document.createElement('span');
  887. newelem.setAttribute("style", butstyle);
  888. newelem.innerHTML="CLEAN PROFILE = ON";
  889. newelem.style.width="125px";
  890. newelem.style.display="none";
  891. newelem.id="clean";
  892. newelem.addEventListener("click", cleancookie);
  893. document.querySelector('[data-testid="room-tab-bar"]').insertBefore(newelem,place.nextSibling);
  894.  
  895. newelem=document.createElement('span');
  896. newelem.setAttribute("style", butstyle);
  897. newelem.innerHTML="RELOAD INFO";
  898. newelem.addEventListener("click", newinfo);
  899. newelem.id="infore";
  900. document.querySelector('[data-testid="room-tab-bar"]').insertBefore(newelem,place.nextSibling);
  901.  
  902. newelem=document.createElement('div');
  903. newelem.id="controls";
  904. newelem.style.display="none";
  905. newelem.style.position="absolute";
  906. newelem.style.backgroundColor="rgb(255, 255, 211)";
  907. newelem.style.border="2px solid rgb(244, 115, 33)";
  908. newelem.style.borderRadius="6px";
  909. newelem.style.width="340px";
  910. newelem.style.padding="12px";
  911. newelem.style.marginTop="600px";
  912. newelem.style.right="320px";
  913. newelem.style.zIndex="999";
  914. document.getElementById("user_information").appendChild(newelem);
  915.  
  916. newelem=document.createElement('span');
  917. newelem.setAttribute("style", cbutstyle);
  918. newelem.innerHTML="MIRROR VIDEO";
  919. newelem.addEventListener("click",mirror);
  920. document.getElementById("controls").appendChild(newelem);
  921.  
  922. newelem=document.createElement('span');
  923. newelem.setAttribute("style", cbutstyle);
  924. newelem.innerHTML="INVERT VIDEO";
  925. newelem.addEventListener("click",invert);
  926. document.getElementById("controls").appendChild(newelem);
  927.  
  928. newelem=document.createElement('span');
  929. newelem.setAttribute("style", cbutstyle);
  930. newelem.innerHTML="DRAG";
  931. newelem.style.cursor="move";
  932. newelem.addEventListener("mousedown",dragMouseDown);
  933. document.getElementById("controls").appendChild(newelem);
  934.  
  935. newelem=document.createElement('br');
  936. document.getElementById("controls").appendChild(newelem);
  937. newelem=document.createElement('br');
  938. document.getElementById("controls").appendChild(newelem);
  939.  
  940. newelem=document.createElement('span');
  941. newelem.setAttribute("style", slistyle);
  942. newelem.innerHTML="BRIGHTNESS : <input type='range' id='myRange' min=0 max=200 value=100 style='width: 200px;height:11px;cursor: pointer;float: right;'>";
  943. document.getElementById("controls").appendChild(newelem);
  944. document.getElementById("myRange").addEventListener("input",badjust);
  945.  
  946. newelem=document.createElement('br');
  947. document.getElementById("controls").appendChild(newelem);
  948. newelem=document.createElement('br');
  949. document.getElementById("controls").appendChild(newelem);
  950.  
  951. newelem=document.createElement('span');
  952. newelem.setAttribute("style", slistyle);
  953. newelem.innerHTML="CONTRAST : <input type='range' id='myRange1' min=0 max=200 value=100 style='width: 200px;height:11px;cursor: pointer;float: right;'>";
  954. document.getElementById("controls").appendChild(newelem);
  955. document.getElementById("myRange1").addEventListener("input",cadjust);
  956.  
  957. newelem=document.createElement('br');
  958. document.getElementById("controls").appendChild(newelem);
  959. newelem=document.createElement('br');
  960. document.getElementById("controls").appendChild(newelem);
  961.  
  962. newelem=document.createElement('span');
  963. newelem.setAttribute("style", slistyle);
  964. newelem.innerHTML="SATURATION : <input type='range' id='myRange2' min=0 max=200 value=100 style='width: 200px;height:11px;cursor: pointer;float: right;'>";
  965. document.getElementById("controls").appendChild(newelem);
  966. document.getElementById("myRange2").addEventListener("input",sadjust);
  967.  
  968. newelem=document.createElement('br');
  969. document.getElementById("controls").appendChild(newelem);
  970. newelem=document.createElement('br');
  971. document.getElementById("controls").appendChild(newelem);
  972.  
  973. newelem=document.createElement('span');
  974. newelem.setAttribute("style", slistyle);
  975. newelem.innerHTML="HUE : <input type='range' id='myRange3' min=180 max=540 value=360 style='width: 200px;height:11px;cursor: pointer;float: right;'>";
  976. document.getElementById("controls").appendChild(newelem);
  977. document.getElementById("myRange3").addEventListener("input",hadjust);
  978.  
  979. newelem=document.createElement('br');
  980. document.getElementById("controls").appendChild(newelem);
  981. newelem=document.createElement('br');
  982. document.getElementById("controls").appendChild(newelem);
  983.  
  984. newelem=document.createElement('span');
  985. newelem.setAttribute("style", cbutstyle);
  986. newelem.innerHTML="HIDE CONTROL PANEL";
  987. newelem.addEventListener("click",vcontrol);
  988. document.getElementById("controls").appendChild(newelem);
  989.  
  990. newelem=document.createElement('span');
  991. newelem.setAttribute("style", cbutstyle);
  992. newelem.innerHTML="RESET ALL";
  993. newelem.addEventListener("click",vreset);
  994. document.getElementById("controls").appendChild(newelem);
  995.  
  996. newelem=document.createElement('div');
  997. newelem.id="chatcontrols";
  998. newelem.style.display="none";
  999. newelem.style.position="absolute";
  1000. newelem.style.backgroundColor="rgb(255, 255, 211)";
  1001. newelem.style.border="2px solid rgb(244, 115, 33)";
  1002. newelem.style.borderRadius="6px";
  1003. newelem.style.width="340px";
  1004. newelem.style.padding="12px";
  1005. newelem.style.top="40px";
  1006. newelem.style.right="10px";
  1007. newelem.style.zIndex="99";
  1008. document.querySelector('[data-testid="room-tab-bar"]').insertBefore(newelem,place.nextSibling);
  1009.  
  1010. newelem=document.createElement('span');
  1011. newelem.setAttribute("style", slistyle);
  1012. newelem.style.margin="2px";
  1013. newelem.innerHTML="Small emoticons : <input type='range' id='c1' min=0 max=1 value=0 style='width: 40px;height:11px;cursor: pointer;float: right;'>";
  1014. document.getElementById("chatcontrols").appendChild(newelem);
  1015.  
  1016. newelem=document.createElement('span');
  1017. newelem.setAttribute("style", slistyle);
  1018. newelem.style.margin="2px";
  1019. newelem.innerHTML="Notice : <input type='range' id='c2' min=0 max=1 value=0 style='width: 40px;height:11px;cursor: pointer;float: right;'>";
  1020. document.getElementById("chatcontrols").appendChild(newelem);
  1021.  
  1022. newelem=document.createElement('span');
  1023. newelem.setAttribute("style", slistyle);
  1024. newelem.style.margin="2px";
  1025. newelem.innerHTML="Subject change : <input type='range' id='c3' min=0 max=1 value=0 style='width: 40px;height:11px;cursor: pointer;float: right;'>";
  1026. document.getElementById("chatcontrols").appendChild(newelem);
  1027.  
  1028. newelem=document.createElement('span');
  1029. newelem.setAttribute("style", slistyle);
  1030. newelem.style.margin="2px";
  1031. newelem.innerHTML="Mod/fan enter-leave : <input type='range' id='c4' min=0 max=1 value=0 style='width: 40px;height:11px;cursor: pointer;float: right;'>";
  1032. if (document.getElementById("biotop").innerHTML.indexOf("Bio and Free Webcam")==-1){newelem.style.display="none"}//only in english
  1033. document.getElementById("chatcontrols").appendChild(newelem);
  1034.  
  1035. newelem=document.createElement('span');
  1036. newelem.setAttribute("style", slistyle);
  1037. newelem.style.margin="2px";
  1038. newelem.innerHTML="Grey user chat : <input type='range' id='c5' min=0 max=1 value=0 style='width: 40px;height:11px;cursor: pointer;float: right;'>";
  1039. document.getElementById("chatcontrols").appendChild(newelem);
  1040.  
  1041. newelem=document.createElement('span');
  1042. newelem.setAttribute("style", slistyle);
  1043. newelem.style.margin="2px";
  1044. newelem.innerHTML="Moderator chat : <input type='range' id='c6' min=0 max=1 value=0 style='width: 40px;height:11px;cursor: pointer;float: right;'>";
  1045. document.getElementById("chatcontrols").appendChild(newelem);
  1046.  
  1047. newelem=document.createElement('span');
  1048. newelem.setAttribute("style", slistyle);
  1049. newelem.style.margin="2px";
  1050. newelem.innerHTML="Tips smaller than : <input type='number' id='c7a' min='2' max='1000' value='100' style='width: 4em;height:11px;cursor: pointer; '> tokens.<input type='range' id='c7' min=0 max=1 value=0 style='width: 40px;height:11px;cursor: pointer;float: right;'>";
  1051. document.getElementById("chatcontrols").appendChild(newelem);
  1052.  
  1053. newelem=document.createElement('span');
  1054. newelem.setAttribute("style", slistyle);
  1055. newelem.style.margin="2px";
  1056. newelem.innerHTML="Lovense messages : <input type='range' id='c8' min=0 max=1 value=0 style='width: 40px;height:11px;cursor: pointer;float: right;'>";
  1057. document.getElementById("chatcontrols").appendChild(newelem);
  1058.  
  1059. newelem=document.createElement('span');
  1060. newelem.setAttribute("style", slistyle);
  1061. newelem.style.margin="2px";
  1062. newelem.innerHTML="Tokens recived : <span id='c9' style='width: 40px;height:11px;float: right; color:black'>0</span>";
  1063. document.getElementById("chatcontrols").appendChild(newelem);
  1064.  
  1065. }
  1066.  
  1067. //============= in html5 player they keep adding/removing the video node so i need a dynamic reference
  1068. function getvid(){
  1069. vareaid=document.getElementsByTagName("video")[0].id;
  1070. observer3.observe(document.getElementsByTagName("video")[0].parentNode, observerConfig3);
  1071. }
  1072.  
  1073. //======================== video control functions
  1074. function varea(){
  1075. var vnode=document.getElementById(vareaid);
  1076. vnode.style.filter=vfilter;
  1077. vnode.style.transform=vmirror;
  1078. if (document.querySelector('[data-testid="video-container"]')&&vnode.src){
  1079. document.querySelector('[data-testid="video-container"]').style.background="rgb(51, 51, 51)";
  1080. }
  1081. document.getElementById("vcontr").style.display="block";
  1082. if (!vnode.src){
  1083. document.getElementById("vcontr").style.display="none";
  1084. document.getElementById("controls").style.display="none";
  1085. }
  1086. return vnode;
  1087. }
  1088.  
  1089. // brightness adjust
  1090. function badjust(){
  1091. br=document.getElementById("myRange").value;
  1092. ofils=varea().style.filter.split(" ");
  1093. vfilter="brightness("+br+"%) "+ofils[1]+" "+ofils[2]+" "+ofils[3]+" "+ofils[4];
  1094. varea();
  1095. }
  1096.  
  1097. // contrast adjust
  1098. function cadjust(){
  1099. br=document.getElementById("myRange1").value;
  1100. ofils=varea().style.filter.split(" ");
  1101. vfilter=ofils[0]+" contrast("+br+"%) "+ofils[2]+" "+ofils[3]+" "+ofils[4];
  1102. varea();
  1103. }
  1104.  
  1105. // saturation adjust
  1106. function sadjust(){
  1107. br=document.getElementById("myRange2").value;
  1108. ofils=varea().style.filter.split(" ");
  1109. vfilter=ofils[0]+" "+ofils[1]+" "+ofils[2]+" saturate("+br+"%) "+ofils[4];
  1110. varea();
  1111. }
  1112.  
  1113. // hue adjust
  1114. function hadjust(){
  1115. br=document.getElementById("myRange3").value;
  1116. if (br > 359){br=br-360;}
  1117. ofils=varea().style.filter.split(" ");
  1118. vfilter=ofils[0]+" "+ofils[1]+" "+ofils[2]+" "+ofils[3]+" hue-rotate("+br+"deg)";
  1119. varea();
  1120. }
  1121.  
  1122. // invert video
  1123. function invert(){
  1124. ofils=varea().style.filter.split(" ");
  1125. br=" invert(100%) ";
  1126. if (ofils[2]=="invert(100%)"){br=" invert(0%) ";}
  1127. vfilter=ofils[0]+" "+ofils[1]+br+ofils[3]+" "+ofils[4];
  1128. varea();
  1129. }
  1130.  
  1131. // mirror video
  1132. function mirror(){
  1133. if (varea().style.transform=="none"){
  1134. vmirror="matrix(-1, 0, 0, 1, 0, 0)";
  1135. varea();
  1136.  
  1137. }else{
  1138. vmirror="none";
  1139. varea();
  1140. }
  1141. }
  1142.  
  1143. // reset all video adjustments
  1144. function vreset(){
  1145. vfilter="brightness(100%) contrast(100%) invert(0%) saturate(100%) hue-rotate(0deg)";
  1146. vmirror="none";
  1147. varea();
  1148. document.getElementById("myRange").value=100;
  1149. document.getElementById("myRange1").value=100;
  1150. document.getElementById("myRange2").value=100;
  1151. document.getElementById("myRange3").value=360;
  1152. }
  1153.  
  1154. // video controls on/off
  1155. function vcontrol(){
  1156. if (document.getElementById("controls").style.display=="block"){
  1157. document.getElementById("controls").style.display="none";
  1158. }else{
  1159. document.getElementById("controls").style.display="block";
  1160. }
  1161. }
  1162.  
  1163. // pull and drag functions
  1164. function dragMouseDown(e) {
  1165. e = e || window.event;
  1166. e.preventDefault();
  1167. pos3 = e.clientX;
  1168. pos4 = e.clientY;
  1169. document.onmouseup = closeDragElement;
  1170. document.onmousemove = elementDrag;
  1171. }
  1172.  
  1173. // when moved while clicked- part of dragMouseDown()
  1174. function elementDrag(e) {
  1175. e = e || window.event;
  1176. e.preventDefault();
  1177. pos1 = pos3 - e.clientX;
  1178. pos2 = pos4 - e.clientY;
  1179. pos3 = e.clientX;
  1180. pos4 = e.clientY;
  1181. var x =parseInt(document.getElementById("controls").style.right);
  1182. var y =parseInt(document.getElementById("controls").style.marginTop);
  1183. if ((pos3>=110)&&(pos3<=window.innerWidth-324)){
  1184. document.getElementById("controls").style.right = (x + pos1) + "px";
  1185. }
  1186. if ((y-pos2>-50)&&(pos4<=window.innerHeight-20)){
  1187. document.getElementById("controls").style.marginTop = (y - pos2) + "px";
  1188. }
  1189. }
  1190.  
  1191. // stop moving when mouse button is released- part of dragMouseDown()
  1192. function closeDragElement() {
  1193. document.onmouseup = null;
  1194. document.onmousemove = null;
  1195. }
  1196.  
  1197. // get basic info, hide video controls in an offline room and on bio only
  1198. function info(){
  1199. var url="https://chaturbate.com/api/chatvideocontext/"+roomname+"/";
  1200. fetching++;
  1201. fetch(url,{ credentials: "same-origin"}).then(
  1202. function(response) {
  1203. if (response.status !== 200){
  1204. fetching--;
  1205. return;
  1206. }
  1207. response.json().then(function(roomdata) {
  1208. data=roomdata;
  1209. fetching--;
  1210. setprofileinfo();
  1211. });
  1212. });
  1213. }
  1214.  
  1215. function setprofileinfo(){
  1216. room_status=data.room_status;
  1217. username=data.viewer_username;
  1218. var ppage=false;
  1219. if(currpage.split("/")[3]=="p"){
  1220. ppage=true;
  1221. }
  1222. if (noaccess){
  1223. ppage=true;
  1224. }
  1225. if (username!="AnonymousUser"){
  1226. loggedin=true;
  1227. }
  1228. if (room_status =="offline"){
  1229. document.getElementById("vcontr").style.display="none";
  1230. }
  1231. if(ppage){
  1232. document.getElementById("vcontr").style.display="none";
  1233. wprof("Find:","<a href='https://camgirlfinder.net/models?m="+roomname+"&p=cb&g=a' rel=noreferrer target='_new'>Open in camgirlfinder</a>");
  1234. }
  1235. wprof("Statistics:","<a href='https://statbate.com/search/1/"+roomname+"' rel=noreferrer target='_new'>Open in statbate</a>");
  1236. wprof("Schedule:","<a href='https://www.cbhours.com/user/"+roomname+".html' rel=noreferrer target='_new'>Open in cbhours</a>");
  1237. if (document.getElementById("vcontr").style.display=="none"){
  1238. if (!data.opt_out){
  1239. wprof("Full video (anon):","<a href='https://www.girls4cock.com/fullvideo/?b="+roomname+"' rel=noreferrer target='_new'>Open full video mode as anonymous</a>");
  1240. if (!noaccess){
  1241. wprof("Full video:","<a href='https://chaturbate.com/fullvideo/?b="+roomname+"' rel=noreferrer target='_new'>Open full video mode</a>");
  1242. }
  1243. }
  1244. }
  1245. if (data.opt_out){
  1246. wprof("On network sites:","No");
  1247. }
  1248.  
  1249. if(data.chat_rules!=""){
  1250. makerulesarea(data.chat_rules);
  1251. wprof ("Chat rules:","<a href=# id='rulesview'>Yes, click to read</a>");
  1252. document.getElementById("rulesview").addEventListener("click",function(){
  1253. if(document.getElementById("rulespop").style.display=="none"){
  1254. document.getElementById("rulespop").style.display="block";
  1255. }
  1256. else{
  1257. document.getElementById("rulespop").style.display="none";
  1258. }
  1259. });
  1260. }
  1261. if(ppage){
  1262. wprof("Users in room:",data.num_viewers);
  1263. }
  1264. if (data.low_satisfaction_score){
  1265. wprof("Satisfaction score:","<font color=#CC0000>LOW !!!</font>");
  1266. }
  1267.  
  1268. if (data.is_moderator){
  1269. wprof("Moderator:","Yes");
  1270. }
  1271. if (data.fan_club_is_member){
  1272. wprof("Fanclub member:","Yes");
  1273. }
  1274. if ((room_status=="offline")||(ppage)){
  1275. wprof("Room topic:","<div style='width:450px;height:auto'>"+data.room_title+"</div>");
  1276. }
  1277. if (ppage){
  1278. if (room_status.indexOf("hidden")!=-1){
  1279. wprof("Hidden message:",data.hidden_message);
  1280. }
  1281. }
  1282. if (room_status != "offline"){
  1283. hls_source=data.hls_source;
  1284. navigator.clipboard.writeText(hls_source);
  1285. var vidqual=data.quality.quality
  1286. if (!vidqual){vidqual= "unknown"};
  1287. wprof("Video quality:",vidqual);
  1288. }
  1289. wprof("Video:",room_status);
  1290. if (data.tips_in_past_24_hours !== 0){
  1291. wprof("You tipped:",data.tips_in_past_24_hours+" Tk/24h");
  1292. }
  1293. if (!data.is_age_verified){
  1294. wprof("Status:","Exhibitionist");
  1295. }else{
  1296. if (data.allow_private_shows){
  1297. if (data.spy_private_show_price !== 0){
  1298. wprof("Spy on private:",data.spy_private_show_price+" Tk/min");
  1299. }else{
  1300. wprof("Spy on private:","Disabled");
  1301. }
  1302. wprof("Minimum private:",data.private_min_minutes+" Minutes");
  1303. wprof("Private recording:",data.allow_show_recordings ? "Yes":"No");
  1304. wprof("Privateshow:",data.private_show_price+" Tk/min");
  1305. }else{
  1306. wprof("Privateshow:","Disabled");
  1307. }
  1308. }
  1309. if (login){
  1310. if (!noaccess){
  1311. wprof ("DM:","<a href='https://chaturbate.com/dm/"+roomname+"/' id='dmpop'>Open window</a>");
  1312. document.getElementById("dmpop").addEventListener("click", function(event){opendm(this);event.stopPropagation();event.preventDefault();return false});
  1313. }
  1314. getnotes();
  1315. }
  1316. if ((room_status!="offline")&&(!ppage)){chatchange()}
  1317. }
  1318.  
  1319. //============ chat control
  1320. function chatchange(){
  1321. document.getElementById("ccontr").style.display="block";
  1322. document.getElementById("c1").addEventListener("change",chatsetchange);
  1323. document.getElementById("c2").addEventListener("change",chatsetchange);
  1324. document.getElementById("c3").addEventListener("change",chatsetchange);
  1325. document.getElementById("c4").addEventListener("change",chatsetchange);
  1326. document.getElementById("c5").addEventListener("change",chatsetchange);
  1327. document.getElementById("c6").addEventListener("change",chatsetchange);
  1328. document.getElementById("c7").addEventListener("change",chatsetchange);
  1329. document.getElementById("c7a").addEventListener("change",chatsetchange);
  1330. document.getElementById("c8").addEventListener("change",chatsetchange);
  1331. var chatobserver = new MutationObserver(chatadjust);
  1332. var chatobserverConfig = {childList: true, subtree: true };
  1333. var observenode=document.getElementsByClassName("message-list")[0];
  1334. chatobserver.observe(observenode,chatobserverConfig);
  1335. }
  1336.  
  1337. function chatsetchange(){
  1338. c1=document.getElementById("c1").value;
  1339. c2=document.getElementById("c2").value;
  1340. c3=document.getElementById("c3").value;
  1341. c4=document.getElementById("c4").value;
  1342. c5=document.getElementById("c5").value;
  1343. c6=document.getElementById("c6").value;
  1344. c7=document.getElementById("c7").value;
  1345. c7a=document.getElementById("c7a").value;
  1346. if (c7a<2){c7a=2;document.getElementById("c7a").value=2};
  1347. if (c7a>1000){c7a=1000;document.getElementById("c7a").value=1000};
  1348. c8=document.getElementById("c8").value;
  1349. smallemoonoff();
  1350. chatadjust();// after change
  1351. }
  1352.  
  1353. function chatadjust(){
  1354. var tags=document.getElementsByClassName('msg-list-fvm');
  1355. for (n=0; n<tags.length; n++){
  1356. chattamper(n);
  1357. }
  1358. }
  1359.  
  1360. function chattamper(tag){
  1361. var messages=document.getElementsByClassName('msg-list-fvm')[tag].querySelectorAll('[data-testid="chat-message"]');
  1362. var chatmessages=messages.length;
  1363. if (chatmessages==0){return}
  1364. for (i=0; i<chatmessages; i++){
  1365. // div notices---------------------------------------------------------------
  1366. var noticeelm=messages[i].querySelector('[data-testid="room-notice"]');
  1367. if (noticeelm!=null){
  1368. var noticeclasses=noticeelm.classList;
  1369. var notetext=noticeelm.querySelector('[data-testid="room-notice-viewport"]').textContent;
  1370. if (noticeclasses.length==1){ // notice with no additional class
  1371. if (notetext.indexOf("Notice:")==0){ // normal notice
  1372. if (c2==1){
  1373. messages[i].style.display="none";
  1374. }else{
  1375. messages[i].style.display="block";
  1376. }
  1377. }
  1378. if (notetext.indexOf("Moderator")==0){ //left / entered the room
  1379. if (c4==1){
  1380. messages[i].style.display="none";
  1381. }else{
  1382. messages[i].style.display="block";
  1383. }
  1384. }
  1385. if (notetext.indexOf("Fan club member")==0){//left / entered the room
  1386. if (c4==1){
  1387. messages[i].style.display="none";
  1388. }else{
  1389. messages[i].style.display="block";
  1390. }
  1391. }
  1392. }
  1393.  
  1394. if (noticeclasses.contains("titleChange")){
  1395. if (c3==1){
  1396. messages[i].style.display="none";
  1397. }else{
  1398. messages[i].style.display="block";
  1399. }
  1400. }
  1401.  
  1402. if (noticeclasses.contains("isTip")){
  1403. var tokens=parseInt(notetext.split("tipped ")[1].split(" ")[0]);
  1404. if (tag==0){
  1405. if(messages[i].style.display=="flex"){
  1406. document.getElementById("c9").innerHTML=parseInt(document.getElementById("c9").innerHTML)+tokens;
  1407. }
  1408. }
  1409. if ((c7==1)&&(tokens<c7a)){
  1410. messages[i].style.display="none";
  1411. }else{
  1412. messages[i].style.display="block";
  1413. }
  1414. }
  1415.  
  1416. }//end roomnotice
  1417.  
  1418. //div chattext-----------------------------------------
  1419. if (messages[i].querySelector('[data-testid="chat-message-text"]')!=null){
  1420. //text in chattext-----------------------
  1421. if (messages[i].querySelector('[data-testid="chat-message-username"]').className=="broadcaster"){
  1422. var chattext=messages[i].querySelector('[data-testid="chat-message-text"]').textContent;
  1423. if ((chattext.indexOf("Lovense")!=-1)||(chattext.indexOf("------")!=-1)||(chattext.indexOf("******")!=-1)||(chattext.indexOf("The High Tipper")!=-1)||(chattext.indexOf("The king Tipper")!=-1)||(chattext.indexOf("Special Commands:")!=-1)||(chattext.indexOf("Blitz Mode")!=-1)){
  1424. if (c8==1){
  1425. messages[i].style.display="none";
  1426. }else{
  1427. messages[i].style.display="block";
  1428. }
  1429. }
  1430. }
  1431.  
  1432. //div users in chattext-------------------------------
  1433. if (messages[i].querySelector('[data-testid="chat-message-username"]').className=="defaultUser"){ // grey user
  1434. if (c5==1){
  1435. messages[i].style.display="none";
  1436. }else{
  1437. messages[i].style.display="block";
  1438. }
  1439. }
  1440. if (messages[i].querySelector('[data-testid="chat-message-username"]').className=="mod"){//mod user
  1441. if (c6==1){
  1442. messages[i].style.display="none";
  1443. }else{
  1444. messages[i].style.display="block";
  1445. }
  1446. }
  1447. }
  1448. }
  1449. }
  1450.  
  1451. //======== small emoticons
  1452. function smallemoonoff(){
  1453. if ((c1==1)&&(document.getElementById("emostyle")==null)){
  1454. var style = document.createElement('style');
  1455. style.setAttribute('type', 'text/css');
  1456. style.id="emostyle";
  1457. style.textContent = ".emoticonImage img {max-height:22px !important;}";
  1458. document.getElementsByTagName('head')[0].appendChild(style);
  1459. }
  1460. if ((c1==0)&&(document.getElementById("emostyle")!=null)){
  1461. document.getElementById("emostyle").remove();
  1462. }
  1463. }
  1464.  
  1465. function ccontrol(){
  1466. if (document.getElementById("chatcontrols").style.display=="block"){
  1467. document.getElementById("chatcontrols").style.display="none"
  1468. }else{
  1469. document.getElementById("chatcontrols").style.display="block"
  1470. }
  1471. }
  1472.  
  1473. //====== open dm from bio
  1474. function opendm(that){
  1475. var dmwindow= window.open(that.href,'DMpop','toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=yes,width=800,height=800')
  1476. dmwindow.onload = function(){
  1477. this.addEventListener('unload', function(){setTimeout(function(){newinfo();},1000);})
  1478. }
  1479. }
  1480.  
  1481. // get notes
  1482. function getnotes(){
  1483. var url="https://chaturbate.com/api/notes/for_user/"+roomname+"/";
  1484. fetching++;
  1485. fetch(url,{ credentials: "same-origin"}).then(
  1486. function(response) {
  1487. if (response.status !== 200) {
  1488. fetching--;
  1489. return;
  1490. }
  1491. response.json().then(function(data) {
  1492. fetching--;
  1493. if (data.text == null){data.text=""}
  1494. opennote=data.text;
  1495. buildprofnote();
  1496. createimage();
  1497. });
  1498. });
  1499. }
  1500.  
  1501. // pop up the rules
  1502. function makerulesarea(rule){
  1503. if (document.getElementById("rulespop")){return}
  1504. var rulestyle="cursor:pointer;z-index:999;top:10px;left:10px;box-shadow:0px 0px 32px rgba(0, 0, 0, 0.32);border-radius:4px;border:1px solid rgb(221, 221, 221);background-color:rgb(200, 200, 200);position:absolute; display:none; white-space: pre-line; text-align: left; line-height: 1.4; height: auto; width:500px; padding: 10px 10px 10px 10px; box-sizing: border-box; overflow-wrap: break-word; word-break: break-word; padding: 15px;"
  1505. var newelem=document.createElement('span');
  1506. newelem.setAttribute("style", rulestyle);
  1507. newelem.id="rulespop";
  1508. newelem.innerHTML="<b>"+roomname+" chatrules:</b><br><br>"+rule+"<br><br><center>(Click to close)</center>";
  1509. newelem.addEventListener("click",function(){this.style.display="none"});
  1510. document.querySelector('[data-testid="room-bio-tab-contents"]').appendChild(newelem);
  1511. }
  1512.  
  1513. //puts in /p/ page jpegplayer , or last image or noting
  1514. function createimage(){
  1515. if ((document.location.href.split("/")[3]!="p")&&!noaccess){return;}
  1516. if ((document.getElementById("profimg"))&&(room_status!="public")){return;}
  1517. if (document.getElementById("profimg")){document.getElementById("profimg").remove();}
  1518. if (room_status=="public"){makeplayer();return}
  1519. //now check if there is an active thumbnail
  1520. var url="https://jpeg.live.mmcdn.com/minifwap/"+roomname+".jpg";
  1521. fetch(url,{
  1522. cache: "no-cache",
  1523. credentials: "same-origin"}).then(
  1524. function(response){
  1525. var imgsize=response.headers.get("content-length");
  1526. if ((imgsize<4800)||(imgsize>4850)){makeimg();}
  1527. }
  1528. );
  1529. }
  1530.  
  1531. function makeimg(){
  1532. var newelem=document.createElement('img');
  1533. newelem.src="https://jpeg.live.mmcdn.com/minifwap/"+roomname+".jpg";
  1534. newelem.id="profimg";
  1535. newelem.style.zIndex="999";
  1536. newelem.style.position="absolute";
  1537. newelem.style.height="270px";
  1538. newelem.style.width="480px";
  1539. newelem.style.top="10px";
  1540. newelem.style.right="10px";
  1541. newelem.style.border="1px solid rgb(221, 221, 221)";
  1542. newelem.style.borderRadius="4px";
  1543. newelem.style.boxShadow="0px 0px 32px rgba(0, 0, 0, 0.32)";
  1544. document.querySelector('[data-testid="room-bio-tab-contents"]').appendChild(newelem);
  1545. }
  1546.  
  1547. function makeplayer(){
  1548. var newelem=document.createElement('img');
  1549. newelem.src="https://jpeg.live.mmcdn.com/minifwap/"+roomname+".jpg";
  1550. newelem.id="profimg";
  1551. newelem.style.zIndex="999";
  1552. newelem.style.position="absolute";
  1553. newelem.style.width="854px";
  1554. newelem.style.height="480px";
  1555. newelem.style.top="10px";
  1556. newelem.style.right="10px";
  1557. newelem.style.border="1px solid rgb(221, 221, 221)";
  1558. newelem.style.borderRadius="4px";
  1559. newelem.style.boxShadow="0px 0px 32px rgba(0, 0, 0, 0.32)";
  1560. document.querySelector('[data-testid="room-bio-tab-contents"]').appendChild(newelem);
  1561. pimg.addEventListener("load",regetimgprof);
  1562. pimg.addEventListener("error",errorimgprof);
  1563. pimg.src = "https://jpeg.live.mmcdn.com/stream?room="+roomname+"&f="+ new Date().getTime();
  1564. }
  1565.  
  1566. function errorimgprof(){
  1567. setTimeout(function(){pimg.src = "https://jpeg.live.mmcdn.com/stream?room="+roomname+"&f="+ new Date().getTime();}, 5000);
  1568. }
  1569.  
  1570. function regetimgprof(){
  1571. if ((document.visibilityState!="visible")||(document.querySelector('[data-testid="room-bio-tab-contents"]').style.height=="0px")){
  1572. setTimeout(regetimgprof,2000);
  1573. }else{
  1574. document.getElementById("profimg").src=pimg.src;
  1575. setTimeout(function(){pimg.src = "https://jpeg.live.mmcdn.com/stream?room="+roomname+"&f="+ new Date().getTime();}, 50);
  1576. }
  1577. }
  1578.  
  1579. //----------note in profile
  1580. function buildprofnote(){
  1581. var subbutraw="<span id='profsubmit' style='color: rgb(255, 255, 255); background: rgba(0, 0, 0, 0) linear-gradient(rgb(255, 151, 53) 0%, rgb(255, 158, 54) 50%, rgb(255, 112, 2) 60%) repeat scroll 0% 0%; font-family: UbuntuMedium, Helvetica, Arial, sans-serif; font-size: 12px; padding: 4px 10px 5px; position: relative; left: 120px; float: left; border-radius: 4px; cursor: pointer;'>Save</span>";
  1582. wprof("",'<div width="200px" id="profnote" style="display:none"><a href=# id="profcancel">Cancel</a>'+subbutraw+'</div>');
  1583. wprof("Personal notes:","<textarea id='proftext' spellcheck='false' placeholder='Enter notes about this user (only seen by you)' style='width: 200px; height: 45px; line-height: 14px; border-width: 1px; border-style: solid; border-color: rgb(172, 172, 172); border-radius: 4px; padding: 7px 8px; overflow: auto;background-color: rgb(221, 233, 245);'></textarea>");
  1584. document.getElementById("proftext").value=opennote;
  1585. document.getElementById("proftext").addEventListener("input",profopenbutton);
  1586. document.getElementById("profcancel").addEventListener("click",profclosebutton);
  1587. document.getElementById("profsubmit").addEventListener("click",profsavenote);
  1588. }
  1589.  
  1590. function profsavenote(){
  1591. var notetext=document.getElementById("proftext").value;
  1592. var url="https://chaturbate.com/api/notes/for_user/"+roomname+"/";
  1593. var csrftoken= readCookie("csrftoken");
  1594. var data = new FormData();
  1595. data.append( "text", notetext );
  1596. fetch(url,
  1597. {
  1598. method: "POST",
  1599. headers: {
  1600. 'x-csrftoken': csrftoken,
  1601. 'x-requested-with': 'XMLHttpRequest'
  1602. },
  1603. body: data
  1604. }).then(profaftersave)
  1605. }
  1606.  
  1607. function profaftersave(){
  1608. opennote=document.getElementById("proftext").value;
  1609. profclosebutton();
  1610. }
  1611.  
  1612. function profopenbutton(){
  1613. document.getElementById("profnote").style.display="block";
  1614. document.getElementById("proftext").value=document.getElementById("proftext").value.replace("$"," "+new Date().toLocaleDateString()+" ");
  1615. if(opennote==document.getElementById("proftext").value){
  1616. profclosebutton();
  1617. }
  1618. }
  1619.  
  1620. function profclosebutton(){
  1621. document.getElementById("profnote").style.display="none";
  1622. document.getElementById("proftext").value=opennote;
  1623. }
  1624.  
  1625.  
  1626. //------bio writer
  1627. function wprof(col1,col2){
  1628. var container=document.getElementsByClassName("BioContents")[0];
  1629. var newtr=document.createElement('tr');
  1630. newtr.setAttribute("style", "font-size: 14px; font-weight: normal; line-height: 15px; vertical-align: top; text-align: left;");
  1631. newtr.setAttribute("name", "info");
  1632. var newtd=document.createElement('td');
  1633. newtd.setAttribute("style", "padding-bottom: 9px; font-family: UbuntuMedium, Arial, Helvetica, sans-serif; height: 16px;");
  1634. newtd.className="label";
  1635. var newspan=document.createElement('span');
  1636. newspan.className="defaultColor";
  1637. newspan.innerHTML=col1;
  1638. newtd.appendChild(newspan);
  1639. var newtd2=document.createElement('td');
  1640. newtd2.setAttribute("style", "font-size: 14px; line-height: 16px; font-family: UbuntuRegular, Arial, Helvetica, sans-serif;");
  1641. newtd2.className="contentText";
  1642. newtd2.innerHTML=col2;
  1643. newtr.appendChild(newtd);
  1644. newtr.appendChild(newtd2);
  1645. var referenceNode=container.getElementsByTagName("table")[0];
  1646. referenceNode.insertBefore(newtr, referenceNode.getElementsByTagName("tr")[2]);
  1647. }
  1648.  
  1649. // removes the extra info in the profile and gets it again
  1650. function newinfo(){
  1651. if (fetching!==0){alert("Slow down !");return;}
  1652. var tags=document.getElementsByName("info");
  1653. for(i=tags.length-1;i>=0;i--){
  1654. tags[i].remove();
  1655. }
  1656. if (noaccess){
  1657. anoninfo();
  1658. }else{
  1659. info();
  1660. }
  1661. }
  1662.  
  1663.  
  1664. //=================== clean profile setup
  1665. function cleaninit(){
  1666. var p=0;
  1667. var maxoke="";
  1668. var tags=document.querySelectorAll('[rel="nofollow"]');
  1669. for (n=0; n<tags.length; n++){
  1670. if (tags[n].style.position){
  1671. if ((tags[n].style.position.indexOf("absolute")!=-1)||(tags[n].style.position.indexOf("fixed")!=-1)){
  1672. tags[n].classList.add("profpos");
  1673. p++;
  1674. }
  1675. }
  1676. // vh em of px 30em , 30 vh , 200px
  1677. if (tags[n].style.marginTop){
  1678. maxoke=-30;
  1679. if(tags[n].style.marginTop.indexOf("px")!=-1){maxoke=-200}
  1680. if (parseFloat(tags[n].style.marginTop)<maxoke){
  1681. tags[n].classList.add("profmar");
  1682. p++;
  1683. }
  1684. }
  1685. if (tags[n].style.margin){
  1686. maxoke=-30;
  1687. if(tags[n].style.margin.split(" ")[0].indexOf("px")!=-1){maxoke=-200}
  1688. if (parseFloat(tags[n].style.margin)<maxoke){
  1689. tags[n].classList.add("profmar");
  1690. p++;
  1691. }
  1692. }
  1693. if (tags[n].style.cursor){
  1694. tags[n].classList.add("profcur");
  1695. p++;
  1696. }
  1697. }
  1698. document.getElementById("clean").style.display="none";
  1699. if (p!==0){
  1700. document.getElementById("clean").style.display="block";
  1701. cleanup();
  1702. }
  1703. }
  1704.  
  1705. //=========== swap profile cleanup cookie and call cleanup()
  1706. function cleancookie(){
  1707. if (readCookie("pclean")){
  1708. eraseCookie("pclean");
  1709. }else{
  1710. createCookie("pclean",1,30);
  1711. }
  1712. cleanup();
  1713. }
  1714.  
  1715. // hide or unhide marked elements in profile according to cookie with css
  1716. function cleanup(){
  1717. var claction=!readCookie("pclean");
  1718. if (claction){
  1719. document.getElementById("clean").innerHTML= "CLEAN PROFILE = ON&nbsp;";
  1720. var style = document.createElement('style');
  1721. style.setAttribute('type', 'text/css');
  1722. style.id="profstyle";
  1723. style.textContent = ".profpos {display:none !important} .profmar {margin-top:0px !important;} .profcur{cursor:default !important }";
  1724. document.getElementsByTagName('head')[0].appendChild(style);
  1725. }else{
  1726. document.getElementById("clean").innerHTML= "CLEAN PROFILE = OFF";
  1727. if (document.getElementById("profstyle")!=null){
  1728. document.getElementById("profstyle").remove();
  1729. }
  1730. }
  1731. }
  1732.  
  1733. //=============== links in bio fix
  1734. function linkfix(){
  1735. var bioarea= document.getElementsByClassName('BioContents')[0];
  1736. var tags = bioarea.getElementsByTagName('a');
  1737. for (i=0; i<tags.length; i++){
  1738. if (tags[i].href.indexOf("campaign=")!=-1){
  1739. tags[i].href=tour;
  1740. }
  1741. if (tags[i].href.indexOf('?url=') != -1){
  1742. var linkout=decodeURIComponent(tags[i].href).split("?url=")[1];
  1743. if (linkout.indexOf("campaign=")!=-1){
  1744. linkout=tour;
  1745. }
  1746. tags[i].href=linkout;
  1747. }
  1748. }
  1749. if(document.querySelector('[data-testid="sign-up-tab"]')){
  1750. document.querySelector('[data-testid="sign-up-tab"]').href=tour;
  1751. }
  1752. }
  1753.  
  1754. //===downloadlink my collection and model media in popup
  1755. function collectiondownload(){
  1756. document.getElementById("main").addEventListener("click", collectiondownload2);
  1757. collectiondownload2();
  1758. }
  1759.  
  1760. function collectiondownload2(){
  1761. setTimeout(function(){collectiondownload3()}, 2000);
  1762. }
  1763.  
  1764. function collectiondownload3(){
  1765. if(document.getElementsByTagName("video").length>0){
  1766. if(document.getElementsByTagName("video")[0].src){
  1767. if(!document.getElementById("link")){
  1768. var newelem=document.createElement('a');
  1769. newelem.id="link";
  1770. newelem.href= document.getElementsByTagName("video")[0].src;
  1771. newelem.target="_blank";
  1772. newelem.innerHTML="Right click, save to disk.<br>";
  1773. newelem.style.backgroundColor="white";
  1774. newelem.style.marginLeft="20px";
  1775. document.getElementsByClassName("createdAt")[0].parentNode.appendChild(newelem);
  1776. }
  1777. }
  1778. }
  1779. }
  1780.  
  1781. //======= downloadlink saved private
  1782. function savedprvdownload(){
  1783. setTimeout(function(){savedprvdownload3();}, 2000);
  1784. }
  1785.  
  1786. function savedprvdownload3(){
  1787. var newelem=document.createElement('a');
  1788. newelem.href= document.getElementsByTagName("video")[0].src;
  1789. newelem.target="_blank";
  1790. newelem.innerHTML="Right click, save to disk.<br>";
  1791. newelem.style.backgroundColor="white";
  1792. newelem.style.marginLeft="20px";
  1793. document.getElementById("tsRecordedShowPlayer").appendChild(newelem);
  1794. }
  1795.  
  1796. //==============================password room
  1797. function passwordfollow(){
  1798. setTimeout(function(){
  1799. var unfollow=document.querySelector('[data-testid="unfollow-button"]');
  1800. var follow=document.querySelector('[data-testid="follow-button"]');
  1801. if (unfollow.style.display=="none"){
  1802. follow.parentNode.parentNode.style.display="block";
  1803. follow.style.display="block";
  1804. }
  1805. unfollow.addEventListener("click", function(){setTimeout(function(){document.location.reload();}, 500);} );
  1806. follow.addEventListener("click", function(){setTimeout(function(){document.location.reload();}, 500);} );
  1807. }, 1000);
  1808.  
  1809. var newelem=document.createElement('div');
  1810. newelem.className="BioContents";
  1811. var newtable=document.createElement('table');
  1812. newelem.appendChild(newtable);
  1813. var newtr=document.createElement('tr');
  1814. newtable.appendChild(newtr);
  1815. newtr=document.createElement('tr');
  1816. newelem.style.position="relative"
  1817. newelem.style.float="left";
  1818. newtable.appendChild(newtr);
  1819. document.getElementsByClassName("defaultColor")[0].appendChild(newelem);
  1820. wprof ("DM:","<a href='https://chaturbate.com/dm/"+roomname+"/' id='dmpop'>Open window</a>");
  1821. document.getElementById("dmpop").addEventListener("click", function(event){opendm3(this);event.stopPropagation();event.preventDefault();return false});
  1822. getnotes();
  1823. document.getElementsByClassName("tooltip")[0].innerHTML="If follow does not work this room banned your region or gender.";
  1824. document.getElementById("tsContent").style.minHeight="400px";
  1825. }
  1826.  
  1827. function opendm3(that){
  1828. var dmwindow= window.open(that.href,'DMpop','toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=yes,width=800,height=800');
  1829. }
  1830.  
  1831. //banned room
  1832. function bannedroom(){
  1833. document.getElementsByClassName("BaseRoomContents")[0].style.minHeight="505px";
  1834. var newelem=document.createElement('div');
  1835. newelem.style.width="100%";
  1836. newelem.style.height="1px";
  1837. newelem.setAttribute('data-testid', 'room-bio-tab-contents');
  1838. document.getElementsByClassName("BaseRoomContents")[0].appendChild(newelem);
  1839. newelem=document.createElement('div');
  1840. newelem.style.fontSize="15px";
  1841. newelem.style.fontWeight="bold";
  1842. newelem.style.color="red";
  1843. newelem.style.margin="14px 14px";
  1844. newelem.id="banreload";
  1845. newelem.innerHTML="Reload info.";
  1846. newelem.style.cursor="pointer";
  1847. newelem.addEventListener("click", newinfo);
  1848. document.getElementsByClassName("BaseRoomContents")[0].appendChild(newelem);
  1849. newelem=document.createElement('div');
  1850. newelem.className="BioContents";
  1851. var newtable=document.createElement('table');
  1852. newelem.appendChild(newtable);
  1853. var newtr=document.createElement('tr');
  1854. newtr.id="vcontr";
  1855. newtable.appendChild(newtr);
  1856. newtr=document.createElement('tr');
  1857. newtable.appendChild(newtr);
  1858. document.getElementsByClassName("BaseRoomContents")[0].appendChild(newelem);
  1859. anoninfo();
  1860. }
  1861.  
  1862. function anoninfo(){
  1863. var url="https://chaturbate.com/api/chatvideocontext/"+roomname+"/";
  1864. fetching++;
  1865. fetch(url,{ credentials: "omit"}).then(
  1866. function(response) {
  1867. if (response.status !== 200){ // region or gender block
  1868. fetching--;
  1869. document.getElementById("banreload").style.display="none";
  1870. i=0;
  1871. banimgsize();
  1872. return;
  1873. }
  1874. response.json().then(function(roomdata) {
  1875. data=roomdata;
  1876. fetching--;
  1877. setprofileinfo();
  1878. });
  1879. });
  1880. }
  1881.  
  1882. function banimgsize(){
  1883. var url="https://jpeg.live.mmcdn.com/minifwap/"+roomname+".jpg";
  1884. fetch(url,{
  1885. cache: "no-cache",
  1886. credentials: "omit",
  1887. referrerPolicy: "no-referrer"}).then(
  1888. function(response){
  1889. var imgsize=response.headers.get("content-length");
  1890. if (i==0){
  1891. i=imgsize;
  1892. setTimeout(banimgsize, 1000);
  1893. return;
  1894. }
  1895. if (i!=imgsize){banonline();return}
  1896. if ((imgsize>4800)&&(imgsize<4850)){banoffline();return}
  1897. banwasonline();
  1898. }
  1899. );
  1900. }
  1901.  
  1902. function banonline(){
  1903. wprof("","<a href=# id=moreinfo>Click here to search for more info.</a>");
  1904. document.getElementById("moreinfo").addEventListener("click",moreinfo);
  1905. putinlinks();
  1906. wprof("Status:","Online");
  1907. makeplayer();
  1908. if(login){
  1909. getnotes();
  1910. }
  1911. }
  1912.  
  1913. function banwasonline(){
  1914. putinlinks();
  1915. wprof("Status:","Recently online.");
  1916. if(login){
  1917. getnotes();
  1918. }else{
  1919. makeimg();
  1920. }
  1921. }
  1922.  
  1923. function banoffline(){
  1924. putinlinks();
  1925. wprof("Status:","Offline.");
  1926. if(login){
  1927. getnotes();
  1928. }
  1929. }
  1930.  
  1931. function putinlinks(){
  1932. wprof("Find:","<a href='https://camgirlfinder.net/models?m="+roomname+"&p=cb&g=a' rel=noreferrer target='_new'>Open in camgirlfinder</a>");
  1933. wprof("Statistics:","<a href='https://statbate.com/search/1/"+roomname+"' rel=noreferrer target='_new'>Open in statbate</a>");
  1934. wprof("Schedule:","<a href='https://www.cbhours.com/user/"+roomname+".html' rel=noreferrer target='_new'>Open in cbhours</a>");
  1935. }
  1936.  
  1937. function moreinfo(){
  1938. document.getElementById("moreinfo").removeEventListener("click",moreinfo);
  1939. document.getElementById("moreinfo").innerHTML="Please wait....";
  1940. var dataurl="https://chaturbate.com/affiliates/api/onlinerooms/?format=json&wm=b0P2s";
  1941. fetch(dataurl,{credentials: "omit",referrerPolicy: "no-referrer"}).then(
  1942. function(response) {
  1943. if (response.status !== 200){
  1944. document.getElementById("moreinfo").innerHTML="Error reading roomlist.";
  1945. return;
  1946. }
  1947. response.json().then(function(data) {
  1948. for (n=0; n<data.length; n++){
  1949. if (data[n].username==roomname){
  1950. wprof("Gender:",data[n].gender)
  1951. wprof("Given location:",data[n].location);
  1952. wprof("Country flag:",data[n].country);
  1953. wprof("Room topic:","<div style='width:450px;height:auto'>"+data[n].room_subject+"</div>");
  1954. wprof("Spoken languages:",data[n].spoken_languages);
  1955. wprof("Name:", data[n].display_name);
  1956. wprof("Birthday:",data[n].birthday);
  1957. wprof("Age:",data[n].age);
  1958. wprof("Time online:",toTime(data[n].seconds_online));
  1959. wprof("Users in room:",data[n].num_users);
  1960. wprof("Followers:",data[n].num_followers);
  1961. document.getElementById("moreinfo").innerHTML="";
  1962. data="";
  1963. break;
  1964. }
  1965. }
  1966. if (n==data.length){
  1967. document.getElementById("moreinfo").innerHTML="No information found, user may no longer be in public or opt-out.";
  1968. data="";
  1969. }
  1970. });
  1971. })
  1972.  
  1973. }
  1974. function toTime(seconds) {
  1975. var date = new Date(null);
  1976. date.setSeconds(seconds);
  1977. return date.toISOString().substr(11, 8).replace(":","h").replace(":","m")+"s";
  1978. }
  1979.  
  1980. //=============== cookie functions
  1981. function createCookie(name,value,days,domain){
  1982. var expires="";
  1983. if (domain){
  1984. domain=";domain=."+domain;
  1985. }else{
  1986. domain = "";
  1987. }
  1988. if (days) {
  1989. var date = new Date();
  1990. date.setTime(date.getTime()+(days*24*60*60*1000));
  1991. expires = "; expires="+date.toGMTString();
  1992. }
  1993. document.cookie = name+"="+value+expires+"; path=/"+domain;
  1994. }
  1995.  
  1996. function readCookie(name) {
  1997. var nameEQ = name + "=";
  1998. var ca = document.cookie.split(';');
  1999. for(i=0;i < ca.length;i++) {
  2000. var c = ca[i];
  2001. while (c.charAt(0)==' '){
  2002. c = c.substring(1,c.length);
  2003. }
  2004. if (c.indexOf(nameEQ) === 0){
  2005. return c.substring(nameEQ.length,c.length);
  2006. }
  2007. }
  2008. return null;
  2009. }
  2010.  
  2011. function eraseCookie(name,domain){
  2012. createCookie(name,"",-1,domain);
  2013. }
  2014.  
  2015. })();