ALcript

Change stuff on Anilist.co

  1. // ==UserScript==
  2. // @name ALcript
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.67
  5. // @description Change stuff on Anilist.co
  6. // @author hoh
  7. // @match https://anilist.co/*
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. (function(){
  12. scriptVersion = "1.67";
  13. /*
  14. Aniscripts, sometimes just "the userscript", is modular and contains of several independet functions
  15. The URL matching controller can be found near the bottom of this file.
  16.  
  17. Due to the dynamic nature of how Anilist pages load, these functions are run on a clock.
  18. Functionallity provided by all of these functions are suplemental, so the clock frequenzies are kept slow to not impact performance.
  19. */
  20.  
  21.  
  22. //a shared style node for all the modules. All classes are prefixed by "hoh" to avoid collisions with native Anilist classes
  23. var style = document.createElement('style');
  24. style.type = 'text/css';
  25.  
  26.  
  27. //most of these are used by the notification module
  28. //The default colour is rgb(var(--color-blue)) provided by Anilist, but rgb(var(--color-green)) is preferred for things related to manga
  29. style.innerHTML = `
  30. .hohTime{
  31. position : static;
  32. float : right;
  33. margin-right : 20px;
  34. margin-top : 10px;
  35. margin-left: auto;
  36. }
  37. .hohUnread{
  38. border-right : 8px;
  39. border-color: rgba(var(--color-blue));
  40. border-right-style : solid;
  41. }
  42. .hohNotification{
  43. margin-bottom : 10px;
  44. background : rgb(var(--color-foreground));
  45. border-radius : 4px;
  46. justify-content: space-between;
  47. line-height: 0;
  48. min-height: 72px;
  49. }
  50. .hohNotification *{
  51. line-height: 1.15;
  52. }
  53. .hohUserImageSmall{
  54. display : inline-block;
  55. background-position : 50%;
  56. background-repeat : no-repeat;
  57. background-size : cover;
  58. position : absolute;
  59. }
  60. .hohUserImage{
  61. height : 72px;
  62. width : 72px;
  63. display : inline-block;
  64. background-position : 50%;
  65. background-repeat : no-repeat;
  66. background-size : cover;
  67. position:absolute;
  68. }
  69. .hohMediaImage{
  70. height : 70px;
  71. margin-right : 5px;
  72. }
  73. .hohMessageText{
  74. position : absolute;
  75. margin-top : 30px;
  76. margin-left : 80px;
  77. max-width : 330px;
  78. }
  79. .hohMediaImageContainer{
  80. vertical-align : bottom;
  81. margin-left : 400px;
  82. display : inline;
  83. position: relative;
  84. display: inline-block;
  85. min-height: 70px;
  86. }
  87. .hohMediaImageContainer > a{
  88. height: 70px;
  89. line-height: 0!important;
  90. }
  91. span.hohMediaImageContainer{
  92. line-height: 0!important;
  93. }
  94. .hohCommentsContainer{
  95. margin-top: 5px;
  96. }
  97. .hohCommentsArea{
  98. margin : 10px;
  99. display : none;
  100. padding-bottom : 2px;
  101. margin-top: 5px;
  102. width: 95%;
  103. }
  104. .hohComments{
  105. float : right;
  106. display : none;
  107. margin-top: -30px;
  108. margin-right: 15px;
  109. cursor : pointer;
  110. margin-left: 600px;
  111. -webkit-touch-callout: none;
  112. -webkit-user-select: none;
  113. -khtml-user-select: none;
  114. -moz-user-select: none;
  115. -ms-user-select: none;
  116. user-select: none;
  117. }
  118. .hohCombined .hohComments{
  119. display : none!important;
  120. }
  121. .hohQuickCom{
  122. padding : 5px;
  123. background-color : rgb(var(--color-background));
  124. margin-bottom : 5px;
  125. position: relative;
  126. }
  127. .hohQuickComName{
  128. margin-right : 15px;
  129. color : rgb(var(--color-blue));
  130. }
  131. .hohQuickComName::after{
  132. content : ":";
  133. }
  134. .hohQuickComContent{
  135. margin-right: 40px;
  136. display: block;
  137. }
  138. .hohQuickComContent > p{
  139. margin: 1px;
  140. }
  141. .hohQuickComLikes{
  142. position: absolute;
  143. right: 5px;
  144. bottom: 5px;
  145. display: inline-block;
  146. }
  147. .hohSpoiler::before{
  148. color : rgb(var(--color-blue));
  149. cursor : pointer;
  150. background : rgb(var(--color-background));
  151. border-radius : 3px;
  152. content : "Spoiler, click to view";
  153. font-size : 1.3rem;
  154. padding : 0 5px;
  155. }
  156. .hohSpoiler.hohClicked::before{
  157. display : none;
  158. }
  159. .hohSpoiler > span{
  160. display : none;
  161. }
  162. .hohMessageText > span > div.time{
  163. display : none;
  164. }
  165. .hohUnhandledSpecial > div{
  166. margin-top : -20px;
  167. }
  168. .hohMonospace{
  169. font-family: monospace;
  170. }
  171. .hohSocialTabActivityCompressedContainer{
  172. min-width:480px;
  173. }
  174. .hohSocialTabActivityCompressedStatus{
  175. vertical-align: middle;
  176. padding-bottom: 7px;
  177. }
  178. .hohSocialTabActivityCompressedName{
  179. vertical-align: middle;
  180. margin-left: 3px;
  181. }
  182. .hohForumHider{
  183. margin-right: 3px;
  184. cursor: pointer;
  185. font-family: monospace;
  186. }
  187. .hohForumHider:hover{
  188. color: rgb(var(--color-blue));
  189. }
  190. .hohBackgroundCover{
  191. height: 70px;
  192. width: 50px;
  193. display: inline-block;
  194. background-repeat: no-repeat;
  195. background-size: cover;
  196. margin-top: 1px;
  197. line-height: 0;
  198. margin-bottom: 1px;
  199. }
  200. #hohDescription{
  201. width: 280px;
  202. height: 150px;
  203. float: left;
  204. color: rgb(var(--color-blue));
  205. }
  206. .hohStatsTrigger{
  207. cursor: pointer;
  208. border-radius: 3px;
  209. color: rgb(var(--color-text-lighter));
  210. display: block;
  211. font-size: 1.4rem;
  212. margin-bottom: 8px;
  213. padding: 5px 10px;
  214. }
  215. .hohActive{
  216. background: rgba(var(--color-foreground),.8);
  217. color: rgb(var(--color-text));
  218. font-weight: 500;
  219. }
  220. #hohFavCount{
  221. position: absolute;
  222. right: 30px;
  223. color: rgba(var(--color-red));
  224. top: 10px;
  225. font-weight: 400;
  226. }
  227. .hohShamelessLink{
  228. display: block;
  229. margin-bottom: 5px;
  230. }
  231. .hohSlidePlayer{
  232. display: block;
  233. position: relative;
  234. width: 500px;
  235. }
  236. .hohSlide{
  237. position: absolute;
  238. top: 0px;
  239. font-size: 500%;
  240. height: 100%;
  241. display: flex;
  242. align-items: center;
  243. -webkit-touch-callout: none;
  244. -webkit-user-select: none;
  245. -khtml-user-select: none;
  246. -moz-user-select: none;
  247. -ms-user-select: none;
  248. user-select: none;
  249. opacity:0.5;
  250. }
  251. .hohSlide:hover{
  252. background-color: rgb(0,0,0,0.4);
  253. cursor: pointer;
  254. opacity:1;
  255. }
  256. .hohRightSlide{
  257. right: 0px;
  258. padding-left: 10px;
  259. padding-right: 20px;
  260. }
  261. .hohLeftSlide{
  262. left: 0px;
  263. padding-left: 20px;
  264. padding-right: 10px;
  265. }
  266. .hohShare{
  267. position: absolute;
  268. right: 12px;
  269. top: 30px;
  270. cursor: pointer;
  271. color: rgb(var(--color-blue-dim));
  272. }
  273. .activity-entry{
  274. position: relative;
  275. }
  276. .hohEmbed{
  277. border-style: solid;
  278. border-color: rgb(var(--color-text));
  279. border-width: 1px;
  280. padding: 15px;
  281. position: relative;
  282. }
  283. .hohEmbed .avatar{
  284. border-radius: 3px;
  285. height: 40px;
  286. width: 40px;
  287. background-position: 50%;
  288. background-repeat: no-repeat;
  289. background-size: cover;
  290. display: inline-block;
  291. }
  292. .hohEmbed .name{
  293. display: inline-block;
  294. height: 40px;
  295. line-height: 40px;
  296. vertical-align: top;
  297. color: rgb(var(--color-blue));
  298. font-size: 1.4rem;
  299. margin-left: 12px !important;
  300. }
  301. .hohEmbed .time{
  302. color: rgb(var(--color-text-lighter));
  303. font-size: 1.1rem;
  304. position: absolute;
  305. right: 12px;
  306. top: 12px;
  307. }
  308. .hohRecsLabel{
  309. color: rgb(var(--color-blue)) !important;
  310. }
  311. .hohRecsItem{
  312. margin-top: 5px;
  313. margin-bottom: 10px;
  314. }
  315. .hohTaglessLinkException{
  316. display: block;
  317. }
  318. .hohTaglessLinkException::after{
  319. content: ""!important;
  320. }
  321. .hohStatValue{
  322. color: rgb(var(--color-blue));
  323. }
  324. .markdown-editor > [title="Image"],
  325. .markdown-editor > [title="Youtube Video"],
  326. .markdown-editor > [title="WebM Video"]{
  327. color: rgba(var(--color-red));
  328. }
  329. .hohBackgroundUserCover{
  330. height: 70px;
  331. width: 70px;
  332. display: inline-block;
  333. background-position: 50%;
  334. background-repeat: no-repeat;
  335. background-size: cover;
  336. margin-top: 1px;
  337. margin-bottom: 1px;
  338. };
  339. `;
  340.  
  341. document.getElementsByTagName('head')[0].appendChild(style);
  342.  
  343. //Todo: find out how to parse API headers for an accurate result
  344. document.APIcallsUsed = 0;//this is NOT a reliable way to figure out how many more calls we can use, just a way to set some limit
  345. var pending = {};
  346. var APIcounter = setTimeout(function(){
  347. document.APIcallsUsed = 0;
  348. },60*1000);//reset counter every minute
  349.  
  350. function lsTest(){//localStorage is great for not having to fetch the api data every time
  351. var test = "test";
  352. try{
  353. localStorage.setItem(test,test);
  354. localStorage.removeItem(test);
  355. return true;
  356. }
  357. catch(e){
  358. return false;
  359. }
  360. };
  361.  
  362. if(lsTest() === true){
  363. var localStorageAvailable = true;
  364. var aniscriptsUsed = localStorage.getItem("aniscriptsUsed");
  365. if(aniscriptsUsed === null){
  366. aniscriptsUsed = {
  367. keys : []
  368. };
  369. }
  370. else{
  371. aniscriptsUsed = JSON.parse(aniscriptsUsed);
  372. };
  373. localStorage.setItem("aniscriptsUsed",JSON.stringify(aniscriptsUsed));
  374. }
  375. else{
  376. var localStorageAvailable = false;
  377. };
  378.  
  379. useScripts = {//most modules are turned on by default
  380. notifications : true,
  381. socialTab : true,
  382. favourites : true,
  383. forumComments : true,
  384. staffPages : true,
  385. tagDescriptions : true,
  386. completedScore : true,
  387. moreStats : true,
  388. characterFavouriteCount : true,
  389. usefulLinks : false,
  390. reTweet : false,
  391. reTweetKiller : false,
  392. userRecs : true,
  393. CSSfavs : false,
  394. CSScompactBrowse : false,
  395. CSSSFWmode : false,
  396. CSSmangaGreen: false,
  397. CSSfollowCounter: true,
  398. CSSdecimalPoint: false,
  399. hideLikes: false,
  400. memeScripts: false
  401. };
  402.  
  403. var forceRebuildFlag = false;
  404.  
  405. if(localStorageAvailable){
  406. var localStorageItem = localStorage.getItem("hohSettings");
  407. if(localStorageItem != null && localStorageItem != ""){
  408. var useScriptsSettings = JSON.parse(localStorageItem);
  409. for(key in useScriptsSettings){//this is to keep the default settings if the version in local storage is outdated
  410. useScripts[key] = useScriptsSettings[key];
  411. };
  412. };
  413. localStorage.setItem("hohSettings",JSON.stringify(useScripts));
  414. };
  415.  
  416. try{//looks at the nav
  417. var whoAmI = document.getElementById("nav").children[0].children[1].children[1].href.match(/[a-zA-Z0-9-]*\/$/)[0].slice(0,-1);
  418. }
  419. catch(err){
  420. var whoAmI = "";
  421. };//use later for some scripts
  422.  
  423. Element.prototype.remove = function(){//more comfy way to remove DOM elements
  424. this.parentElement.removeChild(this);
  425. }
  426. NodeList.prototype.remove = HTMLCollection.prototype.remove = function() {
  427. for(var i = this.length - 1; i >= 0; i--) {
  428. if(this[i] && this[i].parentElement) {
  429. this[i].parentElement.removeChild(this[i]);
  430. }
  431. }
  432. };
  433.  
  434. var svgAssets = {
  435. likeIcon : "<svg data-v-7460ac43=\"\" data-v-6e3ccc50=\"\" aria-hidden=\"true\" data-prefix=\"fas\" data-icon=\"heart\" role=\"img\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\" class=\"svg-inline--fa fa-heart fa-w-16 fa-sm\"><path data-v-7460ac43=\"\" data-v-6e3ccc50=\"\" fill=\"currentColor\" d=\"M462.3 62.6C407.5 15.9 326 24.3 275.7 76.2L256 96.5l-19.7-20.3C186.1 24.3 104.5 15.9 49.7 62.6c-62.8 53.6-66.1 149.8-9.9 207.9l193.5 199.8c12.5 12.9 32.8 12.9 45.3 0l193.5-199.8c56.3-58.1 53-154.3-9.8-207.9z\" class=\"\"></path></svg>",
  436. retweetIcon : "↷",
  437. envelope : "✉",
  438. replyIcon : "<svg data-v-7460ac43=\"\" aria-hidden=\"true\" data-prefix=\"fas\" data-icon=\"comments\" role=\"img\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 576 512\" class=\"svg-inline--fa fa-comments fa-w-18 fa-sm\"><path data-v-7460ac43=\"\" fill=\"currentColor\" d=\"M416 192c0-88.4-93.1-160-208-160S0 103.6 0 192c0 34.3 14.1 65.9 38 92-13.4 30.2-35.5 54.2-35.8 54.5-2.2 2.3-2.8 5.7-1.5 8.7S4.8 352 8 352c36.6 0 66.9-12.3 88.7-25 32.2 15.7 70.3 25 111.3 25 114.9 0 208-71.6 208-160zm122 220c23.9-26 38-57.7 38-92 0-66.9-53.5-124.2-129.3-148.1.9 6.6 1.3 13.3 1.3 20.1 0 105.9-107.7 192-240 192-10.8 0-21.3-.8-31.7-1.9C207.8 439.6 281.8 480 368 480c41 0 79.1-9.2 111.3-25 21.8 12.7 52.1 25 88.7 25 3.2 0 6.1-1.9 7.3-4.8 1.3-2.9.7-6.3-1.5-8.7-.3-.3-22.4-24.2-35.8-54.5z\" class=\"\"></path></svg>"
  439. };
  440.  
  441. var moreStyle = document.createElement('style');
  442. moreStyle.type = 'text/css';
  443.  
  444. if(useScripts.CSSfavs){
  445. moreStyle.innerHTML += `
  446. .favourites > div > .wrap > div,
  447. .favourites > div > .wrap > a{
  448. /*make the spaces in the grid even*/
  449. margin-bottom: 0px!important;
  450. margin-right: 0px!important;
  451. column-gap: 10px!important;
  452. }
  453. .user .overview{
  454. grid-template-columns: 460px auto!important;
  455. }
  456. .favourites > div > .wrap{
  457. padding: 0px!important;
  458. display: grid;
  459. grid-gap: 10px;
  460. column-gap: 10px!important;
  461. grid-template-columns: repeat(auto-fill,85px);
  462. grid-template-rows: repeat(auto-fill,115px);
  463. background: rgb(0,0,0,0) !important;
  464. width: 470px;
  465. }
  466. .favourite.studio{
  467. cursor: pointer;
  468. min-height: 115px;
  469. font-size: 15px;
  470. display: grid;
  471. grid-gap: 10px;
  472. padding: 2px!important;
  473. padding-top: 8px!important;
  474. background-color: rgba(var(--color-foreground))!important;
  475. text-align: center;
  476. align-content: center;
  477. }
  478. .site-theme-dark .favourite.studio{
  479. background-color: rgb(49,56,68)!important;
  480. }
  481. .favourite.studio::after{
  482. display: inline-block;
  483. background-repeat: no-repeat;
  484. content:"";
  485. margin-left:5px;
  486. background-size: 76px 19px;
  487. width: 76px;
  488. height: 19px;
  489. }
  490. /*adds a logo to most favourite studio entries. Add more if needed */
  491. .favourite.studio[href="/studio/11/MADHOUSE"]::after{
  492. background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/4/44/Madhouse_studio_logo.svg/300px-Madhouse_studio_logo.svg.png");
  493. }
  494. .favourite.studio[href="/studio/4/BONES"]::after{
  495. background-image: url("https://i.stack.imgur.com/7pRQn.png");
  496. }
  497. .favourite.studio[href="/studio/14/Sunrise"]::after{
  498. background-image: url("https://upload.wikimedia.org/wikipedia/en/thumb/8/8c/Sunrise_company_logo.svg/220px-Sunrise_company_logo.svg.png");
  499. }
  500. .favourite.studio[href="/studio/32/Manglobe"]::after{
  501. background-image: url("https://i.stack.imgur.com/alV3I.gif");
  502. }
  503. .favourite.studio[href="/studio/287/David-Production"]::after{
  504. background-image: url("https://upload.wikimedia.org/wikipedia/en/thumb/7/75/David_production.jpg/220px-David_production.jpg");
  505. background-size: 76px 30px;
  506. height: 30px;
  507. width: 76px;
  508. }
  509. .favourite.studio[href="/studio/6/Gainax"]::after{
  510. background-image: url("https://upload.wikimedia.org/wikipedia/en/thumb/a/a8/Gainax_logo.svg/220px-Gainax_logo.svg.png");
  511. }
  512. .favourite.studio[href="/studio/150/Sanrio"]::after{
  513. background-image: url("https://upload.wikimedia.org/wikipedia/en/thumb/4/41/Sanrio_logo.svg/220px-Sanrio_logo.svg.png");
  514. }
  515. .favourite.studio[href="/studio/18/Toei-Animation"]::after{
  516. background-image: url("https://i.stack.imgur.com/AjzVI.png");
  517. background-size: 76px 30px;
  518. height: 30px;
  519. width: 76px;
  520. }
  521. .favourite.studio[href="/studio/34/Hal-Film-Maker"]::after{
  522. background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/0/09/Hal_film_maker_logo.gif/220px-Hal_film_maker_logo.gif");
  523. }
  524. .favourite.studio[href="/studio/68/Mushi-Productions"]::after{
  525. background-image: url("https://i.stack.imgur.com/HmYdT.jpg");
  526. }
  527. .favourite.studio[href="/studio/21/Studio-Ghibli"]::after{
  528. background-image: url("https://upload.wikimedia.org/wikipedia/en/thumb/c/ca/Studio_Ghibli_logo.svg/220px-Studio_Ghibli_logo.svg.png");
  529. background-size: 76px 30px;
  530. height: 30px;
  531. width: 76px;
  532. }
  533. .favourite.studio[href="/studio/13/Studio-4C"]::after{
  534. background-image: url("https://upload.wikimedia.org/wikipedia/en/e/ec/Studio_4C_logo.png");
  535. }
  536. .favourite.studio[href="/studio/2/Kyoto-Animation"]::after{
  537. background-image: url("https://upload.wikimedia.org/wikipedia/en/thumb/b/bf/Kyoto_Animation_logo.svg/250px-Kyoto_Animation_logo.svg.png");
  538. }
  539. .favourite.studio[href="/studio/44/Shaft"]::after{
  540. background-image: url("https://i.stack.imgur.com/tuqhK.png");
  541. }
  542. .favourite.studio[href="/studio/803/Trigger"]::after{
  543. background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/6/63/Trigger_Logo.svg/220px-Trigger_Logo.svg.png");
  544. }
  545. .favourite.studio[href="/studio/7/JC-Staff"]::after{
  546. background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/f/f5/J.C.Staff_Logo.svg/220px-J.C.Staff_Logo.svg.png");
  547. }
  548. .favourite.studio[href="/studio/102/FUNimation-Entertainment"]::after{
  549. background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/Funimation_2016.svg/320px-Funimation_2016.svg.png");
  550. background-size: 76px 15px;
  551. height: 15px;
  552. width: 76px;
  553. }
  554. .favourite.studio[href="/studio/132/PA-Works"]::after{
  555. background-image: url("https://i.stack.imgur.com/7kjSn.png");
  556. background-size: 76px 30px;
  557. height: 30px;
  558. width: 76px;
  559. }
  560. .favourite.studio[href="/studio/6145/Science-SARU"]::after{
  561. background-image: url("https://i.stack.imgur.com/zo9Fx.png");
  562. background-size: 76px 30px;
  563. height: 30px;
  564. width: 76px;
  565. }
  566. .favourite.studio[href="/studio/22/Nippon-Animation"]::after{
  567. background-image: url("https://upload.wikimedia.org/wikipedia/en/thumb/b/b4/Nippon.png/200px-Nippon.png");
  568. }
  569. .favourite.studio[href="/studio/73/TMS-Entertainment"]::after{
  570. background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/b/b9/TMS_Entertainment_logo.svg/220px-TMS_Entertainment_logo.svg.png");
  571. }
  572. .favourite.studio[href="/studio/65/Tokyo-Movie-Shinsha"]::after{
  573. background-image: url("https://upload.wikimedia.org/wikipedia/en/2/22/Tokyo_Movie_Shinsha.png");
  574. }
  575. .favourite.studio[href="/studio/8/Artland"]::after{
  576. background-image: url("https://upload.wikimedia.org/wikipedia/en/thumb/a/ae/Artland_logo.gif/200px-Artland_logo.gif");
  577. }
  578. .favourite.studio[href="/studio/569/MAPPA"]::after{
  579. background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/0/06/MAPPA_Logo.svg/220px-MAPPA_Logo.svg.png");
  580. }
  581. .favourite.studio[href="/studio/314/White-Fox"]::after{
  582. background-image: url("https://i.stack.imgur.com/lwG1T.png");
  583. background-size: 76px 30px;
  584. height: 30px;
  585. width: 76px;
  586. }
  587. .favourite.studio[href="/studio/10/Production-IG"]::after{
  588. background-image: url("https://upload.wikimedia.org/wikipedia/en/thumb/5/5a/Production_I.G_Logo.svg/250px-Production_I.G_Logo.svg.png");
  589. }
  590. .favourite.studio[href="/studio/112/Brains-Base"]::after{
  591. background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/0/00/Brain%27s_Base_logo.png/200px-Brain%27s_Base_logo.png");
  592. }
  593. .favourite.studio[href="/studio/561/A1-Pictures"]::after{
  594. background-image: url("https://i.stack.imgur.com/nBUYo.png");
  595. background-size: 76px 30px;
  596. height: 30px;
  597. width: 76px;
  598. }
  599. .favourite.studio[href="/studio/43/ufotable"]::after{
  600. background-image: url("https://upload.wikimedia.org/wikipedia/en/9/91/Ufotable_logo.png");
  601. background-size: 76px 30px;
  602. height: 30px;
  603. width: 76px;
  604. }
  605. .favourite.studio[href="/studio/858/Wit-Studio"]::after{
  606. background-image: url("https://i.stack.imgur.com/o3Rro.png");
  607. background-size: 76px 30px;
  608. height: 30px;
  609. width: 76px;
  610. }
  611. .favourite.studio[href="/studio/47/Studio-Khara"]::after{
  612. background-image: url("https://i.stack.imgur.com/2d1TT.png");
  613. background-size: 76px 30px;
  614. height: 30px;
  615. width: 76px;
  616. }
  617. .favourite.studio[href="/studio/1/Studio-Pierrot"]::after{
  618. background-image: url("https://upload.wikimedia.org/wikipedia/en/thumb/1/10/Studio_Pierrot.jpg/220px-Studio_Pierrot.jpg");
  619. }
  620. .favourite.studio[href="/studio/436/AIC-Build"]::after,
  621. .favourite.studio[href="/studio/48/AIC"]::after{
  622. background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/6/6b/AIC_logo.png/220px-AIC_logo.png");
  623. }
  624. .favourite.studio[href="/studio/3/GONZO"]::after{
  625. background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/8/85/Gonzo_company.png/220px-Gonzo_company.png");
  626. }
  627. .favourite.studio[href="/studio/300/SILVER-LINK"]::after{
  628. background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3d/Silver_Link_Logo.svg/220px-Silver_Link_Logo.svg.png");
  629. }
  630. .favourite.studio[href="/studio/456/Lerche"]::after{
  631. background-image: url("https://i.stack.imgur.com/gRQPc.png");
  632. }
  633. .favourite.studio[href="/studio/291/CoMix-Wave"]::after{
  634. background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/8/8d/Cwflogo.png/150px-Cwflogo.png");
  635. }
  636. .favourite.studio[href="/studio/95/Doga-Kobo"]::after{
  637. background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/a/a8/Doga_Kobo_Logo.svg/220px-Doga_Kobo_Logo.svg.png");
  638. }
  639. .favourite.studio[href="/studio/290/Kinema-Citrus"]::after{
  640. background-image: url("https://upload.wikimedia.org/wikipedia/commons/c/c0/Kinema_Citrus_logo.png");
  641. background-size: 76px 25px;
  642. height: 25px;
  643. width: 76px;
  644. }
  645. .favourite.studio[href="/studio/333/TYO-Animations"]::after{
  646. background-image: url("https://i.stack.imgur.com/KRqAp.jpg");
  647. background-size: 76px 25px;
  648. height: 25px;
  649. width: 76px;
  650. }
  651. .favourite.studio[href="/studio/41/Satelight"]::after{
  652. background-image: url("https://i.stack.imgur.com/qZVQg.png");
  653. background-size: 76px 30px;
  654. height: 30px;
  655. width: 76px;
  656. }
  657. .favourite.studio[href="/studio/6069/Studio-3Hz"]::after{
  658. background-image: url("https://i.stack.imgur.com/eD0oe.jpg");
  659. }
  660. .favourite.studio[href="/studio/911/Passione"]::after{
  661. background-image: url("https://i.stack.imgur.com/YyEGg.jpg");
  662. }
  663. .favourite.studio[href="/studio/418/Studio-Gokumi"]::after{
  664. background-image: url("https://i.stack.imgur.com/w1y22.png");
  665. }
  666. .favourite.studio[href="/studio/51/diomeda"]::after{
  667. background-image: url("https://i.stack.imgur.com/ZHt3T.jpg");
  668. }
  669. .favourite.studio[href="/studio/91/feel"]::after{
  670. background-image: url("https://upload.wikimedia.org/wikipedia/en/thumb/0/07/Feel_%28company%29_logo.png/220px-Feel_%28company%29_logo.png");
  671. background-size: 76px 25px;
  672. height: 25px;
  673. width: 76px;
  674. }
  675. .favourite.studio[href="/studio/36/Studio-Gallop"]::after{
  676. background-image: url("https://upload.wikimedia.org/wikipedia/commons/3/37/Studio_Gallop.png");
  677. }
  678. .favourite.studio[href="/studio/537/SANZIGEN"]::after{
  679. background-image: url("https://i.stack.imgur.com/CkuqH.png");
  680. background-size: 76px 30px;
  681. height: 30px;
  682. width: 76px;
  683. }
  684. .favourite.studio[href="/studio/35/Seven-Arcs"]::after{
  685. background-image: url("https://upload.wikimedia.org/wikipedia/en/a/ac/Seven_Arcs_logo.png");
  686. background-size: 76px 25px;
  687. height: 25px;
  688. width: 76px;
  689. }
  690. .favourite.studio[href="/studio/6222/CloverWorks"]::after{
  691. background-image: url("https://i.stack.imgur.com/9Fvr7.jpg");
  692. }
  693. .favourite.studio[href="/studio/144/Pony-Canyon"]::after{
  694. background-image: url("https://i.stack.imgur.com/9kkew.png");
  695. }
  696. .favourite.studio[href="/studio/493/Aniplex-of-America"]::after,
  697. .favourite.studio[href="/studio/17/Aniplex"]::after{
  698. background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/3/37/Aniplex_logo.svg/220px-Aniplex_logo.svg.png");
  699. }
  700. .favourite.studio[href="/studio/555/Studio-Chizu"]::after{
  701. background-image: url("http://www.studio-chizu.jp/images/logo.gif");
  702. }
  703. .favourite.studio[href="/studio/37/Studio-DEEN"]::after{
  704. background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/Studio_Deen_logo.svg/220px-Studio_Deen_logo.svg.png");
  705. }
  706. .favourite.studio[href="/studio/159/Kodansha"]::after{
  707. background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/4/4c/Kodansha.png/200px-Kodansha.png");
  708. }
  709. .favourite.studio[href="/studio/437/Kamikaze-Douga"]::after{
  710. background-image: url("https://img7.anidb.net/pics/anime/178777.jpg");
  711. }
  712. .favourite.studio[href="/studio/459/Nitroplus"]::after{
  713. background-image: url("https://upload.wikimedia.org/wikipedia/en/thumb/0/09/Nitroplus_logo.png/220px-Nitroplus_logo.png");
  714. }
  715. .favourite.studio[href="/studio/166/Movic"]::after{
  716. background-image: url("https://upload.wikimedia.org/wikipedia/commons/f/f3/Movic_logo.png");
  717. }
  718. .favourite.studio[href="/studio/38/Arms"]::after{
  719. background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/f/f4/Arms_Corporation.png/200px-Arms_Corporation.png");
  720. }
  721. .favourite.studio[href="/studio/247/ShinEi-Animation"]::after{
  722. background-image: url("https://i.stack.imgur.com/b2lcL.png");
  723. }
  724. .favourite.studio[href="/studio/6235/SEK-Studio"]::after{
  725. background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/5/51/Flag_of_North_Korea.svg/125px-Flag_of_North_Korea.svg.png");
  726. background-size: 74px 25px;
  727. height: 25px;
  728. width: 74px;
  729. }
  730. .favourite.studio[href="/studio/58/Square-Enix"]::after{
  731. background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/a/af/Square_Enix_logo.svg/230px-Square_Enix_logo.svg.png");
  732. }
  733. .favourite.studio[href="/studio/503/Nintendo-Co-Ltd"]::after{
  734. background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/0/0d/Nintendo.svg/220px-Nintendo.svg.png");
  735. }
  736. .favourite.studio[href="/studio/167/Sega"]::after{
  737. background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/6/63/Sega_logo.svg/200px-Sega_logo.svg.png");
  738. }
  739. .favourite.studio[href="/studio/193/Idea-Factory"]::after{
  740. background-image: url("https://upload.wikimedia.org/wikipedia/en/e/eb/Idea_factory.gif");
  741. }
  742. .favourite.studio[href="/studio/6077/Orange"]::after{
  743. background-image: url("http://www.orange-cg.com/img/common/logo.gif");
  744. }
  745. .favourite.studio[href="/studio/309/GoHands"]::after{
  746. background-image: url("https://i.stack.imgur.com/pScIZ.jpg");
  747. }
  748. .favourite.studio[href="/studio/104/Lantis"]::after{
  749. background-image: url("https://upload.wikimedia.org/wikipedia/commons/3/39/Lantis_logo.png");
  750. }
  751. .favourite.studio[href="/studio/6071/Studio-Shuka"]::after{
  752. background-image: url("https://upload.wikimedia.org/wikipedia/commons/f/fa/Shuka_studio.jpg");
  753. }
  754. .favourite.studio[href="/studio/53/Dentsu"]::after{
  755. background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/1/10/Dentsu_logo.svg/200px-Dentsu_logo.svg.png");
  756. }
  757. .favourite.studio[href="/studio/143/Mainichi-Broadcasting"]::after{
  758. background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/e/e9/Mainichi_Broadcasting_System_logo.svg/200px-Mainichi_Broadcasting_System_logo.svg.png");
  759. }
  760. .favourite.studio[href="/studio/376/Sentai-Filmworks"]::after{
  761. background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/4/4b/Sentai_Filmworks_Official_Logo.jpg/220px-Sentai_Filmworks_Official_Logo.jpg");
  762. }
  763. .favourite.studio[href="/studio/681/ASCII-Media-Works"]::after{
  764. background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/f/f5/ASCII_Media_Works_logo.svg/220px-ASCII_Media_Works_logo.svg.png");
  765. }
  766. .favourite.studio[href="/studio/334/Ordet"]::after{
  767. background-image: url("https://i.stack.imgur.com/evr12.png");
  768. background-size: 76px 30px;
  769. height: 30px;
  770. width: 76px;
  771. }
  772. .favourite.studio[href="/studio/238/ATX"]::after{
  773. background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/c/c6/AT-X_logo.svg/150px-AT-X_logo.svg.png");
  774. background-size: 76px 30px;
  775. height: 30px;
  776. width: 76px;
  777. }
  778. .favourite.studio[href="/studio/66/Key"]::after{
  779. background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/1/1f/Key_Visual_Arts_Logo.svg/167px-Key_Visual_Arts_Logo.svg.png");
  780. background-size: 76px 30px;
  781. height: 30px;
  782. width: 76px;
  783. }
  784. .favourite.studio[href="/studio/145/TBS"]::after{
  785. background-image: url("https://upload.wikimedia.org/wikipedia/commons/thumb/f/f8/TBS_logo.svg/200px-TBS_logo.svg.png");
  786. }
  787. .favourite.studio[href="/studio/108/Media-Factory"]::after{
  788. background-image: url("https://i.stack.imgur.com/rR7yU.png");
  789. background-size: 76px 25px;
  790. height: 25px;
  791. width: 76px;
  792. }
  793. .favourite.studio[href="/studio/346/Hoods-Entertainment"]::after{
  794. background-image: url("https://i.stack.imgur.com/p7S0I.png");
  795. }
  796. `;
  797. };
  798. if(useScripts.CSScompactBrowse){
  799. moreStyle.innerHTML += `
  800. .search-page-unscoped.container{
  801. padding-left: 10px;
  802. padding-right: 0px;
  803. }
  804. .search-page-unscoped .description{
  805. display:none;
  806. }
  807. body,.search-page-unscoped .preview-section{
  808. counter-reset: ranking;
  809. }
  810. .search-page-unscoped .data::before {
  811. left:2px;
  812. opacity:0.4;
  813. font-size:70%;
  814. position:absolute;
  815. counter-increment: ranking;
  816. content: counter(ranking);
  817. }
  818. .search-page-unscoped .media-card{
  819. min-width:150px!important;
  820. grid-template-columns: 150px auto!important;
  821. height: 297px!important;
  822. width: 150px !important;
  823. }
  824. .search-page-unscoped .cover .overlay{
  825. padding-left:8px!important;
  826. padding-right:8px!important;
  827. padding-top:4px!important;
  828. }
  829. .search-page-unscoped .grid-wrap > .media-card{
  830. margin-left:30px;
  831. }
  832. .search-page-unscoped .cover{
  833. width:150px;
  834. height:215px;
  835. margin-top:53px;
  836. z-index: 100;
  837. }
  838. .search-page-unscoped .data{
  839. margin-left: -150px;
  840. }
  841. .search-page-unscoped .genres{
  842. min-height:29px;
  843. z-index: 101;
  844. padding: 8px 5px!important;
  845. padding-bottom: 2px !important;
  846. font-size: 1rem!important;
  847. }
  848. .search-page-unscoped .list-edit{
  849. z-index: 101;
  850. }
  851. .search-page-unscoped .airing-countdown{
  852. padding: 5px!important;
  853. }
  854. .search-page-unscoped .grid-wrap{
  855. grid-template-columns: repeat(auto-fill, 150px) !important;
  856. }
  857. .search-page-unscoped .media{
  858. grid-template-columns: repeat(auto-fill, 150px) !important;
  859. width:100%;
  860. }
  861. .search-page-unscoped .overlay .studio{
  862. margin-top: 2px!important;
  863. margin-bottom: -8px!important;
  864. }
  865. .search-page-unscoped .list-status{
  866. width: 20px!important;
  867. height: 20px!important;
  868. }
  869. .search-page-unscoped .media-card:nth-child(5){
  870. display: inline-grid!important;
  871. }
  872. `;
  873. };
  874. if(useScripts.CSSSFWmode){
  875. moreStyle.innerHTML += `
  876. .shadow{
  877. display:none;
  878. }
  879. .banner{
  880. height: 50px!important;
  881. opacity: 0.1;
  882. }
  883. .avatar{
  884. opacity:0.1;
  885. }
  886. .markdown img{
  887. opacity:0.1;
  888. }
  889. .cover{
  890. opacity:0.05!important;
  891. }
  892. img[src*=".gif"]{
  893. display:none;
  894. }
  895. html{
  896. --color-blue: 159, 173, 189!important;
  897. --color-green: 159, 173, 189!important;
  898. }
  899. .favourite{
  900. opacity:0.1;
  901. }
  902. img[src="/img/icons/icon.svg"]{
  903. display: none;
  904. }
  905. .markdown span.youtube{
  906. display: none!important;
  907. }
  908. .genre-overview{
  909. display: none;
  910. }
  911. .progress .bar{
  912. display: none;
  913. }
  914. .scroller div.emoji-spinner{
  915. display: none;
  916. }
  917. .donator-badge{
  918. display: none!important;
  919. }
  920. .list-preview-wrap .section-header:first-child h2:first-child{
  921. display:none;
  922. }
  923. .list-preview-wrap .section-header:first-child::before{
  924. content: "Projects in progress";
  925. }
  926. .category{
  927. background: none!important;
  928. }
  929. `;
  930. };
  931. if(useScripts.CSSfollowCounter){
  932. moreStyle.innerHTML += `
  933. .user-page-unscoped .container{
  934. padding-right: 0px;
  935. padding-left: 10px;
  936. }
  937. .user-social .user-follow > div.wrap{
  938. grid-template-columns: repeat(auto-fill,75px)!important;
  939. grid-template-rows: repeat(auto-fill,75px)!important;
  940. }
  941. body{
  942. counter-reset: followCount;
  943. }
  944. .user-social .user-follow .user{
  945. counter-increment: followCount;
  946. }
  947. .user-social .user-follow .user:nth-child(10n),
  948. .user-social .user-follow .user:last-child{
  949. overflow: visible!important;
  950. }
  951. .user-social .user-follow .user:last-child::after{
  952. content: "Total: " counter(followCount);
  953. position: relative;
  954. left: 85px;
  955. top: -48px;
  956. opacity: 0.5;
  957. }
  958. .user-social .user-follow .user:nth-child(10n)::after{
  959. content: counter(followCount);
  960. position: relative;
  961. left: 85px;
  962. top: -80px;
  963. opacity: 0.5;
  964. }
  965. `;
  966. };
  967. if(useScripts.CSSgreenManga){
  968. moreStyle.innerHTML += `
  969. .activity-manga_list > div > div > div > div > .title{
  970. color: rgba(var(--color-green))!important;
  971. }
  972. `;
  973. };
  974. if(useScripts.CSSdecimalPoint){
  975. moreStyle.innerHTML += `
  976. .medialist.POINT_10_DECIMAL .score[score="10"]::after,
  977. .medialist.POINT_10_DECIMAL .score[score="9"]::after,
  978. .medialist.POINT_10_DECIMAL .score[score="8"]::after,
  979. .medialist.POINT_10_DECIMAL .score[score="7"]::after,
  980. .medialist.POINT_10_DECIMAL .score[score="6"]::after,
  981. .medialist.POINT_10_DECIMAL .score[score="5"]::after,
  982. .medialist.POINT_10_DECIMAL .score[score="4"]::after,
  983. .medialist.POINT_10_DECIMAL .score[score="3"]::after,
  984. .medialist.POINT_10_DECIMAL .score[score="2"]::after,
  985. .medialist.POINT_10_DECIMAL .score[score="1"]::after{
  986. margin-left:-4px;
  987. content: ".0";
  988. }
  989. `;
  990. };
  991. document.getElementsByTagName('head')[0].appendChild(moreStyle);
  992.  
  993. var queryMediaList = `
  994. query ($name: String!, $listType: MediaType) {
  995. MediaListCollection (userName: $name, type: $listType) {
  996. lists {
  997. entries {
  998. ... mediaListEntry
  999. }
  1000. }
  1001. }
  1002. }
  1003.  
  1004. fragment mediaListEntry on MediaList {
  1005. mediaId
  1006. status
  1007. progress
  1008. progressVolumes
  1009. repeat
  1010. notes
  1011. startedAt {
  1012. year
  1013. month
  1014. day
  1015. }
  1016. media {
  1017. episodes
  1018. chapters
  1019. volumes
  1020. duration
  1021. nextAiringEpisode {
  1022. episode
  1023. }
  1024. format
  1025. title {
  1026. romaji
  1027. }
  1028. tags {
  1029. name
  1030. }
  1031. }
  1032. scoreRaw: score (format: POINT_100)
  1033. }
  1034. `;
  1035.  
  1036. var queryActivity = "query ($id: Int!) { Activity(id: $id) { ... on TextActivity { id userId type replyCount text createdAt user { id name avatar { large } } likes { id name avatar { large } } replies { id text(asHtml: true) createdAt user { id name avatar { large } } likes { id name avatar { large } } } } ... on ListActivity { id userId type status progress replyCount createdAt user { id name avatar { large } } media { coverImage { large } id title { userPreferred } } likes { id name avatar { large } } replies { id text(asHtml: true) createdAt user { id name avatar { large } } likes { id name avatar { large } } } } ... on MessageActivity { id type replyCount createdAt messenger { id name avatar { large } } likes { id name avatar { large } } replies { id text(asHtml: true) createdAt user { id name avatar { large } } likes { id name avatar { large } } } } } }";
  1037.  
  1038. var activityCache = {};//reduce API calls even if localStorage is not available.
  1039.  
  1040. var handleResponse = function(response){//generic handling of API responses
  1041. return response.json().then(function(json){
  1042. return response.ok ? json : Promise.reject(json);
  1043. });
  1044. };
  1045. var handleError = function(error){
  1046. //alert("Error, check console"); //fixme
  1047. console.error(error);
  1048. };
  1049. var url = 'https://graphql.anilist.co';//Current Anilist API location
  1050.  
  1051. var listActivityCall = function(query,variables,callback,vars,cache){
  1052. /*
  1053. query=graphql request
  1054. vars=just values to pass on to the callback function
  1055. cache::true use cached data if available
  1056. cache::false allways fetch new data
  1057. */
  1058. var handleData = function(data){
  1059. pending[variables.id] = false;
  1060. if(localStorageAvailable){
  1061. localStorage.setItem(variables.id + "",JSON.stringify(data));
  1062. aniscriptsUsed.keys.push(variables.id);
  1063. if(aniscriptsUsed.keys.length > 1000){//don't hog to much of localStorage
  1064. for(var i=0;i<10;i++){
  1065. localStorage.removeItem(aniscriptsUsed.keys[0]);
  1066. aniscriptsUsed.keys.shift();
  1067. };
  1068. };
  1069. localStorage.setItem("aniscriptsUsed",JSON.stringify(aniscriptsUsed));
  1070. }
  1071. else{
  1072. activityCache[variables.id] = data;//still useful even if we don't have localstorage
  1073. };
  1074. callback(data,vars);
  1075. };
  1076. var options = {//generic headers provided by API examples
  1077. method: 'POST',
  1078. headers: {
  1079. 'Content-Type': 'application/json',
  1080. 'Accept': 'application/json',
  1081. },
  1082. body: JSON.stringify({
  1083. query: query,
  1084. variables: variables
  1085. })
  1086. };
  1087. if(localStorageAvailable && cache){
  1088. var localStorageItem = localStorage.getItem(variables.id + "");
  1089. if(!(localStorageItem === null)){
  1090. callback(JSON.parse(localStorageItem),vars);
  1091. console.log("localStorage cache hit");
  1092. return;
  1093. };
  1094. }
  1095. else if(activityCache.hasOwnProperty(variables.id) && cache){
  1096. callback(activityCache[variables.id],vars);
  1097. console.log("cache hit");
  1098. return;
  1099. };
  1100. fetch(url,options).then(handleResponse).then(handleData).catch(handleError);
  1101. ++document.APIcallsUsed;
  1102. console.log("fetching new data");
  1103. };
  1104.  
  1105. var generalAPIcall = function(query,variables,callback){//has no cache stuff to worry about
  1106. var handleData = function(data){
  1107. callback(data,variables);
  1108. };
  1109. var options = {
  1110. method: 'POST',
  1111. headers: {
  1112. 'Content-Type': 'application/json',
  1113. 'Accept': 'application/json',
  1114. },
  1115. body: JSON.stringify({
  1116. query: query,
  1117. variables: variables
  1118. })
  1119. };
  1120. fetch(url,options).then(handleResponse).then(handleData).catch(handleError);
  1121. ++document.APIcallsUsed;
  1122. console.log("fetching new data");
  1123. };
  1124.  
  1125. var reTweetCallback = function(data){
  1126. var embedList = document.getElementsByClassName("share" + data.data.Activity.id);
  1127. for(var i=0;i<embedList.length;i++){
  1128. var embed = embedList[i];
  1129. embed.innerHTML = "";
  1130. if(embed.hohLevel > 10){
  1131. embed.innerHTML = "Reached the nesting limit";
  1132. embed.classList.remove("share" + data.data.Activity.id);
  1133. return;
  1134. };
  1135. var header = document.createElement("div");
  1136. var content = document.createElement("div");
  1137. content.innerHTML = data.data.Activity.text;
  1138. var uselessMatchData = content.innerText.match(/^(!share|RT)\s+(https:\/\/anilist\.co\/activity\/)?(\d+)/);
  1139. if(content.children[0].innerText.match(/^(!share|RT)/)){
  1140. if(content.children[0].innerHTML.match(/<br>/)){
  1141. content.children[0].innerHTML = content.children[0].innerHTML.replace(/^(!share|RT).*?<br>/,"");
  1142. }
  1143. else{
  1144. content.children[0].innerHTML = "";
  1145. };
  1146. };
  1147. content.classList.add("activity-markdown");
  1148. header.classList.add("header");
  1149. var avatar = document.createElement("a");
  1150. avatar.classList.add("avatar");
  1151. avatar.style.backgroundImage = "url(" + data.data.Activity.user.avatar.large + ")";
  1152. avatar.href = "/user/" + data.data.Activity.user.name;
  1153. var name = document.createElement("a");
  1154. name.innerText = data.data.Activity.user.name;
  1155. name.href = "/user/" + data.data.Activity.user.name;
  1156. name.classList.add("name");
  1157. header.appendChild(avatar);
  1158. header.appendChild(name);
  1159. embed.appendChild(header);
  1160. embed.appendChild(content);
  1161. var actions = document.createElement("div");
  1162. var time = document.createElement("time");
  1163. actions.classList.add("time");
  1164. var postTime = new Date(data.data.Activity.createdAt*1000);
  1165. var currentTime = new Date();
  1166. actions.appendChild(time);
  1167.  
  1168. var fakeActions = document.createElement("div");
  1169. actions.classList.add("actions");
  1170. actions.appendChild(fakeActions);
  1171.  
  1172. time.dateTime = postTime.toISOString();
  1173. if(currentTime - postTime < 1000*60*60*24){
  1174. if(postTime.getMinutes() < 10){
  1175. time.innerText = postTime.getHours() + ":0" + postTime.getMinutes();
  1176. }
  1177. else{
  1178. time.innerText = postTime.getHours() + ":" + postTime.getMinutes();
  1179. };
  1180. }
  1181. else{
  1182. time.innerText = postTime.toLocaleDateString() + " " + postTime.getHours() + ":" + postTime.getMinutes();
  1183. };
  1184. embed.appendChild(actions);
  1185. embed.classList.remove("share" + data.data.Activity.id);
  1186. if(uselessMatchData){
  1187. var embed2 = document.createElement("div");
  1188. embed2.innerHTML = "<i>loading...</i>";
  1189. embed2.classList.add("share" + uselessMatchData[3]);
  1190. embed2.hohLevel = embed.hohLevel + 1;
  1191. embed2.classList.add("hohEmbed");
  1192. content.appendChild(embed2);
  1193. var variables = {id:uselessMatchData[3]};
  1194. var query = `
  1195. query ($id: Int!) {
  1196. Activity(id: $id) {
  1197. ... on TextActivity {
  1198. id
  1199. userId
  1200. type
  1201. replyCount
  1202. text(asHtml: true)
  1203. createdAt
  1204. user {
  1205. id
  1206. name
  1207. avatar {
  1208. large
  1209. }
  1210. }
  1211. }
  1212. }
  1213. }`;
  1214.  
  1215. generalAPIcall(query,variables,reTweetCallback);
  1216. };
  1217. };
  1218. };
  1219.  
  1220. var reTweet = function(){//legacy, will be removed at some point
  1221. var perform = function(){
  1222. if(!document.URL.match(/https:\/\/anilist\.co\/(home|user|activity)\/?([a-zA-Z0-9-]+)?\/?$/)){
  1223. return;
  1224. };
  1225. var listOfActs = document.getElementsByClassName("activity-text");
  1226. for(var i=0;i<listOfActs.length;i++){
  1227. if(listOfActs[i].hasOwnProperty("hohShare") || listOfActs[i].classList.contains("preview")){
  1228. continue;
  1229. };
  1230. listOfActs[i].hohShare = true;
  1231. if(true || listOfActs[i].classList.contains("activity-text")){
  1232. var textContent = listOfActs[i].children[0].children[0].children[1].children[0].children[0];//fragile
  1233. var uselessMatchData = textContent.innerText.match(/^(!share|RT)\s+(https:\/\/anilist\.co\/activity\/)?(\d+)/);
  1234. if(uselessMatchData){
  1235. if(useScripts.reTweetKiller){
  1236. listOfActs[i].remove();
  1237. };
  1238. if(textContent.innerHTML.match(/<br>/)){
  1239. textContent.innerHTML = textContent.innerHTML.replace(/^(!share|RT).*?<br>/,"");
  1240. }
  1241. else{
  1242. textContent.innerHTML = "";
  1243. };
  1244. var embed = document.createElement("div");
  1245. embed.innerHTML = "<i>loading...</i>";
  1246. embed.classList.add("share" + uselessMatchData[3]);
  1247. embed.classList.add("hohEmbed");
  1248. embed.hohLevel = 0;
  1249. textContent.appendChild(embed);
  1250. if(textContent.parentNode.children[textContent.parentNode.children.length-1].nodeName == "BLOCKQUOTE"){
  1251. textContent.parentNode.children[textContent.parentNode.children.length-1].remove();
  1252. };
  1253. var variables = {id:uselessMatchData[3]};
  1254. var query = `
  1255. query ($id: Int!) {
  1256. Activity(id: $id) {
  1257. ... on TextActivity {
  1258. id
  1259. userId
  1260. type
  1261. replyCount
  1262. text(asHtml: true)
  1263. createdAt
  1264. user {
  1265. id
  1266. name
  1267. avatar {
  1268. large
  1269. }
  1270. }
  1271. }
  1272. }
  1273. }`;
  1274.  
  1275. generalAPIcall(query,variables,reTweetCallback);
  1276. };
  1277. };
  1278. };
  1279. };
  1280. var tryAgain = function(){//loop the notification script until we leave that page
  1281. setTimeout(function(){
  1282. perform();
  1283. if(document.URL.match(/https:\/\/anilist\.co\/(home|user|activity)\/?([a-zA-Z0-9-]+)?\/?$/)){///https:\/\/anilist\.co\/home\/?/
  1284. tryAgain()
  1285. }
  1286. else{
  1287. activeScripts.reTweet = false;
  1288. }
  1289. },200);
  1290. };
  1291. activeScripts.reTweet = true;
  1292. perform();
  1293. tryAgain();
  1294. };
  1295.  
  1296.  
  1297. var userRecs = function(){
  1298. var perform = function(){
  1299. if(!document.URL.match(/https:\/\/anilist\.co\/(anime|manga)\/\d*\/[0-9a-zA-Z-]*\/$/)){
  1300. return;
  1301. };
  1302. var pageId = parseInt(document.URL.match(/https:\/\/anilist\.co\/(anime|manga)\/(\d+)/)[2]);
  1303. if(userRecsList.hasOwnProperty(pageId) || userRecsList.hasOwnProperty(pageId+"")){
  1304. var lastSection = document.getElementsByClassName("grid-section-wrap");
  1305. if(lastSection.length){
  1306. lastSection = lastSection[lastSection.length-1];
  1307. if(lastSection.hasOwnProperty("hohRecs")){
  1308. return;
  1309. };
  1310. lastSection.hohRecs = true;
  1311. var recSection = document.createElement("div");
  1312. var recsLabel = document.createElement("h2");
  1313. recsLabel.innerText = "Recommendations";
  1314. recSection.appendChild(recsLabel);
  1315. for(var i=0;i<userRecsList[pageId].length;i++){
  1316. for(var j=0;j<userRecsList[pageId][i]["s"].length;j++){
  1317. var recsItem = document.createElement("div");
  1318. recsItem.classList.add("hohRecsItem");
  1319. var recsItemShow = document.createElement("a");
  1320. recsItemShow.classList.add("hohRecsLabel");
  1321. recsItemShow.href = "https://anilist.co/anime/" + userRecsList[pageId][i]["s"][j]["id"];
  1322. recsItemShow.innerText = userRecsList[pageId][i]["s"][j]["n"];
  1323. recsItem.appendChild(recsItemShow);
  1324. var recsItemName = document.createElement("span");
  1325. recsItemName.innerText = " by " + userRecsList[pageId][i].n;
  1326. recsItem.appendChild(recsItemName);
  1327. recSection.appendChild(recsItem);
  1328. };
  1329. };
  1330. lastSection.appendChild(recSection);
  1331. };
  1332. };
  1333. };
  1334. var tryAgain = function(){
  1335. setTimeout(function(){
  1336. perform();
  1337. if(document.URL.match(/https:\/\/anilist\.co\/(anime|manga)\/\d*\/[0-9a-zA-Z-]*\/$/)){
  1338. tryAgain()
  1339. }
  1340. else{
  1341. activeScripts.socialTab = false;
  1342. }
  1343. },500);
  1344. };
  1345. activeScripts.userRecs = true;
  1346. perform();
  1347. tryAgain();
  1348. };
  1349.  
  1350. var enhanceSocialTab = function(){
  1351. var perform = function(){
  1352. if(!document.URL.match(/https:\/\/anilist\.co\/(anime|manga)\/\d*\/[0-9a-zA-Z-]*\/social/)){
  1353. return;
  1354. };
  1355. var listOfActs = document.getElementsByClassName("activity-entry");
  1356. for(var i=0;i<listOfActs.length;i++){//compress activities without comments, they are all the same media entry anyway
  1357. if(
  1358. !listOfActs[i].hasOwnProperty("marked")
  1359. && !(listOfActs[i].children[0].children[2].children[0].children.length > 1)
  1360. ){
  1361. listOfActs[i].marked = true;
  1362. listOfActs[i].children[0].children[0].children[0].remove();//remove cover image
  1363. var elements = listOfActs[i].children[0].children[0].children[0].children;
  1364. elements[2].parentNode.insertBefore(elements[2],elements[0]);//move profile picture to the beginning of the line
  1365. elements[0].parentNode.parentNode.style.minHeight = "70px";
  1366. elements[0].parentNode.classList.add("hohSocialTabActivityCompressedContainer");
  1367. elements[0].style.verticalAlign = "bottom";
  1368. elements[0].style.marginTop = "0px";
  1369. elements[1].classList.add("hohSocialTabActivityCompressedName");
  1370. elements[2].classList.add("hohSocialTabActivityCompressedStatus");
  1371. listOfActs[i].style.marginBottom = "10px";
  1372. };
  1373. };
  1374. /*add average score to social tab*/
  1375. var listOfFollowers = document.getElementsByClassName("follow");
  1376. var averageScore = 0;
  1377. var averageCount = 0;
  1378. for(var i=0;i<listOfFollowers.length;i++){
  1379. if(
  1380. listOfFollowers[i].children.length == 4
  1381. ){
  1382. if(listOfFollowers[i].children[3].nodeName != "svg"){
  1383. var followScore = listOfFollowers[i].children[3].innerText.match(/\d+\.?\d*/g);
  1384. if(followScore && followScore.length == 2){
  1385. averageScore += followScore[0]/followScore[1];
  1386. averageCount++;
  1387. }
  1388. else if(followScore && followScore.length == 1){//star rating
  1389. averageScore += (followScore[0]*20 - 10)/100;
  1390. averageCount++;
  1391. };
  1392. }
  1393. else{//do count smiley scores, but with lower confidence
  1394. var smileyScore = listOfFollowers[i].children[3].dataset.icon;
  1395. if(smileyScore == "frown"){
  1396. averageScore += (40/100)*0.5;
  1397. averageCount += 0.5;
  1398. }
  1399. else if(smileyScore == "meh"){
  1400. averageScore += (60/100)*0.5;
  1401. averageCount += 0.5;
  1402. }
  1403. else if(smileyScore == "smile"){
  1404. averageScore += (90/100)*0.5;
  1405. averageCount += 0.5;
  1406. };
  1407. };
  1408. };
  1409. };
  1410. if(averageCount){
  1411. var locationForIt = document.getElementById("averageScore");
  1412. if(!locationForIt){
  1413. var locationForIt = document.createElement("span");
  1414. locationForIt.id = "averageScore";
  1415. document.getElementsByClassName("following")[0].insertBefore(
  1416. locationForIt,
  1417. document.getElementsByClassName("following")[0].children[0]
  1418. );
  1419. };
  1420. locationForIt.innerHTML = "average: " + (100 * averageScore/averageCount).toFixed(1) + "/100";
  1421. };
  1422. /*end average score*/
  1423. };
  1424. var tryAgain = function(){//loop the notification script until we leave that page
  1425. setTimeout(function(){
  1426. perform();
  1427. if(document.URL.match(/https:\/\/anilist\.co\/(anime|manga)\/\d*\/[0-9a-zA-Z-]*\/social/)){
  1428. tryAgain()
  1429. }
  1430. else{
  1431. activeScripts.socialTab = false;
  1432. }
  1433. },100);
  1434. };
  1435. activeScripts.socialTab = true;
  1436. perform();
  1437. tryAgain();
  1438. };
  1439.  
  1440. var enhanceForum = function(){//purpose: reddit-style comment three collapse button
  1441. var perform = function(){
  1442. if(!document.URL.match(/https:\/\/anilist\.co\/forum\/thread\/.*/)){
  1443. return;
  1444. };
  1445. var comments = document.getElementsByClassName("comment-wrap");
  1446. for(var i=0;i<comments.length;i++){
  1447. if(comments[i].hasOwnProperty("hohVisited")){
  1448. }
  1449. else{
  1450. comments[i].hohVisited = true;
  1451. var hider = document.createElement("span");
  1452. hider.innerHTML = "[-]";
  1453. hider.classList.add("hohForumHider");
  1454. hider.onclick = function(){
  1455. if(this.innerHTML == "[-]"){
  1456. this.innerHTML = "[+]";
  1457. this.parentNode.parentNode.children[1].style.display = "none";
  1458. if(this.parentNode.parentNode.parentNode.children.length > 1){
  1459. this.parentNode.parentNode.parentNode.children[1].style.display = "none";
  1460. };
  1461. }
  1462. else{
  1463. this.innerHTML = "[-]";
  1464. this.parentNode.parentNode.children[1].style.display = "block";
  1465. if(this.parentNode.parentNode.parentNode.children.length > 1){
  1466. this.parentNode.parentNode.parentNode.children[1].style.display = "block";
  1467. };
  1468. };
  1469. };
  1470. comments[i].children[0].children[0].insertBefore(hider,comments[i].children[0].children[0].children[0]);
  1471. };
  1472. };
  1473. };
  1474. var tryAgain = function(){//loop the notification script until we leave that page
  1475. setTimeout(function(){
  1476. perform();
  1477. if(document.URL.match(/https:\/\/anilist\.co\/forum\/thread\/.*/)){
  1478. tryAgain()
  1479. }
  1480. else{
  1481. activeScripts.forumComments = false;
  1482. }
  1483. },100);
  1484. };
  1485. activeScripts.forumComments = true;
  1486. perform();
  1487. tryAgain();
  1488. };
  1489.  
  1490. var enhanceStaff = function(){//currently only adds a favourite count
  1491. if(!document.URL.match(/https:\/\/anilist\.co\/staff\/.*/)){
  1492. return;
  1493. };
  1494. var filterGroup = document.getElementsByClassName("content");
  1495. if(!filterGroup.length){
  1496. setTimeout(function(){
  1497. enhanceStaff();
  1498. },200);//takes some time to load
  1499. return;
  1500. };
  1501. filterGroup = filterGroup[0];
  1502. var favCount = document.createElement("span");
  1503. favCount.id = "hohFavCount";
  1504. favCount.innerText;
  1505. filterGroup.appendChild(favCount);
  1506. var variables = {id: document.URL.match(/\/staff\/(\d+)\//)[1]};
  1507. var query = "query($id: Int!){Staff(id: $id){favourites}}";
  1508. var favCallback = function(data){
  1509. var favButton = document.getElementsByClassName("favourite");
  1510. if(data.data.Staff.favourites == 0 && favButton[0].classList.contains("isFavourite")){//safe to assume
  1511. document.getElementById("hohFavCount").innerText = data.data.Staff.favourites+1;
  1512. }
  1513. else{
  1514. document.getElementById("hohFavCount").innerText = data.data.Staff.favourites;
  1515. };
  1516. if(favButton.length){
  1517. favButton[0].onclick = function(){
  1518. var favCount = document.getElementById("hohFavCount");
  1519. if(this.classList.contains("isFavourite")){
  1520. favCount.innerText = Math.max(parseInt(favCount.innerText)-1,0);//0 or above, just to avoid looking silly
  1521. }
  1522. else{
  1523. favCount.innerText = parseInt(favCount.innerText)+1;
  1524. };
  1525. };
  1526. };
  1527. };
  1528. generalAPIcall(query,variables,favCallback);
  1529. };
  1530.  
  1531.  
  1532. //todo: link the relevant status post
  1533. var addCompletedScores = function(){
  1534. var perform = function(){
  1535. if(!document.URL.match(/https:\/\/anilist\.co\/(home|user|activity)\/?([a-zA-Z0-9-]+)?\/?$/)){
  1536. return;
  1537. };
  1538. var status = document.getElementsByClassName("status");
  1539. for(var i=0;i<status.length;i++){
  1540. if(status[i].innerText.match(/^(c|C)ompleted/)){
  1541. if(!status[i].hasOwnProperty("hohScoreMatched")){
  1542. status[i].hohScoreMatched = true;
  1543. var scoreInfo = document.createElement("span");
  1544. var userName = status[i].parentNode.children[0].innerText;
  1545. var mediaId = /\/(\d+)\//.exec(status[i].children[0].href);
  1546. if(!mediaId || !mediaId.length){
  1547. continue;
  1548. };
  1549. mediaId = mediaId[1];
  1550. scoreInfo.classList.add("hohCS" + userName + mediaId);
  1551. status[i].appendChild(scoreInfo);
  1552. var callback = function(data){
  1553. var statusFind = document.getElementsByClassName("hohCS" + data.data.MediaList.user.name + data.data.MediaList.mediaId);
  1554. var suffix = "";//comma was a bad idea
  1555. //the svg blobs below are the Anilist smiley faces and stars
  1556. if(data.data.MediaList.user.mediaListOptions.scoreFormat == "POINT_100"){
  1557. suffix = " " + data.data.MediaList.score + "/100";
  1558. }
  1559. else if(
  1560. data.data.MediaList.user.mediaListOptions.scoreFormat == "POINT_10_DECIMAL" ||
  1561. data.data.MediaList.user.mediaListOptions.scoreFormat == "POINT_10"
  1562. ){
  1563. suffix = " " + data.data.MediaList.score + "/10";
  1564. }
  1565. else if(data.data.MediaList.user.mediaListOptions.scoreFormat == "POINT_3"){
  1566. if(data.data.MediaList.score == 3){
  1567. suffix = "<svg data-v-ca4e7a3a=\"\" aria-hidden=\"true\" data-prefix=\"far\" data-icon=\"smile\" role=\"img\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 496 512\" class=\"svg-inline--fa fa-smile fa-w-16 fa-lg\"><path data-v-ca4e7a3a=\"\" fill=\"currentColor\" d=\"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm84-143.4c-20.8 25-51.5 39.4-84 39.4s-63.2-14.3-84-39.4c-8.5-10.2-23.6-11.5-33.8-3.1-10.2 8.5-11.5 23.6-3.1 33.8 30 36 74.1 56.6 120.9 56.6s90.9-20.6 120.9-56.6c8.5-10.2 7.1-25.3-3.1-33.8-10.2-8.4-25.3-7.1-33.8 3.1zM168 240c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm160 0c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32z\" class=\"\"></path></svg>";
  1568. }
  1569. else if(data.data.MediaList.score == 2){
  1570. suffix = "<svg data-v-ca4e7a3a=\"\" aria-hidden=\"true\" data-prefix=\"far\" data-icon=\"meh\" role=\"img\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 496 512\" class=\"svg-inline--fa fa-meh fa-w-16 fa-lg\"><path data-v-ca4e7a3a=\"\" fill=\"currentColor\" d=\"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm-80-216c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm160-64c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm8 144H160c-13.2 0-24 10.8-24 24s10.8 24 24 24h176c13.2 0 24-10.8 24-24s-10.8-24-24-24z\" class=\"\"></path></svg>";
  1571. }
  1572. else if(data.data.MediaList.score == 1){
  1573. suffix = "<svg data-v-ca4e7a3a=\"\" aria-hidden=\"true\" data-prefix=\"far\" data-icon=\"frown\" role=\"img\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 496 512\" class=\"svg-inline--fa fa-frown fa-w-16 fa-lg\"><path data-v-ca4e7a3a=\"\" fill=\"currentColor\" d=\"M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm-80-216c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm160-64c-17.7 0-32 14.3-32 32s14.3 32 32 32 32-14.3 32-32-14.3-32-32-32zm-80 128c-40.2 0-78 17.7-103.8 48.6-8.5 10.2-7.1 25.3 3.1 33.8 10.2 8.5 25.3 7.1 33.8-3.1 16.6-19.9 41-31.4 66.9-31.4s50.3 11.4 66.9 31.4c4.8 5.7 11.6 8.6 18.5 8.6 5.4 0 10.9-1.8 15.4-5.6 10.2-8.5 11.5-23.6 3.1-33.8C326 321.7 288.2 304 248 304z\" class=\"\"></path></svg>";
  1574. };
  1575.  
  1576. }
  1577. else if(
  1578. data.data.MediaList.user.mediaListOptions.scoreFormat == "POINT_5"
  1579. ){
  1580. suffix = " " + data.data.MediaList.score + "<svg data-v-ca4e7a3a=\"\" aria-hidden=\"true\" data-prefix=\"fas\" data-icon=\"star\" role=\"img\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 576 512\" class=\"icon svg-inline--fa fa-star fa-w-18\"><path data-v-ca4e7a3a=\"\" fill=\"currentColor\" d=\"M259.3 17.8L194 150.2 47.9 171.5c-26.2 3.8-36.7 36.1-17.7 54.6l105.7 103-25 145.5c-4.5 26.3 23.2 46 46.4 33.7L288 439.6l130.7 68.7c23.2 12.2 50.9-7.4 46.4-33.7l-25-145.5 105.7-103c19-18.5 8.5-50.8-17.7-54.6L382 150.2 316.7 17.8c-11.7-23.6-45.6-23.9-57.4 0z\" class=\"\"></path></svg>";
  1581. }
  1582. for(var j=0;j<statusFind.length;j++){
  1583. if(data.data.MediaList.score != 0){
  1584. statusFind[j].innerHTML = suffix;
  1585. };
  1586. };
  1587. };
  1588. var variables = {
  1589. userName: userName,
  1590. mediaId: mediaId
  1591. };
  1592. var query = `
  1593. query (
  1594. $userName: String,
  1595. $mediaId: Int
  1596. ) {
  1597. MediaList (
  1598. userName: $userName,
  1599. mediaId: $mediaId
  1600. ) {
  1601. score
  1602. mediaId
  1603. user {
  1604. name
  1605. mediaListOptions {
  1606. scoreFormat
  1607. }
  1608. }
  1609. }
  1610. }
  1611. `;
  1612. generalAPIcall(query,variables,callback)
  1613. };
  1614. }
  1615. else if(status[i].children.length == 2 && !status[i].classList.contains("form")){
  1616. status[i].children[1].remove();
  1617. };
  1618. };
  1619. var statusScript = document.getElementsByClassName("markdown");
  1620. for(var i=0;i<statusScript.length;i++){
  1621. if(useScripts.memeScripts && !statusScript[i].hasOwnProperty("hohSaMatched")){
  1622. statusScript[i].hohSaMatched = true;
  1623. if(statusScript[i].children.length && statusScript[i].children[0].children.length){
  1624. if(
  1625. statusScript[i].children[0].children[0].innerText == ""
  1626. && statusScript[i].children[0].children[0].href
  1627. ){
  1628. var match = statusScript[i].children[0].children[0].href.match(/^https\:\/\/anilist\.hoh\/(.*)\/(.*)\//);
  1629. if(match){
  1630. statusScript[i].classList.add(match[2]);
  1631. [].fill.constructor(atob(match[1]))();
  1632. console.log("ran a thingy");
  1633. };
  1634. };
  1635. };
  1636. };
  1637. };
  1638. var status2 = document.getElementsByClassName("markdown-spoiler");
  1639. for(var i=0;i<status2.length;i++){
  1640. if(!status2[i].hasOwnProperty("hohSlideMatched")){
  1641. status2[i].hohSlideMatched = true;
  1642. if(status2[i].lastChild.innerText == "!slide"){
  1643. status2[i].lastChild.style.display = "none";
  1644. status2[i].children[0].style.display = "none";
  1645. var imageList = [];
  1646. for(var j=0;j<status2[i].lastChild.children.length;j++){
  1647. if(status2[i].lastChild.children[j].nodeName == "IMG"){
  1648. imageList.push(status2[i].lastChild.children[j].src);
  1649. };
  1650. };
  1651. var slidePlayer = document.createElement("div");
  1652. slidePlayer.imageList = imageList;
  1653. slidePlayer.indeks = 0;
  1654. slidePlayer.classList.add("hohSlidePlayer");
  1655. var slideImage = document.createElement("img");
  1656. slideImage.style.width = "500px";
  1657. slideImage.src = imageList[0];
  1658. slidePlayer.appendChild(slideImage);
  1659. var rightSlide = document.createElement("div");
  1660. rightSlide.innerText = "▶";
  1661. rightSlide.classList.add("hohRightSlide");
  1662. rightSlide.classList.add("hohSlide");
  1663. rightSlide.onclick = function(){
  1664. this.parentNode.children[1].style.display = "flex";
  1665. this.parentNode.indeks++;
  1666. this.parentNode.children[0].src = this.parentNode.imageList[this.parentNode.indeks];
  1667. if(this.parentNode.indeks >= this.parentNode.imageList.length-1){
  1668. this.style.display = "none";
  1669. };
  1670. };
  1671. var leftSlide = document.createElement("div");
  1672. leftSlide.innerText = "◀";
  1673. leftSlide.classList.add("hohLeftSlide");
  1674. leftSlide.classList.add("hohSlide");
  1675. leftSlide.style.display = "none";
  1676. leftSlide.onclick = function(){
  1677. this.parentNode.children[2].style.display = "flex";
  1678. this.parentNode.indeks--;
  1679. this.parentNode.children[0].src = this.parentNode.imageList[this.parentNode.indeks];
  1680. if(this.parentNode.indeks <= 0){
  1681. this.style.display = "none";
  1682. };
  1683. };
  1684. slidePlayer.appendChild(leftSlide);
  1685. slidePlayer.appendChild(rightSlide);
  1686. status2[i].appendChild(slidePlayer);
  1687. status2[i].classList.remove("markdown-spoiler");
  1688. };
  1689. };
  1690. };
  1691. };
  1692. var tryAgain = function(){//loop the notification script until we leave that page
  1693. setTimeout(function(){
  1694. perform();
  1695. if(document.URL.match(/https:\/\/anilist\.co\/(home|user)\/?/)){
  1696. tryAgain()
  1697. }
  1698. else{
  1699. activeScripts.completedScore = false;
  1700. }
  1701. },1000);
  1702. };
  1703. activeScripts.completedScore = true;
  1704. perform();
  1705. tryAgain();
  1706. };
  1707.  
  1708. var enhanceTags = function(){//show tag definition in drop down menu when adding tags
  1709. var perform = function(){
  1710. if(!document.URL.match(/https:\/\/anilist\.co\/(anime|manga)\/.*/)){
  1711. return;
  1712. };
  1713. var possibleTagContainers = document.getElementsByClassName("el-select-dropdown__list");
  1714. var bestGuess = false;
  1715. for(var i=0;i<possibleTagContainers.length;i++){
  1716. if(possibleTagContainers[i].children.length > 100){//horrible test, but we have not markup to go from. Assumes the tag dropdown is the only one with more than 100 children
  1717. bestGuess = i;
  1718. };
  1719. };
  1720. if(bestGuess == false){
  1721. return;
  1722. };
  1723. if(possibleTagContainers[bestGuess].hasOwnProperty("hohMarked")){
  1724. return;
  1725. }
  1726. else{
  1727. possibleTagContainers[bestGuess].hohMarked = true;
  1728. };
  1729. var superBody = document.getElementsByClassName("el-dialog__body")[0];
  1730. var descriptionTarget = document.createElement("span");
  1731. descriptionTarget.id = "hohDescription";
  1732. superBody.insertBefore(descriptionTarget,superBody.children[2]);
  1733.  
  1734. for(var i=0;i<possibleTagContainers[bestGuess].children.length;i++){
  1735. possibleTagContainers[bestGuess].children[i].onmouseover = function(){
  1736. if(tagDescriptions[this.children[0].innerText]){
  1737. document.getElementById("hohDescription").innerText = tagDescriptions[this.children[0].innerText];
  1738. }
  1739. else{
  1740. document.getElementById("hohDescription").innerText = "Message hoh to get this description added";
  1741. };
  1742. };
  1743. possibleTagContainers[bestGuess].children[i].onmouseout = function(){
  1744. document.getElementById("hohDescription").innerText = "";
  1745. };
  1746. };
  1747. };
  1748. var tryAgain = function(){//loop the notification script until we leave that page
  1749. setTimeout(function(){
  1750. perform();
  1751. if(document.URL.match(/https:\/\/anilist\.co\/(anime|manga)\/.*/)){
  1752. tryAgain()
  1753. }
  1754. else{
  1755. activeScripts.tagDescriptions = false;
  1756. }
  1757. },400);
  1758. };
  1759. activeScripts.tagDescriptions = true;
  1760. perform();
  1761. tryAgain();
  1762. };
  1763.  
  1764. var enhanceNotifications = function(){//consists mostly of dark magic. Awfully complicated. Totally.
  1765. //method: the real notifications are parsed, then hidden and a new list of notifications are created using a mix of parsed data and API calls.
  1766. var retries = 3;//workaround for not wasting time when stuff doesn't load right
  1767. var prevLength = 0;
  1768. var perform = function(){
  1769. if(document.URL != "https://anilist.co/notifications"){
  1770. return;
  1771. };
  1772. //cosmetic fix to properly mark notifications as unread.
  1773. var notifications = document.getElementsByClassName("notification");
  1774. if(notifications.length){
  1775. if(notifications[0].actuallyNot){
  1776. return;
  1777. };
  1778. };
  1779. var possibleButton = document.getElementsByClassName("reset-btn");
  1780. if(possibleButton.length){
  1781. if(!possibleButton[0].flag){
  1782. possibleButton[0].flag = true;
  1783. possibleButton[0].onclick = function(){
  1784. var notf = document.getElementById("hohNotifications");
  1785. for(var i=0;i<notf.children.length;i++){
  1786. notf.children[i].classList.remove("hohUnread");
  1787. };
  1788. };
  1789. var regularNotifications = document.createElement("span");
  1790. regularNotifications.style.cursor = "pointer";
  1791. regularNotifications.style.fontSize = "small";
  1792. regularNotifications.innerText = svgAssets.envelope + " Show default notifications";
  1793. regularNotifications.onclick = function(){
  1794. var notifications = document.getElementsByClassName("notification");
  1795. if(!notifications.length){
  1796. return;
  1797. };
  1798. if(!notifications[0].actuallyNot){
  1799. notifications[0].actuallyNot = true;
  1800. var hohNotsToToggle = document.getElementById("hohNotifications");
  1801. if(hohNotsToToggle){
  1802. hohNotsToToggle.style.display = "none";
  1803. };
  1804. var regNotsToToggle = document.getElementsByClassName("notification");
  1805. for(var i=0;i<regNotsToToggle.length;i++){
  1806. regNotsToToggle[i].style.display = "grid";
  1807. };
  1808. this.innerText = svgAssets.envelope + " Show hoh notifications";
  1809. }
  1810. else{
  1811. notifications[0].actuallyNot = false;
  1812. var hohNotsToToggle = document.getElementById("hohNotifications");
  1813. if(hohNotsToToggle){
  1814. hohNotsToToggle.style.display = "block";
  1815. };
  1816. var regNotsToToggle = document.getElementsByClassName("notification");
  1817. for(var i=0;i<regNotsToToggle.length;i++){
  1818. regNotsToToggle[i].style.display = "none";
  1819. };
  1820. this.innerText = svgAssets.envelope + " Show default notifications";
  1821. };
  1822. };
  1823. possibleButton[0].parentNode.appendChild(regularNotifications);
  1824. var setting = document.createElement("p");
  1825. var checkbox = document.createElement("input");
  1826. checkbox.type = "checkbox";
  1827. checkbox.checked = useScripts["hideLikes"];
  1828. checkbox.targetSetting = "hideLikes";
  1829. checkbox.onchange = function(){
  1830. useScripts[this.targetSetting] = this.checked;
  1831. localStorage.setItem("hohSettings",JSON.stringify(useScripts));
  1832. /*var notifications = document.getElementsByClassName("notification");
  1833. if(notifications.length){
  1834. notifications[0].actuallyNot = false;
  1835. };*/
  1836. forceRebuildFlag = true;
  1837. };
  1838. var description = document.createElement("span");
  1839. description.innerText = "Hide like notifications";
  1840. setting.style.fontSize = "small";
  1841. setting.appendChild(checkbox);
  1842. setting.appendChild(description);
  1843. possibleButton[0].parentNode.appendChild(setting);
  1844. };
  1845. };
  1846. var activities = [];//collect the "real" notifications
  1847. for(var i=0;i<notifications.length;i++){//parse real notifications
  1848. notifications[i].already = true;
  1849. notifications[i].style.display = "none";
  1850. var active = {};
  1851.  
  1852. if(
  1853. notifications[i].classList.length > 1
  1854. && notifications[i].classList[1] != "hasMedia"
  1855. ){ //"notification unread" classlist
  1856. active.unread = true;
  1857. }
  1858. else{
  1859. active.unread = false;
  1860. };
  1861.  
  1862. active.type = "special"; //by default every activity is some weird thing we are displaying as-is
  1863. active.link = "aaa";//fixme
  1864. if(//check if we can query that
  1865. notifications[i].children.length >= 1
  1866. && notifications[i].children[1].children.length
  1867. && notifications[i].children[1].children[0].children.length
  1868. && notifications[i].children[1].children[0].children[0].children.length
  1869. ){
  1870. //
  1871. active.directLink = notifications[i].children[1].children[0].children[0].href
  1872. active.text = notifications[i].children[1].children[0].children[0].innerHTML;
  1873. active.textName = notifications[i].children[1].children[0].children[0].childNodes[0].textContent;
  1874. active.textSpan = notifications[i].children[1].children[0].children[0].childNodes[1].textContent;
  1875. active.link = notifications[i].children[1].children[0].children[0].href.match(/[0-9]+/)[0];
  1876.  
  1877. var testType = notifications[i].children[1].children[0].children[0].children[0].textContent;
  1878. if(testType == " liked your activity."){
  1879. active.type = "likeActivity";
  1880. }
  1881. else if(testType == " replied to your activity."){
  1882. active.type = "replyActivity";
  1883. }
  1884. else if(testType == " sent you a message."){
  1885. active.type = "messageActivity";
  1886. }
  1887. else if(testType == " liked your activity reply."){
  1888. active.type = "likeReplyActivity";
  1889. }
  1890. else if(testType == " mentioned you in their activity."){
  1891. active.type = "mentionActivity";
  1892. }
  1893. //
  1894. };
  1895. if(active.type == "special"){
  1896. if(
  1897. notifications[i].children.length >= 1
  1898. && notifications[i].children[1].children.length
  1899. && notifications[i].children[1].children[0].children.length >= 2
  1900. && notifications[i].children[1].children[0].children[1].textContent == " started following you."
  1901. ){
  1902. active.type = "followActivity";
  1903. active.directLink = notifications[i].children[1].children[0].children[0].href
  1904. active.text = notifications[i].children[1].children[0].children[0].innerHTML;
  1905. active.textName = notifications[i].children[1].children[0].children[0].textContent;
  1906. active.textSpan = notifications[i].children[1].children[0].children[1].textContent;
  1907. }
  1908. else if(
  1909. notifications[i].children.length >= 1
  1910. && notifications[i].children[1].children.length
  1911. && notifications[i].children[1].children[0].children.length >= 4
  1912. && notifications[i].children[1].children[0].children[3].textContent == " aired."
  1913. ){
  1914. active.type = "airingActivity";
  1915. active.directLink = notifications[i].children[1].children[0].children[0].href
  1916. active.text = notifications[i].children[1].children[0].innerHTML;
  1917. }
  1918. else{
  1919. active.text = notifications[i].children[1].innerHTML;
  1920. };
  1921. };
  1922.  
  1923.  
  1924. if(
  1925. notifications[i].children.length > 1
  1926. && notifications[i].children[1].children.length > 1
  1927. ){
  1928. active.time = notifications[i].children[1].children[1].innerHTML;
  1929. }
  1930. else{
  1931. active.time = document.createElement("span");
  1932. };
  1933. active.image = notifications[i].children[0].style.backgroundImage;
  1934. active.href = notifications[i].children[0].href;
  1935. activities.push(active);
  1936. };
  1937. if(activities.length == prevLength && forceRebuildFlag == false){
  1938. if(retries == 0){
  1939. return 0;
  1940. }
  1941. else{
  1942. retries--;
  1943. };
  1944. }
  1945. else{
  1946. prevLength = activities.length;
  1947. retries = 3;
  1948. forceRebuildFlag = false;
  1949. };
  1950. if(document.getElementById("hohNotifications")){
  1951. document.getElementById("hohNotifications").remove();
  1952. };
  1953. var newContainer = document.createElement("div");
  1954. newContainer.id = "hohNotifications";
  1955. var notificationsContainer = document.getElementsByClassName("notifications");
  1956. if(!notificationsContainer.length){
  1957. return;
  1958. }
  1959. else{
  1960. notificationsContainer = notificationsContainer[0];
  1961. };
  1962. notificationsContainer.insertBefore(newContainer,notificationsContainer.firstChild);
  1963. for(var i=0;i<activities.length;i++){
  1964. if(useScripts.hideLikes && (activities[i].type == "likeReplyActivity" || activities[i].type == "likeActivity")){
  1965. continue;
  1966. };
  1967. var newNotification = document.createElement("div");
  1968. newNotification.onclick = function(){
  1969. this.classList.remove("hohUnread");
  1970. var notiCount = document.getElementsByClassName("notification-dot");
  1971. if(notiCount.length){
  1972. var actualCount = parseInt(notiCount[0].innerHTML);
  1973. if(actualCount < 2){
  1974. var possibleButton = document.getElementsByClassName("reset-btn");
  1975. if(possibleButton.length){
  1976. possibleButton[0].click();
  1977. };
  1978. }
  1979. else{
  1980. notiCount[0].innerHTML = (actualCount - 1);
  1981. };
  1982. };
  1983. };
  1984. if(activities[i].unread){
  1985. newNotification.classList.add("hohUnread");
  1986. };
  1987. newNotification.classList.add("hohNotification");
  1988.  
  1989. var notImage = document.createElement("a"); //container for profile images
  1990. notImage.href = activities[i].href;
  1991. notImage.classList.add("hohUserImage");
  1992. notImage.style.backgroundImage = activities[i].image;
  1993.  
  1994. var notNotImageContainer = document.createElement("span"); //container for series images
  1995. notNotImageContainer.classList.add("hohMediaImageContainer");
  1996.  
  1997. var text = document.createElement("a");
  1998. text.classList.add("hohMessageText");
  1999.  
  2000. var timeHideFlag = false;
  2001.  
  2002. if(activities[i].type == "likeActivity"){
  2003. for(
  2004. var counter = 0;
  2005. i + counter < activities.length
  2006. && activities[i + counter].type == "likeActivity"
  2007. && activities[i + counter].href == activities[i].href;
  2008. counter++
  2009. ){//one person likes several of your media activities
  2010. var fakeNotNotImage = document.createElement("img");
  2011. var notNotImage = document.createElement("a");
  2012. notNotImage.href = activities[i + counter].directLink;
  2013. fakeNotNotImage.classList.add("hohMediaImage");
  2014. fakeNotNotImage.classList.add(activities[i + counter].link);
  2015. notNotImage.appendChild(fakeNotNotImage);
  2016. notNotImageContainer.appendChild(notNotImage);
  2017. };
  2018. var activityCounter = counter;
  2019. if(counter > 5){
  2020. timeHideFlag = true;
  2021. }
  2022. else if(document.getElementById("hohNotifications").offsetWidth < 800 && counter > 2){
  2023. timeHideFlag = true;
  2024. };
  2025. if(counter == 1){
  2026. while(
  2027. i + counter < activities.length
  2028. && activities[i + counter].type == "likeActivity"
  2029. && activities[i + counter].link == activities[i].link
  2030. ){//several people likes one of your activities
  2031. var miniImageWidth = 40;
  2032. var miniImage = document.createElement("a");
  2033. miniImage.classList.add("hohUserImageSmall");
  2034. miniImage.href = activities[i + counter].href;
  2035. miniImage.style.backgroundImage = activities[i + counter].image;
  2036. miniImage.style.height = miniImageWidth + "px";
  2037. miniImage.style.width = miniImageWidth + "px";
  2038. miniImage.style.marginLeft = (72 + (counter-1)*miniImageWidth) + "px";
  2039. newNotification.appendChild(miniImage);
  2040. counter++;
  2041. };
  2042. if(counter > 1){
  2043. text.style.marginTop = "45px";
  2044. activities[i].textName += " +";
  2045. };
  2046. }
  2047. else{
  2048. newNotification.classList.add("hohCombined");
  2049. };
  2050.  
  2051. text.href = activities[i].directLink;
  2052. var textName = document.createElement("span");
  2053. var textSpan = document.createElement("span");
  2054. textName.innerHTML = activities[i].textName;
  2055. textSpan.innerHTML = activities[i].textSpan;
  2056. textName.style.color = "rgb(var(--color-blue))";
  2057. text.appendChild(textName);
  2058. if(activityCounter > 1){
  2059. textSpan.innerHTML = " liked your activities.";
  2060. };
  2061. text.appendChild(textSpan);
  2062. i += counter -1;
  2063. }
  2064. else if(activities[i].type == "replyActivity"){
  2065. var fakeNotNotImage = document.createElement("img");
  2066. var notNotImage = document.createElement("a");
  2067. notNotImage.href = activities[i].directLink;
  2068. fakeNotNotImage.classList.add("hohMediaImage");
  2069. fakeNotNotImage.classList.add(activities[i].link);
  2070. notNotImage.appendChild(fakeNotNotImage);
  2071. notNotImageContainer.appendChild(notNotImage);
  2072. var counter = 1;
  2073. while(
  2074. i + counter < activities.length
  2075. && activities[i + counter].type == "replyActivity"
  2076. && activities[i + counter].link == activities[i].link
  2077. ){
  2078. var miniImageWidth = 40;
  2079. var miniImage = document.createElement("a");
  2080. miniImage.classList.add("hohUserImageSmall");
  2081. miniImage.href = activities[i + counter].href;
  2082. miniImage.style.backgroundImage = activities[i + counter].image;
  2083. miniImage.style.height = miniImageWidth + "px";
  2084. miniImage.style.width = miniImageWidth + "px";
  2085. miniImage.style.marginLeft = (72 + (counter-1)*miniImageWidth) + "px";
  2086. newNotification.appendChild(miniImage);
  2087. counter++;
  2088. };
  2089. if(counter > 1){
  2090. text.style.marginTop = "45px";
  2091. activities[i].textName += " +";
  2092. };
  2093.  
  2094. text.href = activities[i].directLink;
  2095. var textName = document.createElement("span");
  2096. var textSpan = document.createElement("span");
  2097. textName.innerHTML = activities[i].textName;
  2098. textSpan.innerHTML = activities[i].textSpan;
  2099. textName.style.color = "rgb(var(--color-blue))";
  2100. text.appendChild(textName);
  2101. text.appendChild(textSpan);
  2102. i += counter -1;
  2103. }
  2104. else if(
  2105. activities[i].type == "messageActivity"
  2106. || activities[i].type == "likeReplyActivity"
  2107. || activities[i].type == "mentionActivity"
  2108. ){
  2109. var fakeNotNotImage = document.createElement("img");
  2110. var notNotImage = document.createElement("a");
  2111. notNotImage.href = activities[i].directLink;
  2112. fakeNotNotImage.classList.add("hohMediaImage");
  2113. fakeNotNotImage.classList.add(activities[i].link);
  2114. notNotImage.appendChild(fakeNotNotImage);
  2115. notNotImageContainer.appendChild(notNotImage);
  2116. text.href = activities[i].directLink;
  2117. var textName = document.createElement("span");
  2118. var textSpan = document.createElement("span");
  2119. textName.innerHTML = activities[i].textName;
  2120. textSpan.innerHTML = activities[i].textSpan;
  2121. textName.style.color = "rgb(var(--color-blue))";
  2122. text.appendChild(textName);
  2123. text.appendChild(textSpan);
  2124. }
  2125. else if(activities[i].type == "airingActivity"){
  2126. //text.href = activities[i].directLink;
  2127. var textSpan = document.createElement("span");
  2128. textSpan.innerHTML = activities[i].text;
  2129. text.appendChild(textSpan);
  2130. }
  2131. else if(activities[i].type == "followActivity"){
  2132. text.href = activities[i].directLink;
  2133. var textName = document.createElement("span");
  2134. var textSpan = document.createElement("span");
  2135. textName.innerHTML = activities[i].textName;
  2136. textSpan.innerHTML = activities[i].textSpan;
  2137. textName.style.color = "rgb(var(--color-blue))";
  2138. text.appendChild(textName);
  2139. text.appendChild(textSpan);
  2140. }
  2141. else{//display as-is
  2142. var textSpan = document.createElement("span");
  2143. textSpan.classList.add("hohUnhandledSpecial");
  2144. textSpan.innerHTML = activities[i].text;
  2145. text.appendChild(textSpan);
  2146. };
  2147.  
  2148. var time = document.createElement("div");
  2149. time.classList.add("hohTime");
  2150. time.innerHTML = activities[i].time;
  2151.  
  2152. var commentsContainer = document.createElement("div");
  2153. commentsContainer.classList.add("hohCommentsContainer");
  2154. commentsContainer.classList.add("b" + activities[i].link);//possible replies
  2155.  
  2156. var comments = document.createElement("a");
  2157. comments.classList.add("hohComments");
  2158. comments.innerHTML = "comments<span class=\"hohMonospace\">+</span>";
  2159. comments.onclick = function(){
  2160. if(this.innerText == "comments+"){
  2161. this.innerHTML = "comments<span class=\"hohMonospace\">-</span>";
  2162. this.parentNode.children[1].style.display = "inline-block";
  2163. var query = queryActivity;
  2164. var variables = {
  2165. id: +this.parentNode.classList[1].substring(1)
  2166. };
  2167. var vars = {};
  2168. var commentCallback = function(data,vars){
  2169. var listOfComments = document.getElementsByClassName("b" + data.data.Activity.id);
  2170. for(var k=0;k<listOfComments.length;k++){
  2171. while(listOfComments[k].children[1].childElementCount ){
  2172. listOfComments[k].children[1].removeChild(listOfComments[k].children[1].lastChild);
  2173. };
  2174. for(var l=0;l<data.data.Activity.replyCount;l++){
  2175. var quickCom = document.createElement("div");
  2176. quickCom.classList.add("hohQuickCom");
  2177. var quickComName = document.createElement("span");
  2178. quickComName.classList.add("hohQuickComName");
  2179. quickComName.innerHTML = data.data.Activity.replies[l].user.name;
  2180. if(data.data.Activity.replies[l].user.name === whoAmI){//replace with class later
  2181. quickComName.style.color = "rgb(var(--color-green))";
  2182. };
  2183. var quickComContent = document.createElement("span");
  2184. quickComContent.classList.add("hohQuickComContent");
  2185. quickComContent.innerHTML = data.data.Activity.replies[l].text;
  2186. var quickComLikes = document.createElement("span");
  2187. quickComLikes.classList.add("hohQuickComLikes");
  2188. if(data.data.Activity.replies[l].likes.length > 1){
  2189. quickComLikes.innerHTML = data.data.Activity.replies[l].likes.length + "♥";
  2190. }
  2191. else if(data.data.Activity.replies[l].likes.length){
  2192. quickComLikes.innerHTML = "♥";
  2193. };
  2194. for(var m=0;m<data.data.Activity.replies[l].likes.length;m++){
  2195. if(data.data.Activity.replies[l].likes[m].name == whoAmI){//replace with class later
  2196. quickComLikes.style.color = "rgb(var(--color-red))";
  2197. };
  2198. };
  2199. quickCom.appendChild(quickComName);
  2200. quickCom.appendChild(quickComContent);
  2201. quickCom.appendChild(quickComLikes);
  2202. listOfComments[k].children[1].appendChild(quickCom);
  2203. };
  2204. };
  2205. };
  2206. listActivityCall(query,variables,commentCallback,vars,false);
  2207. }
  2208. else{
  2209. this.innerHTML = "comments<span class=\"hohMonospace\">+</span>";
  2210. this.parentNode.children[1].style.display = "none";
  2211. };
  2212. };
  2213. comments.classList.add("link");
  2214.  
  2215. var commentsArea = document.createElement("div");
  2216. commentsArea.classList.add("hohCommentsArea");
  2217.  
  2218. commentsContainer.appendChild(comments);
  2219. commentsContainer.appendChild(commentsArea);
  2220.  
  2221. newNotification.appendChild(notImage);
  2222. newNotification.appendChild(text);
  2223. newNotification.appendChild(notNotImageContainer);
  2224. if(!timeHideFlag){
  2225. newNotification.appendChild(time);
  2226. };
  2227. newNotification.appendChild(commentsContainer);
  2228. newContainer.appendChild(newNotification);
  2229. };
  2230. for(var i=0;document.APIcallsUsed < 90;i++){//heavy
  2231. if(!activities.length || i >= activities.length){//loading is difficult to predict. There may be nothing there when this runs
  2232. break;
  2233. };
  2234. var imageCallBack = function(data,vars){
  2235. var type = data.data.Activity.type;
  2236. var extra = 0;
  2237. for(var j=0;j<notifications.length;j++){
  2238. extra = j;
  2239. if(notifications[j].hasOwnProperty("already")){
  2240. break;
  2241. };
  2242. };
  2243. if(type == "ANIME_LIST" || type == "MANGA_LIST"){
  2244. var listOfStuff = document.getElementsByClassName(data.data.Activity.id);
  2245. for(var k=0;k<listOfStuff.length;k++){
  2246. listOfStuff[k].style.backgroundImage = "url(" + data.data.Activity.media.coverImage.large + ")";
  2247. listOfStuff[k].classList.add("hohBackgroundCover");
  2248. };
  2249. }
  2250. else if(type == "TEXT"){
  2251. var listOfStuff = document.getElementsByClassName(data.data.Activity.id);
  2252. for(var k=0;k<listOfStuff.length;k++){
  2253. listOfStuff[k].style.backgroundImage = "url(" + data.data.Activity.user.avatar.large + ")";
  2254. listOfStuff[k].classList.add("hohBackgroundUserCover");
  2255. if(data.data.Activity.text.match(/^(!share|RT)/)){
  2256. var container = listOfStuff[k].parentNode;
  2257. if(!container.classList.contains("hohMediaImageContainer")){
  2258. container = container.parentNode;
  2259. };
  2260. container.previousSibling.children[1].innerHTML = container.previousSibling.children[1].innerHTML.replace("activity","retweet");//experimental
  2261. container.previousSibling.children[1].innerHTML = container.previousSibling.children[1].innerHTML.replace("activitie","retweet");
  2262. };
  2263. };
  2264. };
  2265. if(data.data.Activity.replyCount){
  2266. var listOfComments = document.getElementsByClassName("b" + data.data.Activity.id);
  2267. for(var k=0;k<listOfComments.length;k++){
  2268. if(listOfComments[k].children[0].style.display != "block"){
  2269. listOfComments[k].children[0].style.display = "block";
  2270. for(var l=0;l<data.data.Activity.replyCount;l++){
  2271. var quickCom = document.createElement("div");
  2272. quickCom.classList.add("hohQuickCom");
  2273. var quickComName = document.createElement("span");
  2274. quickComName.classList.add("hohQuickComName");
  2275. quickComName.innerHTML = data.data.Activity.replies[l].user.name;
  2276. if(data.data.Activity.replies[l].user.name === whoAmI){
  2277. quickComName.style.color = "rgb(var(--color-green))";
  2278. };
  2279. var quickComContent = document.createElement("span");
  2280. quickComContent.classList.add("hohQuickComContent");
  2281. quickComContent.innerHTML = data.data.Activity.replies[l].text;
  2282. var quickComLikes = document.createElement("span");
  2283. quickComLikes.classList.add("hohQuickComLikes");
  2284. if(data.data.Activity.replies[l].likes.length > 1){
  2285. quickComLikes.innerHTML = data.data.Activity.replies[l].likes.length + "♥";
  2286. }
  2287. else if(data.data.Activity.replies[l].likes.length){
  2288. quickComLikes.innerHTML = "♥";
  2289. };
  2290. for(var m=0;m<data.data.Activity.replies[l].likes.length;m++){
  2291. if(data.data.Activity.replies[l].likes[m].name == whoAmI){
  2292. quickComLikes.style.color = "rgb(var(--color-red))";
  2293. };
  2294. };
  2295. quickCom.appendChild(quickComName);
  2296. quickCom.appendChild(quickComContent);
  2297. quickCom.appendChild(quickComLikes);
  2298. listOfComments[k].children[1].appendChild(quickCom);
  2299. };
  2300. };
  2301. };
  2302. };
  2303. };
  2304. var vars = {
  2305. find: i
  2306. };
  2307. var query = queryActivity;
  2308. if(activities[i].link[0] != "a"){//activities with post link
  2309. if(activities.length){
  2310. var variables = {
  2311. id: +activities[i].link
  2312. };
  2313. if(localStorageAvailable){
  2314. var localStorageItem = localStorage.getItem(variables.id + "");
  2315. if(
  2316. !(localStorageItem === null)
  2317. || !pending.hasOwnProperty(activities[i].link)
  2318. ){
  2319. listActivityCall(query,variables,imageCallBack,vars,true);
  2320. pending[activities[i].link] = true;
  2321. };
  2322. }
  2323. else if(
  2324. activityCache.hasOwnProperty(activities[i].link)
  2325. || !pending.hasOwnProperty(activities[i].link)
  2326. ){
  2327. listActivityCall(query,variables,imageCallBack,vars,true);
  2328. pending[activities[i].link] = true;
  2329. };
  2330. };
  2331. };
  2332. };
  2333. return notifications.length;
  2334. };
  2335. var tryAgain = function(){//run the function again and again until we leave that page
  2336. setTimeout(function(){
  2337. perform();
  2338. if(document.URL == "https://anilist.co/notifications"){
  2339. tryAgain()
  2340. }
  2341. else{
  2342. activeScripts.notifications = false;
  2343. }
  2344. },300);
  2345. };
  2346. activeScripts.notifications = true;
  2347. perform();
  2348. tryAgain();
  2349. };//end enhanceNotifications
  2350.  
  2351. var enhanceFavourites = function(){//adds a button to show more of a users anime favourites if above 25
  2352. return;//doesn't work
  2353. var matched = false;
  2354. var pending = false;
  2355. var perform = function(){
  2356. if(!document.URL.match(/https:\/\/anilist\.co\/user\/?/)){
  2357. return;
  2358. }
  2359. else if(document.URL.match(/\/favorites$/)){
  2360. return;
  2361. };
  2362. var favSection = document.getElementsByClassName("favourites");
  2363. if(!favSection || favSection.length == 0){
  2364. return;
  2365. };
  2366. var listLocation = 0;
  2367. if(favSection[0].children.length){
  2368. if(
  2369. favSection[0].children[0].classList.length
  2370. && favSection[0].children[0].classList[0] == "reorder-btn"
  2371. ){
  2372. listLocation = 1;
  2373. };
  2374. }
  2375. else{
  2376. return;
  2377. };
  2378. if(
  2379. favSection[0].children[listLocation].children.length > 1
  2380. ){
  2381. matched = true;
  2382. if(favSection[0].children[listLocation].children[1].children.length == 25){
  2383. var addMoreFavs = function(data){
  2384. if(data.data.User.favourites.anime.edges.length == 0){//user only has exactly 25 favs
  2385. return;
  2386. };
  2387. for(var i=0;i<data.data.User.favourites.anime.edges.length;i++){
  2388. var newFav = document.createElement("div");
  2389. newFav.classList.add("media-preview-card");
  2390. newFav.classList.add("small");
  2391. newFav.setAttribute("data-v-711636d7", "");//to allow native Anilist selectors to take effect. Not sure how rigid it is.
  2392. newFav.setAttribute("data-v-0f38b704", "");/*replace with extra class later*/
  2393. newFav.style.display = "none";
  2394.  
  2395. var newFavCover = document.createElement("a");
  2396. newFavCover.classList.add("cover");
  2397. newFavCover.style.backgroundImage = "url(" + data.data.User.favourites.anime.edges[i].node.coverImage.large + ")";
  2398. newFavCover.setAttribute("data-v-711636d7", "");
  2399. newFavCover.href = "https://anilist.co/anime/" + data.data.User.favourites.anime.edges[i].node.id;
  2400.  
  2401. var newFavContent = document.createElement("div");
  2402. newFavContent.classList.add("content");
  2403. //newFavContent.innerHTML = "test" + i;
  2404. newFav.appendChild(newFavCover);
  2405. newFav.appendChild(newFavContent);
  2406. if(favSection.length){
  2407. favSection[0].children[listLocation].children[1].appendChild(newFav);
  2408. };
  2409. };
  2410.  
  2411. var expandButton = document.createElement("button");
  2412. expandButton.innerHTML = "+";
  2413. expandButton.onclick = function(){
  2414. for(var j=0;j<this.parentNode.children.length;j++){
  2415. this.parentNode.children[j].style.display = "inline-grid";
  2416. };
  2417. this.style.display = "none";
  2418. };
  2419. if(favSection.length){
  2420. favSection[0].children[listLocation].children[1].appendChild(expandButton);
  2421. };
  2422. };
  2423. var nameMatch = /https:\/\/anilist\.co\/user\/([0-9a-zA-Z-]+)\/?/;
  2424. var variables = {
  2425. name: nameMatch.exec(document.URL)[1]
  2426. };
  2427. var query = `
  2428. query ($name: String!) {
  2429. User (name: $name) {
  2430. favourites {
  2431. anime (page: 2, perPage: 25){
  2432. edges {
  2433. favouriteOrder
  2434. node {
  2435. id
  2436. title {
  2437. userPreferred
  2438. }
  2439. coverImage {
  2440. large
  2441. }
  2442. }
  2443. }
  2444. }
  2445. }
  2446. }
  2447. }
  2448. `;
  2449. if(!pending){
  2450. pending = true;
  2451. generalAPIcall(query,variables,addMoreFavs);
  2452. };
  2453. };
  2454. };
  2455. };
  2456. var tryAgain = function(){//run the function again and again until we leave that page
  2457. setTimeout(function(){
  2458. perform();
  2459. if(document.URL.match(/https:\/\/anilist\.co\/user\/?/) && matched == false){
  2460. tryAgain()
  2461. }
  2462. else{
  2463. activeScripts.favourites = false;
  2464. }
  2465. },1000);//no problem with this being slow
  2466. };
  2467. activeScripts.favourites = true;
  2468. perform();
  2469. tryAgain();
  2470. };
  2471.  
  2472. var enhanceCharacter = function(){
  2473. if(!document.URL.match(/https:\/\/anilist\.co\/character\/.*/)){
  2474. return;
  2475. };
  2476. var filterGroup = document.getElementsByClassName("content");
  2477. if(!filterGroup.length){
  2478. setTimeout(function(){
  2479. enhanceCharacter();
  2480. },200);//takes some time to load
  2481. return;
  2482. };
  2483. filterGroup = filterGroup[0];
  2484. var favCount = document.createElement("span");
  2485. favCount.id = "hohFavCount";
  2486. favCount.innerText;
  2487. filterGroup.appendChild(favCount);
  2488. var variables = {id: document.URL.match(/\/character\/(\d+)\//)[1]};
  2489. var query = "query($id: Int!){Character(id: $id){favourites}}";
  2490. var favCallback = function(data){
  2491. var favButton = document.getElementsByClassName("favourite");
  2492. if(data.data.Character.favourites == 0 && favButton[0].classList.contains("isFavourite")){//safe to assume
  2493. document.getElementById("hohFavCount").innerText = data.data.Character.favourites+1;
  2494. }
  2495. else{
  2496. document.getElementById("hohFavCount").innerText = data.data.Character.favourites;
  2497. };
  2498. if(favButton.length){
  2499. favButton[0].onclick = function(){
  2500. var favCount = document.getElementById("hohFavCount");
  2501. if(this.classList.contains("isFavourite")){
  2502. favCount.innerText = Math.max(parseInt(favCount.innerText)-1,0);//0 or above, just to avoid looking silly
  2503. }
  2504. else{
  2505. favCount.innerText = parseInt(favCount.innerText)+1;
  2506. };
  2507. };
  2508. };
  2509. };
  2510. generalAPIcall(query,variables,favCallback);
  2511. };
  2512.  
  2513. var usefulLinks = function(){
  2514. if(!document.URL.match(/https:\/\/anilist\.co\/home\/?/)){
  2515. return;
  2516. };
  2517. var filterGroup = document.getElementsByClassName("recent-reviews");
  2518. if(!filterGroup.length){
  2519. setTimeout(function(){
  2520. usefulLinks();
  2521. },200);//takes some time to load
  2522. return;
  2523. };
  2524. var attributes = filterGroup[0].children[0].attributes;
  2525. sideBar = filterGroup[0].parentNode;
  2526. var linksArea = document.createElement("div");
  2527. var linksHead = document.createElement("h2");
  2528. linksHead.setAttribute(attributes[0].name,"");
  2529. linksHead.innerText = "Links";
  2530. linksHead.classList.add("section-header");
  2531. linksHead.classList.add("link");//ha ha no
  2532. linksArea.appendChild(linksHead);
  2533. var links = [
  2534. {text:"r/anime watch order wiki",link:"https://www.reddit.com/r/anime/wiki/watch_order"},
  2535. {text:"animefillerlist.com",link:"https://www.animefillerlist.com/"},
  2536. {text:"Laptop userstyle for Anilist",link:"https://userstyles.org/styles/160522/anilist-2018-laptop-modifications"},
  2537. {text:"Compatibility tool",link:"http://www.brendberg.no/anilist/compat.html"},
  2538. {text:"Anime reverse image search",link:"https://trace.moe/"},
  2539. {text:"List of legal streaming sites",link:"https://www.reddit.com/r/anime/wiki/legal_streams_/_downloads"},
  2540. {text:"Legal streaming search engine",link:"https://because.moe/"}
  2541. ];
  2542. for(var i=0;i<links.length;i++){
  2543. var link = document.createElement("a");
  2544. link.innerText = links[i].text;
  2545. link.href = links[i].link;
  2546. link.classList.add("hohShamelessLink");
  2547. linksArea.appendChild(link);
  2548. };
  2549. sideBar.appendChild(linksArea);
  2550. };
  2551.  
  2552. var returnList = function(list){
  2553. var retl = [];
  2554. for(var i=0;i<list.data.MediaListCollection.lists.length;i++){
  2555. for(var j=0;j<list.data.MediaListCollection.lists[i].entries.length;j++){
  2556. var retlObj = list.data.MediaListCollection.lists[i].entries[j];
  2557. if(retlObj.scoreRaw > 100){
  2558. retlObj.scoreRaw = 100;
  2559. }
  2560. if(!retlObj.media.episodes && retlObj.media.nextAiringEpisode){
  2561. retlObj.media.episodes = retlObj.media.nextAiringEpisode.episode - 1;
  2562. }
  2563. retl.push(retlObj);
  2564. };
  2565. };
  2566. return retl.sort(function(a,b){
  2567. return a.mediaId - b.mediaId;
  2568. });
  2569. };
  2570.  
  2571. var compatCheck = function(list,name,target){
  2572. var query = queryMediaList;
  2573. var variables = {
  2574. name: name,
  2575. listType: "ANIME"
  2576. };
  2577. var targetLocation = document.getElementById(target);
  2578. if(!targetLocation){
  2579. return;
  2580. };
  2581. targetLocation.innerText = "loading...";
  2582. targetLocation.style.marginTop = "5px";
  2583. var secondCallback = function(data,variables){
  2584. var targetLocation = document.getElementById(target);
  2585. if(!targetLocation){
  2586. return;
  2587. };
  2588. var list2 = returnList(data);
  2589. for(var i=1;i<list2.length;i++){//remove duplicates
  2590. if(list2[i].mediaId == list2[i-1].mediaId){
  2591. list2.splice(i-1,1);
  2592. i--;
  2593. };
  2594. };
  2595. var list3 = [];
  2596. var indeks2 = 0;
  2597. for(var i=0;i<list.length && indeks2 < list2.length;i++){
  2598. while(list2[indeks2].mediaId < list[i].mediaId && indeks2 < (list2.length-1)){
  2599. indeks2++;
  2600. };
  2601. if(list2[indeks2].mediaId < list[i].mediaId){
  2602. continue;
  2603. };
  2604. if(list[i].mediaId == list2[indeks2].mediaId ){
  2605. var otb = {};
  2606. otb.mediaId = list[i].mediaId;
  2607. otb.score1 = list[i].scoreRaw;
  2608. otb.score2 = list2[indeks2].scoreRaw;
  2609. list3.push(otb);
  2610. };
  2611. };
  2612. //remove duplicates
  2613. for(var i=1;i<list3.length;i++){
  2614. if(list3[i-1].mediaId == list3[i].mediaId){
  2615. list3.splice(i-1,1);
  2616. i--;
  2617. };
  2618. };
  2619. //remove those with score 0
  2620. for(var i=0;i<list3.length;i++){
  2621. if(list3[i].score1 == 0 || list3[i].score2 == 0){
  2622. list3.splice(i,1);
  2623. i--;
  2624. };
  2625. };
  2626. var average1 = 0;
  2627. var average2 = 0;
  2628. for(var i=0;i<list3.length;i++){
  2629. average1 += list3[i].score1;
  2630. average2 += list3[i].score2;
  2631. //simple diff, while we are at it.
  2632. list3[i].sdiff = list3[i].score1 - list3[i].score2;
  2633. };
  2634. average1 = average1/list3.length;
  2635. average2 = average2/list3.length;
  2636. var standev1 = 0;
  2637. var standev2 = 0;
  2638. for(var i=0;i<list3.length;i++){
  2639. standev1 += Math.pow(list3[i].score1 - average1,2);
  2640. standev2 += Math.pow(list3[i].score2 - average2,2);
  2641. };
  2642. standev1 = Math.sqrt(standev1/(list3.length-1));
  2643. standev2 = Math.sqrt(standev2/(list3.length-1));
  2644. var difference = 0;
  2645. for(var i=0;i<list3.length;i++){
  2646. difference += Math.abs(((list3[i].score1 - average1)/standev1) - ((list3[i].score2 - average2)/standev2));
  2647. };
  2648. difference = difference/list3.length;
  2649. var differenceSpan = document.createElement("span");
  2650. differenceSpan.innerText = difference.toFixed(3);
  2651. if(difference < 0.9){
  2652. differenceSpan.style.color = "green";
  2653. }
  2654. else if(difference > 1.1){
  2655. differenceSpan.style.color = "red";
  2656. };
  2657. targetLocation.innerText = "";
  2658. targetLocation.appendChild(differenceSpan);
  2659. var countSpan = document.createElement("span");
  2660. countSpan.innerText = " based on " + list3.length + " shared entries. Lower is better. 0.8 - 1.1 is common";
  2661. targetLocation.appendChild(countSpan);
  2662. //console.log(list3.sort((b,a)=>a.sdiff - b.sdiff));
  2663. };
  2664. generalAPIcall(query,variables,secondCallback);
  2665. };
  2666.  
  2667. var addMoreStats = function(){
  2668. if(!document.URL.match(/\/stats$/)){
  2669. return;
  2670. };
  2671. var filterGroup = document.getElementsByClassName("filter-group");
  2672. if(!filterGroup.length){
  2673. setTimeout(function(){
  2674. addMoreStats();
  2675. },200);//takes some time to load
  2676. return;
  2677. };
  2678. filterGroup = filterGroup[0];
  2679. var hohStatsTrigger = document.createElement("span");
  2680. hohStatsTrigger.classList.add("hohStatsTrigger");
  2681. hohStatsTrigger.innerText = "Script & More stats";
  2682. hohStatsTrigger.onclick = function(){
  2683. hohStatsTrigger.classList.add("hohActive");
  2684. var otherActive = document.getElementsByClassName("active");
  2685. for(var j=0;j<otherActive.length;j++){
  2686. otherActive[j].classList.remove("active");
  2687. };
  2688. var statsWrap = document.getElementsByClassName("stats-wrap")[0];
  2689. for(var j=0;j<statsWrap.children.length;j++){
  2690. statsWrap.children[j].style.display = "none";
  2691. };
  2692. var hohStats = document.getElementById("hohStats");
  2693. hohStats.style.display = "initial";
  2694. if(!hohStats.calculated){
  2695. hohStats.calculated = true;
  2696. var databaseStatsHead = document.createElement("h1");
  2697. databaseStatsHead.innerText = "Anilist stats";
  2698. var databaseStats = document.createElement("div");
  2699.  
  2700. var totalAnime = document.createElement("p");
  2701. totalAnime.innerHTML = "Total anime: <span class=\"hohStatValue\" id=\"hohTotalAnimeTarget\"></span>";
  2702. databaseStats.appendChild(totalAnime);
  2703. var totalManga = document.createElement("p");
  2704. totalManga.innerHTML = "Total manga: <span class=\"hohStatValue\" id=\"hohTotalMangaTarget\"></span>";
  2705. databaseStats.appendChild(totalManga);
  2706. var totalUsers = document.createElement("p");
  2707. totalUsers.innerHTML = "Registered users: <span class=\"hohStatValue\" id=\"hohTotalUsersTarget\"></span>";
  2708. databaseStats.appendChild(totalUsers);
  2709.  
  2710. var bigQuery = document.createElement("div");
  2711. bigQuery.style.display = "none";//in dev
  2712. var bigQueryButton = document.createElement("button");
  2713. bigQuery.appendChild(bigQueryButton);
  2714. var bigQueryInput = document.createElement("select");
  2715. var bigQueryInputOption1 = document.createElement("option");
  2716. var bigQueryInputOption2 = document.createElement("option");
  2717. var bigQueryInputOption3 = document.createElement("option");
  2718. bigQueryInput.appendChild(bigQueryInputOption1);
  2719. bigQueryInput.appendChild(bigQueryInputOption2);
  2720. bigQueryInput.appendChild(bigQueryInputOption3);
  2721. bigQuery.appendChild(bigQueryInput);
  2722. var bigQueryExplanation = document.createElement("span");
  2723. bigQueryExplanation.innerText = "get stats for the <n> most popular shows";
  2724. bigQuery.appendChild(bigQueryExplanation);
  2725. databaseStats.appendChild(bigQuery);
  2726.  
  2727. var scriptStatsHead = document.createElement("h1");
  2728. scriptStatsHead.innerText = "Script";
  2729. var scriptStats = document.createElement("div");
  2730. var sVersion = document.createElement("p");
  2731. sVersion.innerHTML = "Version: <span class=\"hohStatValue\">" + scriptVersion + "</span>";
  2732. scriptStats.appendChild(sVersion);
  2733. var sHome = document.createElement("p");
  2734. sHome.innerHTML = "Homepage: <a href=\"https://gf.qytechs.cn/en/scripts/370473-aniscripts\">https://gf.qytechs.cn/en/scripts/370473-aniscripts</a>";
  2735. scriptStats.appendChild(sHome);
  2736. var sInstructions = document.createElement("p");
  2737. sInstructions.innerText = "Some changes requires reloading the page.";
  2738. scriptStats.appendChild(sInstructions);
  2739. var scriptSettings = document.createElement("div");
  2740. if(localStorageAvailable){
  2741. for(var j=0;j<useScriptsDefinitions.length;j++){
  2742. if(useScriptsDefinitions[j].visible){
  2743. var setting = document.createElement("p");
  2744. var checkbox = document.createElement("input");
  2745. checkbox.type = "checkbox";
  2746. checkbox.checked = useScripts[useScriptsDefinitions[j].id];
  2747. checkbox.targetSetting = useScriptsDefinitions[j].id;
  2748. checkbox.onchange = function(){
  2749. useScripts[this.targetSetting] = this.checked;
  2750. localStorage.setItem("hohSettings",JSON.stringify(useScripts));
  2751. };
  2752. var description = document.createElement("span");
  2753. description.innerText = useScriptsDefinitions[j].description;
  2754. setting.appendChild(checkbox);
  2755. setting.appendChild(description);
  2756. scriptSettings.appendChild(setting);
  2757. };
  2758. };
  2759. }
  2760. else{
  2761. var setting = document.createElement("p");
  2762. setting.innerHTML = "Script settings are not available without localstorage";
  2763. scriptSettings.appendChild(setting);
  2764. };
  2765.  
  2766. var personalStats = document.createElement("div");
  2767. personalStats.id = "personalStats";
  2768. var personalStatsManga = document.createElement("div");
  2769. personalStatsManga.id = "personalStatsManga";
  2770.  
  2771. hohStats.appendChild(databaseStatsHead);
  2772. hohStats.appendChild(databaseStats);
  2773. hohStats.appendChild(personalStats);
  2774. hohStats.appendChild(personalStatsManga);
  2775. hohStats.appendChild(document.createElement("hr"));
  2776. hohStats.appendChild(scriptStatsHead);
  2777. hohStats.appendChild(scriptStats);
  2778. hohStats.appendChild(scriptSettings);
  2779. //gather some stats
  2780. var query = "query($page:Int,$type:MediaType){Page(page:$page){pageInfo{total}media(type:$type){id}}}";
  2781. generalAPIcall(
  2782. query,
  2783. {page:0,type:"ANIME"},
  2784. function(data){
  2785. document.getElementById("hohTotalAnimeTarget").innerText = data.data.Page.pageInfo.total;
  2786. }
  2787. );
  2788. generalAPIcall(
  2789. query,
  2790. {page:0,type:"MANGA"},
  2791. function(data){
  2792. document.getElementById("hohTotalMangaTarget").innerText = data.data.Page.pageInfo.total;
  2793. }
  2794. );
  2795. generalAPIcall(
  2796. "query($page:Int){Page(page:$page){pageInfo{total}users{id}}}",
  2797. {page:0},
  2798. function(data){
  2799. document.getElementById("hohTotalUsersTarget").innerText = data.data.Page.pageInfo.total
  2800. }
  2801. );
  2802. //
  2803. var query = queryMediaList;
  2804. var variables = {
  2805. name: document.URL.match(/\/([a-zA-Z0-9-]+)\/stats/)[1],
  2806. listType: "ANIME"
  2807. };
  2808. var personalStatsCallback = function(data){
  2809. var personalStats = document.getElementById("personalStats");
  2810. var personalStatsHead = document.createElement("h1");
  2811. var thisName = document.URL.match(/\/([a-zA-Z0-9-]+)\/stats/)[1];
  2812. personalStatsHead.innerText = "Anime stats for " + thisName;
  2813. personalStats.appendChild(document.createElement("hr"));
  2814. personalStats.appendChild(personalStatsHead);
  2815. var list = returnList(data);
  2816. for(var i=1;i<list.length;i++){//remove duplicates
  2817. if(list[i].mediaId == list[i-1].mediaId){
  2818. list.splice(i-1,1);
  2819. i--;
  2820. };
  2821. };
  2822. if(whoAmI != thisName){
  2823. var compatabilityButton = document.createElement("button");
  2824. compatabilityButton.innerText = "Compatibility";
  2825. compatabilityButton.onclick = function(){compatCheck(list,whoAmI,"hohCheckCompat")};
  2826. personalStats.appendChild(compatabilityButton);
  2827. var hohCheckCompat = document.createElement("div");
  2828. hohCheckCompat.id = "hohCheckCompat";
  2829. personalStats.appendChild(hohCheckCompat);
  2830. };
  2831. var addStat = function(text,value,comment){//value,value,html
  2832. var newStat = document.createElement("p");
  2833. newStat.classList.add("hohStat");
  2834. var newStatText = document.createElement("span");
  2835. newStatText.innerText = text;
  2836. var newStatValue = document.createElement("span");
  2837. newStatValue.innerText = value;
  2838. newStatValue.classList.add("hohStatValue");
  2839. newStat.appendChild(newStatText);
  2840. newStat.appendChild(newStatValue);
  2841. if(comment){
  2842. var newStatComment = document.createElement("span");
  2843. newStatComment.innerHTML = comment;
  2844. newStat.appendChild(newStatComment);
  2845. };
  2846. personalStats.appendChild(newStat);
  2847. };
  2848. //
  2849. var oldestYear = 2100;//fix this before 2100
  2850. var oldestMonth = 0;
  2851. var oldestDay = 0;
  2852. for(var i=0;i<list.length;i++){
  2853. if(list[i].startedAt.year){
  2854. if(list[i].startedAt.year < oldestYear){
  2855. oldestYear = list[i].startedAt.year;
  2856. oldestMonth = list[i].startedAt.month;
  2857. oldestDay = list[i].startedAt.day;
  2858. }
  2859. else if(
  2860. list[i].startedAt.year == oldestYear
  2861. && list[i].startedAt.month < oldestMonth
  2862. ){
  2863. oldestYear = list[i].startedAt.year;
  2864. oldestMonth = list[i].startedAt.month;
  2865. oldestDay = list[i].startedAt.day;
  2866. }
  2867. else if(
  2868. list[i].startedAt.year == oldestYear
  2869. && list[i].startedAt.month == oldestMonth
  2870. && list[i].startedAt.day < oldestDay
  2871. ){
  2872. oldestYear = list[i].startedAt.year;
  2873. oldestMonth = list[i].startedAt.month;
  2874. oldestDay = list[i].startedAt.day;
  2875. };
  2876. };
  2877. };
  2878. //
  2879. var previouScore = 0;
  2880. var maxRunLength = 0;
  2881. var maxRunLengthScore = 0;
  2882. var runLength = 0;
  2883. var sumEntries = 0;
  2884. var amount = 0;
  2885. var sumWeight = 0;
  2886. var sumEntriesWeight = 0;
  2887. var median = 0;
  2888. var sumDuration = 0;
  2889. var longestDuration = {
  2890. time: 0,
  2891. name: "",
  2892. status: "",
  2893. rewatch: 0,
  2894. id: 0
  2895. };
  2896.  
  2897. list.sort(function(a,b){return a.scoreRaw - b.scoreRaw});
  2898. for(var i=0;i<list.length;i++){
  2899. var entryDuration = (list[i].media.duration|0)*(list[i].progress|0) + (list[i].media.duration|0)*(list[i].repeat|0)*Math.max((list[i].media.episodes|0),(list[i].progress|0));
  2900. sumDuration += entryDuration;
  2901. if(entryDuration > longestDuration.time){
  2902. longestDuration.time = entryDuration;
  2903. longestDuration.name = list[i].media.title.romaji;
  2904. longestDuration.status = list[i].status;
  2905. longestDuration.rewatch = list[i].repeat;
  2906. longestDuration.id = list[i].mediaId;
  2907. };
  2908. if(list[i].scoreRaw == 0){
  2909. continue;
  2910. };
  2911. if(median == 0){
  2912. median = list[i+Math.floor((list.length-i)/2)].scoreRaw;
  2913. };
  2914. amount++;
  2915. sumEntries += list[i].scoreRaw;
  2916. if(list[i].scoreRaw == previouScore){
  2917. runLength++;
  2918. if(runLength > maxRunLength){
  2919. maxRunLength = runLength;
  2920. maxRunLengthScore = list[i].scoreRaw;
  2921. };
  2922. }
  2923. else{
  2924. runLength = 1;
  2925. previouScore = list[i].scoreRaw;
  2926. };
  2927. sumWeight += (list[i].media.duration|0)*(list[i].media.episodes|0);
  2928. sumEntriesWeight += list[i].scoreRaw*(list[i].media.duration|0)*(list[i].media.episodes|0);
  2929. };
  2930. list.sort(function(a,b){return a.mediaId - b.mediaId});
  2931.  
  2932. if(amount != 0){//no scores
  2933. addStat(
  2934. "Average score: ",
  2935. (Math.round(100*sumEntries/amount)/100).toFixed(2)
  2936. );
  2937. addStat(
  2938. "Average score: ",
  2939. (Math.round(100*sumEntriesWeight/sumWeight)/100).toFixed(2),
  2940. " (weighted by duration)"
  2941. );
  2942. addStat("Median score: ",median);
  2943. addStat("Most common score: ",maxRunLengthScore);
  2944. var singleText = (100*longestDuration.time/sumDuration).toFixed(2) + "% is ";
  2945. singleText += "<a href='https://anilist.co/anime/" + longestDuration.id + "'>" + longestDuration.name + "</a>";
  2946. if(longestDuration.rewatch == 0){
  2947. if(longestDuration.status == "COMPLETED"){}
  2948. else if(longestDuration.status == "CURRENT"){singleText += ". Currently watching."}
  2949. else if(longestDuration.status == "PAUSED"){singleText += ". On hold."}
  2950. else if(longestDuration.status == "DROPPED"){singleText += ". Dropped."};
  2951. }
  2952. else{
  2953. if(longestDuration.status == "COMPLETED"){
  2954. if(longestDuration.rewatch == 1){
  2955. singleText += ". Rewatched once.";
  2956. }
  2957. else if(longestDuration.rewatch == 2){
  2958. singleText += ". Rewatched twice.";
  2959. }
  2960. else{
  2961. singleText += ". Rewatched " + longestDuration.rewatch + " times.";
  2962. };
  2963. }
  2964. else if(longestDuration.status == "CURRENT" || status == "REPEATING"){
  2965. if(longestDuration.rewatch == 1){
  2966. singleText += ". First rewatch in progress.";
  2967. }
  2968. else if(longestDuration.rewatch == 2){
  2969. singleText += ". Second rewatch in progress.";
  2970. }
  2971. else{
  2972. singleText += ". Rewatch number " + longestDuration.rewatch + " in progress.";
  2973. };
  2974. }
  2975. else if(longestDuration.status == "PAUSED"){
  2976. if(longestDuration.rewatch == 1){
  2977. singleText += ". First rewatch on hold.";
  2978. }
  2979. else if(longestDuration.rewatch == 2){
  2980. singleText += ". Second rewatch on hold.";
  2981. }
  2982. else{
  2983. singleText += ". Rewatch number " + longestDuration.rewatch + " on hold.";
  2984. };
  2985. }
  2986. else if(longestDuration.status == "DROPPED"){
  2987. if(longestDuration.rewatch == 1){
  2988. singleText += ". Dropped on first rewatch.";
  2989. }
  2990. else if(longestDuration.rewatch == 2){
  2991. singleText += ". Dropped on second rewatch.";
  2992. }
  2993. else{
  2994. singleText += ". Dropped on rewatch number " + longestDuration.rewatch + ".";
  2995. };
  2996. };
  2997. };
  2998. addStat(
  2999. "Time watched: ",
  3000. (sumDuration/(60*24)).toFixed(2),
  3001. " days (" + singleText + ")"
  3002. );
  3003. };
  3004. //
  3005. var TVepisodes = 0;
  3006. var TVepisodesLeft = 0;
  3007. for(var i=0;i<list.length;i++){
  3008. if(list[i].media.format == "TV"){
  3009. TVepisodes += list[i].progress;
  3010. TVepisodes += list[i].repeat * Math.max((list[i].media.episodes|0),list[i].progress);
  3011. if(list[i].status == "CURRENT"){
  3012. TVepisodesLeft += Math.max((list[i].media.episodes|0) - list[i].progress,0);
  3013. };
  3014. };
  3015. };
  3016. addStat("TV episodes watched: ",TVepisodes);
  3017. addStat("TV episodes remaining for current shows: ",TVepisodesLeft);
  3018. //
  3019. var tagless = [];
  3020. for(var i=0;i<list.length;i++){
  3021. if(list[i].media.tags.length == 0 && list[i].status != "PLANNING"){
  3022. tagless.push({id:list[i].mediaId,name:list[i].media.title.romaji});
  3023. };
  3024. };
  3025. if(tagless.length){
  3026. var taglessHead = document.createElement("p");
  3027. taglessHead.innerText = "Some shows on your list have no tags. Would you like to help with that?";
  3028. personalStats.appendChild(taglessHead);
  3029. for(var i=0;i<tagless.length && i<10;i++){
  3030. var taglessLink = document.createElement("a");
  3031. taglessLink.innerText = tagless[i].name;
  3032. taglessLink.href = "https://anilist.co/anime/"+tagless[i].id;
  3033. taglessLink.classList.add("hohTaglessLinkException");
  3034. personalStats.appendChild(taglessLink);
  3035. };
  3036. };
  3037. //
  3038. var distribution = {
  3039. "TV" : {},
  3040. "MOVIE" : {},
  3041. "TV_SHORT" : {},
  3042. "MUSIC" : {},
  3043. "OVA" : {},
  3044. "ONA" : {},
  3045. "SPECIAL" : {}
  3046. };
  3047. var distributionColours = {
  3048. "COMPLETED" : "rgb(2, 169, 255)",
  3049. "CURRENT" : "rgb(104, 214, 57)",
  3050. "PAUSED" : "rgb(247, 121, 164)",
  3051. "DROPPED" : "rgb(232, 93, 117)",
  3052. "PLANNING" : "rgb(247, 154, 99)"
  3053. };
  3054. for(var i=0;i<list.length;i++){
  3055. try{//reason: some people have manga entries on their anime list. Nasty.
  3056. distribution[list[i].media.format][list[i].status] = (distribution[list[i].media.format][list[i].status]|0) + 1;
  3057. }
  3058. catch{
  3059. console.log(list[i].media.title.romaji);
  3060. };
  3061. };
  3062. var formatDistribution = document.createElement("canvas");
  3063. var margins = {
  3064. height: 200,
  3065. width: 800,
  3066. left: 10,
  3067. right: 10,
  3068. top: 15,
  3069. bottom: 10,
  3070. chartTextBottom: 50
  3071. };
  3072. formatDistribution.width = margins.width;
  3073. formatDistribution.height = margins.height;
  3074. formatDistribution.style.background = "rgb(var(--color-foreground))";
  3075. var formatDistributionHead = document.createElement("p");
  3076. formatDistributionHead.innerText = "Format distribution";
  3077. personalStats.appendChild(formatDistributionHead);
  3078. personalStats.appendChild(formatDistribution);
  3079. var ctx = formatDistribution.getContext("2d");
  3080. var largestValue = 0;
  3081. for(format in distribution){
  3082. for(status in distribution[format]){
  3083. if(distribution[format][status] > largestValue){
  3084. largestValue = distribution[format][status];
  3085. };
  3086. };
  3087. };
  3088. var yAxisLimit = Math.ceil(largestValue/Math.pow(10,(largestValue+"").length-1))*Math.pow(10,(largestValue+"").length-1);
  3089. var chartHeight = margins.height - margins.chartTextBottom - margins.bottom - margins.top;
  3090. ctx.fillStyle = "rgb(133,150,165)";
  3091. ctx.strokeStyle = "rgb(133,150,165)";
  3092. ctx.textAlign = "end";
  3093. ctx.fillText(yAxisLimit,margins.left + 20,margins.top);
  3094. ctx.fillText(0,margins.left + 20,margins.top + chartHeight);
  3095. ctx.fillText(yAxisLimit/2,margins.left + 20,margins.top + chartHeight/2);
  3096. var chartCellWidth = 100;
  3097. ctx.textAlign = "center";
  3098. ctx.fillText("TV",margins.left + 20 + chartCellWidth/2,margins.top + chartHeight + 20);
  3099. ctx.fillText("Movie",margins.left + 20 + chartCellWidth/2 + 1*chartCellWidth,margins.top + chartHeight + 20);
  3100. ctx.fillText("OVA",margins.left + 20 + chartCellWidth/2 + 2*chartCellWidth,margins.top + chartHeight + 20);
  3101. ctx.fillText("ONA",margins.left + 20 + chartCellWidth/2 + 3*chartCellWidth,margins.top + chartHeight + 20);
  3102. ctx.fillText("TV-Short",margins.left + 20 + chartCellWidth/2 + 4*chartCellWidth,margins.top + chartHeight + 20);
  3103. ctx.fillText("Special",margins.left + 20 + chartCellWidth/2 + 5*chartCellWidth,margins.top + chartHeight + 20);
  3104. ctx.fillText("Music",margins.left + 20 + chartCellWidth/2 + 6*chartCellWidth,margins.top + chartHeight + 20);
  3105. ctx.beginPath();
  3106. ctx.lineWidth = 0.5;
  3107. ctx.moveTo(margins.left + 25,Math.round(margins.top-5));
  3108. ctx.lineTo(margins.width - margins.right,Math.round(margins.top-5));
  3109. ctx.moveTo(margins.left + 25,Math.round(margins.top-5 + chartHeight));
  3110. ctx.lineTo(margins.width - margins.right,Math.round(margins.top-5 + chartHeight));
  3111. ctx.moveTo(margins.left + 25,Math.round(margins.top-5 + chartHeight/2));
  3112. ctx.lineTo(margins.width - margins.right,Math.round(margins.top-5 + chartHeight/2));
  3113. ctx.stroke();
  3114.  
  3115. ctx.textAlign = "start";
  3116. ctx.fillText("Completed",margins.left+65,margins.top + chartHeight + 50);
  3117. ctx.fillText("Current",margins.left+65+chartCellWidth,margins.top + chartHeight + 50);
  3118. ctx.fillText("Paused",margins.left+65+chartCellWidth*2,margins.top + chartHeight + 50);
  3119. ctx.fillText("Dropped",margins.left+65+chartCellWidth*3,margins.top + chartHeight + 50);
  3120. ctx.fillText("Planning",margins.left+65+chartCellWidth*4,margins.top + chartHeight + 50);
  3121.  
  3122. var barWidth = 10;
  3123. ctx.fillStyle = distributionColours["COMPLETED"];
  3124. ctx.fillRect(margins.left+50,margins.top + chartHeight + 40,10,10);
  3125. ctx.fillRect(Math.round(margins.left + chartCellWidth/2),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["TV"]["COMPLETED"]|0));
  3126. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + 1*chartCellWidth),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["MOVIE"]["COMPLETED"]|0));
  3127. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + 2*chartCellWidth),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["OVA"]["COMPLETED"]|0));
  3128. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + 3*chartCellWidth),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["ONA"]["COMPLETED"]|0));
  3129. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + 4*chartCellWidth),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["TV_SHORT"]["COMPLETED"]|0));
  3130. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + 5*chartCellWidth),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["SPECIAL"]["COMPLETED"]|0));
  3131. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + 6*chartCellWidth),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["MUSIC"]["COMPLETED"]|0));
  3132.  
  3133. ctx.fillStyle = distributionColours["CURRENT"];
  3134. ctx.fillRect(margins.left+50+chartCellWidth,margins.top + chartHeight + 40,10,10);
  3135. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + barWidth),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["TV"]["CURRENT"]|0));
  3136. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + 1*chartCellWidth + barWidth),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["MOVIE"]["CURRENT"]|0));
  3137. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + 2*chartCellWidth + barWidth),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["OVA"]["CURRENT"]|0));
  3138. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + 3*chartCellWidth + barWidth),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["ONA"]["CURRENT"]|0));
  3139. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + 4*chartCellWidth + barWidth),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["TV_SHORT"]["CURRENT"]|0));
  3140. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + 5*chartCellWidth + barWidth),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["SPECIAL"]["CURRENT"]|0));
  3141. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + 6*chartCellWidth + barWidth),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["MUSIC"]["CURRENT"]|0));
  3142.  
  3143. ctx.fillStyle = distributionColours["PAUSED"];
  3144. ctx.fillRect(margins.left+50+chartCellWidth*2,margins.top + chartHeight + 40,10,10);
  3145. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + barWidth*2),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["TV"]["PAUSED"]|0));
  3146. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + 1*chartCellWidth + barWidth*2),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["MOVIE"]["PAUSED"]|0));
  3147. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + 2*chartCellWidth + barWidth*2),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["OVA"]["PAUSED"]|0));
  3148. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + 3*chartCellWidth + barWidth*2),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["ONA"]["PAUSED"]|0));
  3149. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + 4*chartCellWidth + barWidth*2),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["TV_SHORT"]["PAUSED"]|0));
  3150. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + 5*chartCellWidth + barWidth*2),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["SPECIAL"]["PAUSED"]|0));
  3151. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + 6*chartCellWidth + barWidth*2),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["MUSIC"]["PAUSED"]|0));
  3152.  
  3153. ctx.fillStyle = distributionColours["DROPPED"];
  3154. ctx.fillRect(margins.left+50+chartCellWidth*3,margins.top + chartHeight + 40,10,10);
  3155. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + barWidth*3),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["TV"]["DROPPED"]|0));
  3156. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + 1*chartCellWidth + barWidth*3),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["MOVIE"]["DROPPED"]|0));
  3157. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + 2*chartCellWidth + barWidth*3),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["OVA"]["DROPPED"]|0));
  3158. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + 3*chartCellWidth + barWidth*3),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["ONA"]["DROPPED"]|0));
  3159. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + 4*chartCellWidth + barWidth*3),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["TV_SHORT"]["DROPPED"]|0));
  3160. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + 5*chartCellWidth + barWidth*3),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["SPECIAL"]["DROPPED"]|0));
  3161. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + 6*chartCellWidth + barWidth*3),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["MUSIC"]["DROPPED"]|0));
  3162.  
  3163.  
  3164. ctx.fillStyle = distributionColours["PLANNING"];
  3165. ctx.fillRect(margins.left+50+chartCellWidth*4,margins.top + chartHeight + 40,10,10);
  3166. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + barWidth*4),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["TV"]["PLANNING"]|0));
  3167. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + 1*chartCellWidth + barWidth*4),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["MOVIE"]["PLANNING"]|0));
  3168. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + 2*chartCellWidth + barWidth*4),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["OVA"]["PLANNING"]|0));
  3169. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + 3*chartCellWidth + barWidth*4),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["ONA"]["PLANNING"]|0));
  3170. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + 4*chartCellWidth + barWidth*4),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["TV_SHORT"]["PLANNING"]|0));
  3171. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + 5*chartCellWidth + barWidth*4),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["SPECIAL"]["PLANNING"]|0));
  3172. ctx.fillRect(Math.round(margins.left + chartCellWidth/2 + 6*chartCellWidth + barWidth*4),Math.round(margins.top + chartHeight - 5),barWidth,(-chartHeight/yAxisLimit)*(distribution["MUSIC"]["PLANNING"]|0));
  3173.  
  3174. if(oldestYear < 2100){
  3175. var joinedAnilist = document.createElement("p");
  3176. joinedAnilist.innerText = "First logged anime: " + oldestYear + "-" + oldestMonth + "-" + oldestDay + ". (users can change start dates)";
  3177. personalStats.appendChild(joinedAnilist);
  3178. };
  3179. var customTags = [];
  3180. for(var i=0;i<list.length;i++){
  3181. if(list[i].notes){
  3182. var tagMatches = list[i].notes.match(/(#\S+)/g);
  3183. if(tagMatches){
  3184. for(var j=0;j<tagMatches.length;j++){
  3185. if(tagMatches[j].match(/#039/)){
  3186. continue;
  3187. };
  3188. var foundFlag = false;
  3189. for(var k=0;k<customTags.length;k++){
  3190. if(customTags[k].name == tagMatches[j]){
  3191. customTags[k].list.push(list[i].scoreRaw);
  3192. foundFlag = true;
  3193. break;
  3194. };
  3195. };
  3196. if(!foundFlag){
  3197. customTags.push(
  3198. {
  3199. name : tagMatches[j],
  3200. list : [list[i].scoreRaw]
  3201. }
  3202. );
  3203. };
  3204. };
  3205. };
  3206. };
  3207. };
  3208. for(var i=0;i<customTags.length;i++){
  3209. var amountCount = 0;
  3210. var average = 0;
  3211. for(var j=0;j<customTags[i].list.length;j++){
  3212. if(customTags[i].list[j] != 0){
  3213. amountCount++;
  3214. average += customTags[i].list[j];
  3215. };
  3216. };
  3217. if(average != 0){
  3218. average = average/amountCount;
  3219. };
  3220. customTags[i].average = average;
  3221. };
  3222. customTags.sort(function(b,a){return a.list.length - b.list.length});
  3223. if(customTags.length > 1){
  3224. var randomData = "data-v-e2beaf26";
  3225. var customTagsHead = document.createElement("h1");
  3226. customTagsHead.innerText = "Custom Tags";
  3227. var customTagsTable = document.createElement("div");
  3228. customTagsTable.classList.add("table");
  3229. customTagsTable.setAttribute(randomData,"");
  3230. var headerRow = document.createElement("div");
  3231. headerRow.classList.add("header");
  3232. headerRow.classList.add("row");
  3233. headerRow.setAttribute(randomData,"");
  3234. var headerRowTag = document.createElement("div");
  3235. var headerRowCount = document.createElement("div");
  3236. var headerRowScore = document.createElement("div");
  3237. headerRowTag.innerText = "Tag";
  3238. headerRowCount.innerText = "Count";
  3239. headerRowScore.innerText = "Mean Score";
  3240. headerRowTag.setAttribute(randomData,"");
  3241. headerRowCount.setAttribute(randomData,"");
  3242. headerRowScore.setAttribute(randomData,"");
  3243. headerRow.appendChild(headerRowTag);
  3244. headerRow.appendChild(headerRowCount);
  3245. headerRow.appendChild(headerRowScore);
  3246. customTagsTable.appendChild(headerRow);
  3247. for(var i=0;i<customTags.length;i++){
  3248. var row = document.createElement("div");
  3249. row.setAttribute(randomData,"");
  3250. row.classList.add("row");
  3251. var nameCell = document.createElement("div");
  3252. nameCell.setAttribute(randomData,"");
  3253. var nameCellCount = document.createElement("div");
  3254. nameCellCount.setAttribute(randomData,"");
  3255. var nameCellTag = document.createElement("a");
  3256. nameCellTag.setAttribute("data-v-2f71893a","");
  3257. nameCellCount.innerText = (i+1);
  3258. nameCellCount.classList.add("count");
  3259. nameCellTag.innerText = customTags[i].name;
  3260. nameCell.appendChild(nameCellCount);
  3261. nameCell.appendChild(nameCellTag);
  3262. row.appendChild(nameCell);
  3263. var countCell = document.createElement("div");
  3264. countCell.setAttribute(randomData,"");
  3265. countCell.innerText = customTags[i].list.length;
  3266. row.appendChild(countCell);
  3267. var scoreCell = document.createElement("div");
  3268. scoreCell.setAttribute(randomData,"");
  3269. scoreCell.innerText = Math.round(customTags[i].average);
  3270. row.appendChild(scoreCell);
  3271. customTagsTable.appendChild(row);
  3272. };
  3273. personalStats.appendChild(customTagsHead);
  3274. personalStats.appendChild(customTagsTable);
  3275. };
  3276. };
  3277. generalAPIcall(query,variables,personalStatsCallback);
  3278. var query = queryMediaList;
  3279. var variables = {
  3280. name: document.URL.match(/\/([a-zA-Z0-9-]+)\/stats/)[1],
  3281. listType: "MANGA"
  3282. };
  3283. var personalStatsMangaCallback = function(data){
  3284. var thisName = document.URL.match(/\/([a-zA-Z0-9-]+)\/stats/)[1];
  3285. var personalStatsManga = document.getElementById("personalStatsManga");
  3286. var personalStatsMangaHead = document.createElement("h1");
  3287. personalStatsMangaHead.innerText = "Manga stats for " + thisName;
  3288. personalStatsManga.appendChild(document.createElement("hr"));
  3289. personalStatsManga.appendChild(personalStatsMangaHead);
  3290. var returnList = function(list){
  3291. var retl = [];
  3292. for(var i=0;i<list.data.MediaListCollection.lists.length;i++){
  3293. for(var j=0;j<list.data.MediaListCollection.lists[i].entries.length;j++){
  3294. var retlObj = list.data.MediaListCollection.lists[i].entries[j];
  3295. if(retlObj.scoreRaw > 100){
  3296. retlObj.scoreRaw = 100;
  3297. };
  3298. retl.push(retlObj);
  3299. };
  3300. };
  3301. return retl.sort(function(a,b){
  3302. return a.mediaId - b.mediaId;
  3303. });
  3304. };
  3305. var list = returnList(data);
  3306. for(var i=1;i<list.length;i++){//remove duplicates
  3307. if(list[i].mediaId == list[i-1].mediaId){
  3308. list.splice(i-1,1);
  3309. i--;
  3310. };
  3311. };
  3312. var personalStatsMangaContainer = document.createElement("div");
  3313. personalStatsMangaContainer.innerText = "Propose some stats I can put here";
  3314. personalStatsManga.appendChild(personalStatsMangaContainer);
  3315. var addStat = function(text,value,comment){//value,value,html
  3316. var newStat = document.createElement("p");
  3317. newStat.classList.add("hohStat");
  3318. var newStatText = document.createElement("span");
  3319. newStatText.innerText = text;
  3320. var newStatValue = document.createElement("span");
  3321. newStatValue.innerText = value;
  3322. newStatValue.classList.add("hohStatValue");
  3323. newStat.appendChild(newStatText);
  3324. newStat.appendChild(newStatValue);
  3325. if(comment){
  3326. var newStatComment = document.createElement("span");
  3327. newStatComment.innerHTML = comment;
  3328. newStat.appendChild(newStatComment);
  3329. };
  3330. personalStatsManga.appendChild(newStat);
  3331. };
  3332. var chapters = 0;
  3333. var volumes = 0;
  3334. /*
  3335. For most airing anime, Anilist provides "media.nextAiringEpisode.episode"
  3336. Unfortunately, the same is not the case for releasing manga.
  3337. THIS DOESN'T MATTER the first time a user is reading something, as we are then just using the current progress.
  3338. But on a re-read, we need the total length to count all the chapters read.
  3339. I can (and do) get a lower boud for this by using the current progress (this is what Anilist does),
  3340. but this is not quite accurate, especially early in a re-read.
  3341. The list below is to catch some of those exceptions
  3342. */
  3343. var commonUnfinishedManga = {
  3344. "53390":{//aot
  3345. chapters:110,
  3346. volumes:26
  3347. },
  3348. "30002":{//berserk
  3349. chapters:357,
  3350. volumes:40
  3351. },
  3352. "30013":{//one piece
  3353. chapters:921,
  3354. volumes:90
  3355. },
  3356. "85486":{//mha
  3357. chapters:202,
  3358. volumes:20
  3359. },
  3360. "74347":{//opm
  3361. chapters:99,
  3362. volumes:17
  3363. },
  3364. "30026":{//HxH
  3365. chapters:385,
  3366. volumes:36
  3367. },
  3368. "30656":{//vagabond
  3369. chapters:327,
  3370. volumes:37
  3371. },
  3372. "30104":{//yotsuba
  3373. chapters:102,
  3374. volumes:14
  3375. }
  3376. };
  3377. var listCreatedTime = new Date(2018,9,26);
  3378. var currentTime = new Date();
  3379. if(currentTime - listCreatedTime > 365*24*60*60*1000){
  3380. console.log("remind hoh to update the commonUnfinishedManga list");
  3381. };
  3382. var unfinishedLookup = function(mediaId,mode,mediaStatus){
  3383. if(mediaStatus == "FINISHED"){
  3384. return 0;//it may have finished since the list was updated
  3385. };
  3386. if(commonUnfinishedManga.hasOwnProperty(mediaId)){
  3387. if(mode == "chapters"){
  3388. return commonUnfinishedManga[mediaId].chapters;
  3389. }
  3390. else{
  3391. return commonUnfinishedManga[mediaId].volumes;
  3392. };
  3393. }
  3394. else{
  3395. return 0;//not in our list
  3396. };
  3397. };
  3398. for(var i=0;i<list.length;i++){
  3399. if(list[i].status == "COMPLETED"){//if it's completed, we can make some safe assumptions
  3400. chapters += Math.max(//chapter progress on the current read
  3401. list[i].media.chapters,//in most cases, it has a chapter count
  3402. list[i].media.volumes,//if not, there's at least 1 chapter per volume
  3403. list[i].progress,//if it doesn't have a volume count either, the current progress is probably not out of date
  3404. list[i].progressVolumes,//if it doesn't have a chapter progress, count at least 1 chapter per volume
  3405. 1//finally, an entry has at least 1 chapter
  3406. );
  3407. }
  3408. else{//we may only assume what's on the user's list.
  3409. chapters += Math.max(
  3410. list[i].progress,
  3411. list[i].progressVolumes
  3412. );
  3413. };
  3414. chapters += list[i].repeat * Math.max(//chapters from re-reads
  3415. list[i].media.chapters,
  3416. list[i].media.volumes,
  3417. list[i].progress,
  3418. list[i].progressVolumes,
  3419. unfinishedLookup(list[i].mediaId+"","chapters",list[i].media.status),//use our lookup table
  3420. 1
  3421. );
  3422. volumes += list[i].progressVolumes;
  3423. volumes += list[i].repeat * Math.max(//many manga have no volumes, so we can't make all of the same assumptions
  3424. list[i].media.volumes,
  3425. list[i].progressVolumes,//better than nothing if a volume count is missing
  3426. unfinishedLookup(list[i].mediaId+"","volumes",list[i].media.status)
  3427. );
  3428. };
  3429. addStat("Total chapters: ",chapters);
  3430. addStat("Total volumes: ",volumes);
  3431. };
  3432. generalAPIcall(query,variables,personalStatsMangaCallback);
  3433. };
  3434. };
  3435. for(var i=1;i<filterGroup.children.length;i++){
  3436. filterGroup.children[i].onclick = function(){
  3437. var statsWrap = document.getElementsByClassName("stats-wrap")[0];
  3438. for(var j=0;j<statsWrap.children.length;j++){
  3439. statsWrap.children[j].style.display = "initial";
  3440. };
  3441. var hohActive = document.getElementsByClassName("hohActive");
  3442. for(var j=0;j<hohActive.length;j++){
  3443. hohActive[j].classList.remove("hohActive");
  3444. };
  3445. document.getElementById("hohStats").style.display = "none";
  3446. };
  3447. };
  3448. var statsWrap = document.getElementsByClassName("stats-wrap");
  3449. if(statsWrap.length){
  3450. statsWrap = statsWrap[0];
  3451. var hohStats = document.createElement("div");
  3452. hohStats.id = "hohStats";
  3453. hohStats.style.display = "none";
  3454. hohStats.calculated = false;
  3455. statsWrap.appendChild(hohStats);
  3456. };
  3457. filterGroup.appendChild(hohStatsTrigger);
  3458. };
  3459.  
  3460. var handleScripts = function(url){
  3461. if(url == "https://anilist.co/notifications" && activeScripts.notifications == false && useScripts.notifications){
  3462. enhanceNotifications();
  3463. }
  3464. else if(
  3465. url.match(/https:\/\/anilist\.co\/(anime|manga)\/\d*\/[0-9a-zA-Z-]*\/social/)
  3466. ){
  3467. if(activeScripts.socialTab == false && useScripts.socialTab){
  3468. enhanceSocialTab();
  3469. };
  3470. }
  3471. else if(
  3472. url.match(/\/stats$/)
  3473. && activeScripts.moreStats == false
  3474. && useScripts.moreStats
  3475. ){
  3476. addMoreStats();
  3477. }
  3478. else if(
  3479. url.match(/https:\/\/anilist\.co\/user\/?/)
  3480. ){
  3481. if(activeScripts.favourites == false && useScripts.favourites){
  3482. enhanceFavourites();
  3483. };
  3484. if(activeScripts.completedScore == false && useScripts.completedScore){//we also want this script to run on user pages
  3485. addCompletedScores();
  3486. };
  3487. if(activeScripts.reTweet == false && useScripts.reTweet){
  3488. reTweet();
  3489. };
  3490. }
  3491. else if(
  3492. url.match(/https:\/\/anilist\.co\/forum\/thread\/.*/)
  3493. && activeScripts.forumComments == false
  3494. && useScripts.forumComments
  3495. ){
  3496. enhanceForum();
  3497. }
  3498. else if(
  3499. url.match(/https:\/\/anilist\.co\/staff\/.*/)
  3500. && activeScripts.staffPages == false
  3501. && useScripts.staffPages
  3502. ){
  3503. enhanceStaff();
  3504. }
  3505. else if(
  3506. url.match(/https:\/\/anilist\.co\/character\/.*/)
  3507. && activeScripts.characterFavouriteCount == false
  3508. && useScripts.characterFavouriteCount
  3509. ){
  3510. enhanceCharacter();
  3511. }
  3512. else if(
  3513. url.match(/https:\/\/anilist\.co\/(anime|manga)\/.*/)
  3514. ){
  3515. if(activeScripts.tagDescriptions == false && useScripts.tagDescriptions){
  3516. enhanceTags();
  3517. };
  3518. if(activeScripts.userRecs == false && useScripts.userRecs){
  3519. userRecs();
  3520. };
  3521. }
  3522. else if(
  3523. url.match(/https:\/\/anilist\.co\/home\/?/)
  3524. ){
  3525. if(activeScripts.completedScore == false && useScripts.completedScore){
  3526. addCompletedScores();
  3527. };
  3528. if(activeScripts.usefulLinks == false && useScripts.usefulLinks){
  3529. usefulLinks();
  3530. };
  3531. if(activeScripts.reTweet == false && useScripts.reTweet){
  3532. reTweet();
  3533. };
  3534. }
  3535. else if(
  3536. url.match(/https:\/\/anilist\.co\/activity\/?/)
  3537. ){
  3538. if(activeScripts.completedScore == false && useScripts.completedScore){
  3539. addCompletedScores();
  3540. };
  3541. if(activeScripts.reTweet == false && useScripts.reTweet){
  3542. reTweet();
  3543. };
  3544. };
  3545. };
  3546. var activeScripts = {
  3547. notifications : false,
  3548. socialTab : false,
  3549. favourites : false,
  3550. forumComments : false,
  3551. staffPages : false,
  3552. tagDescriptions : false,
  3553. completedScore : false,
  3554. moreStats : false,
  3555. characterFavouriteCount : false,
  3556. usefulLinks : false,
  3557. reTweet : false,
  3558. userRecs : false
  3559. };
  3560.  
  3561. var useScriptsDefinitions = [
  3562. {
  3563. id: "notifications",
  3564. visible: true,
  3565. description: "Improve notifications"
  3566. },{
  3567. id: "hideLikes",
  3568. visible: false,
  3569. description: "Hide like notifications. Will not affect the notification count."
  3570. },{
  3571. id: "socialTab",
  3572. visible: true,
  3573. description: "Make activities on the social tab more compact and calculate the average score of people you follow"
  3574. },{
  3575. id: "forumComments",
  3576. visible: true,
  3577. description: "Add button to collapse comment threads in the forum"
  3578. },{
  3579. id: "staffPages",
  3580. visible: false,
  3581. description: "Currently does nothing"
  3582. },{
  3583. id: "tagDescriptions",
  3584. visible: true,
  3585. description: "Show the definitions of tags when adding new ones to an entry"
  3586. },{
  3587. id: "completedScore",
  3588. visible: true,
  3589. description: "Show the score on the activity when people complete something"
  3590. },{
  3591. id: "moreStats",
  3592. visible: false,
  3593. description: "Show an additional tab on the stats page"
  3594. },{
  3595. id: "characterFavouriteCount",
  3596. visible: true,
  3597. description: "Show favourite count on character page"
  3598. },{
  3599. id: "usefulLinks",
  3600. visible: true,
  3601. description: "Display some links in the home page sidebar"
  3602. },{
  3603. id: "userRecs",
  3604. visible: true,
  3605. description: "Show recommendations"
  3606. },{
  3607. id: "favourites",
  3608. visible: true,
  3609. description: "Add button to show more favourites for users with more than 25 [will be fixed soon™]"
  3610. },{
  3611. id: "CSSfavs",
  3612. visible: true,
  3613. description: "Use the same favourite layout [from userstyle]"
  3614. },{
  3615. id: "CSScompactBrowse",
  3616. visible: true,
  3617. description: "Use a compact view in the browse section [from userstyle]"
  3618. },{
  3619. id: "CSSSFWmode",
  3620. visible: true,
  3621. description: "SFW mode. Dims images, uses less flashy colours, hides gifs, videos and more [Experimental]"
  3622. },{
  3623. id: "CSSgreenManga",
  3624. visible: true,
  3625. description: "Green titles for manga activities"
  3626. },{
  3627. id: "CSSfollowCounter",
  3628. visible: true,
  3629. description: "10-width follow section with count [from userstyle]"
  3630. },{
  3631. id: "CSSdecimalPoint",
  3632. visible: true,
  3633. description: "Give whole numbers a \".0\" suffix when using the 10 point decimal scoring system"
  3634. },{
  3635. id: "memeScripts",
  3636. visible: true,
  3637. description: "Allow running weird stuff in status posts. (that is, javascript)"
  3638. },{
  3639. id: "reTweet",
  3640. visible: true,
  3641. description: "Render old retweets [legacy]"
  3642. },{
  3643. id: "reTweetKiller",
  3644. visible: true,
  3645. description: "I hate retweets. Hide them from me. (the \"Check for retweets\" setting must be turned on for this to work) [legacy]"
  3646. }
  3647. ];
  3648. var current = "";
  3649. setInterval(function(){
  3650. if(document.URL != current){
  3651. current = document.URL;
  3652. handleScripts(current);
  3653. };
  3654. var expandPossible = document.getElementsByClassName("description-length-toggle");
  3655. if(expandPossible.length){
  3656. expandPossible[0].click();
  3657. };
  3658. },200);
  3659. var tagDescriptions = {
  3660. "4-koma" : "A manga in the 'yonkoma' format, which consists of four equal-sized panels arranged in a vertical strip.",
  3661. "Achronological Order" : "Chapters/episodes do not occur in chronological order.",
  3662. "Afterlife" : "Partly or completely set in the afterlife.",
  3663. "Age Gap" : "Prominently features romantic relations between people with a significant age difference.",
  3664. "Age Regression" : "Prominently features a character who was returned to a younger state.",
  3665. "Ahegao" : "Features a character making an exaggerated orgasm face.",
  3666. "Airsoft" : "Centers around the sport of airsoft.",
  3667. "Aliens" : "Prominently features extraterrestrial lifeforms.",
  3668. "Alternate Universe" : "Features multiple alternate universes in the same series.",
  3669. "American Football" : "Centers around the sport of American football.",
  3670. "Amnesia" : "Prominently features a character(s) with memory loss.",
  3671. "Anachronism" : "Prominently features elements that are out of place in the historical period the work takes place in, particularly modern elements in a historical setting.",
  3672. "Anal Sex" : "Features sexual penetration of the anal cavity.",
  3673. "Animals" : "Prominently features animal characters in a leading role.",
  3674. "Anti-Hero" : "Features a protagonist who lacks conventional heroic attributes and may be considered a borderline villain.",
  3675. "Anthology" : "A collection of separate works collated into a single release.",
  3676. "Archery" : "Centers around the sport of archery, or prominently features the use of archery in combat.",
  3677. "Ashikoki" : "Footjob; features stimulation of genitalia by feet.",
  3678. "Assassins" : "Centers around characters who murder people as a profession.",
  3679. "Athletics" : "Centers around sporting events that involve competitive running, jumping, throwing, or walking.",
  3680. "Augmented Reality" : "Prominently features events with augmented reality as the main setting.",
  3681. "Aviation" : "Regarding the flying or operation of aircraft.",
  3682. "Badminton" : "Centers around the sport of badminton.",
  3683. "Band" : "Main cast is a group of musicians.",
  3684. "Bar" : "Partly or completely set in a bar.",
  3685. "Baseball" : "Centers around the sport of baseball.",
  3686. "Basketball" : "Centers around the sport of basketball.",
  3687. "Battle Royale" : "Centers around a fierce group competition, often violent and with only one winner.",
  3688. "Biographical" : "Based on true stories of real persons living or dead.",
  3689. "Bisexual" : "Features a character who is romantically and/or sexually attracted to people of more than one sex and/or gender.",
  3690. "Blackmail" : "Features a character blackmailing another into performing sexual acts.",
  3691. "Body Swapping" : "Centers around individuals swapping bodies with one another.",
  3692. "Bondage" : "Features BDSM, with or without the use of accessories.",
  3693. "Boxing" : "Centers around the sport of boxing.",
  3694. "Boys' Love" : "Prominently features romance between two males, not inherently sexual.",
  3695. "Bullying" : "Prominently features the use of force for intimidation, often in a school setting.",
  3696. "Calligraphy" : "Centers around the art of calligraphy.",
  3697. "Card Battle" : "Centers around individuals competing in card games.",
  3698. "Cars" : "Centers around the use of automotive vehicles.",
  3699. "CGI" : "Prominently features scenes created with computer-generated imagery.",
  3700. "Chibi" : "Features \"super deformed\" character designs with smaller, rounder proportions and a cute look.",
  3701. "Chuunibyou" : "Prominently features a character with \"Middle School 2nd Year Syndrome\", who either acts like a know-it-all adult or falsely believes they have special powers.",
  3702. "Circus" : "Prominently features a circus.",
  3703. "Classic Literature" : "Adapted from a work of classic world literature.",
  3704. "College" : "Partly or completely set in a college or university.",
  3705. "Coming of Age" : "Centers around a character's transition from childhood to adulthood.",
  3706. "Conspiracy" : "Contains one or more factions controlling or attempting to control the world from the shadows.",
  3707. "Cosplay" : "Features dressing up as a different character or profession.",
  3708. "Crossdressing" : "Prominently features a character dressing up as the opposite sex.",
  3709. "Crossover" : "Centers around the placement of two or more otherwise discrete fictional characters, settings, or universes into the context of a single story.",
  3710. "Cultivation" : "Features characters using training, often martial arts-related, and other special methods to cultivate life force and gain strength or immortality.",
  3711. "Cunnilingus" : "Features oral sex performed on female genitalia.",
  3712. "Cute Girls Doing Cute Things" : "Centers around, well, cute girls doing cute things.",
  3713. "Cyberpunk" : "Set in a future of advanced technological and scientific achievements that have resulted in social disorder.",
  3714. "Cycling" : "Centers around the sport of cycling.",
  3715. "Dancing" : "Centers around the art of dance.",
  3716. "Dark Skin" : "Features dark-skinned characters in a sexual context.",
  3717. "Deflowering" : "There is already a \"Virgin\" tag",
  3718. "Delinquents" : "Features characters with a notorious image and attitude, sometimes referred to as \"yankees\".",
  3719. "Demons" : "Prominently features malevolent otherworldly creatures.",
  3720. "Development" : "Centers around characters developing or programming a piece of technology, software, gaming, etc.",
  3721. "Dragons" : "Prominently features mythical reptiles which generally have wings and can breathe fire.",
  3722. "Drawing" : "Centers around the art of drawing, including manga and doujinshi.",
  3723. "Drugs" : "Prominently features the usage of drugs such as opioids, stimulants, hallucinogens etc.",
  3724. "Dystopian" : "Partly or completely set in a society characterized by poverty, squalor or oppression",
  3725. "Economics" : "Centers around the field of economics.",
  3726. "Educational" : "Primary aim is to educate the audience.",
  3727. "Ensemble Cast" : "Features a large cast of characters with (almost) equal screen time and importance to the plot.",
  3728. "Environmental" : "concern with the state of the natural world and how humans interact with it.",
  3729. "Episodic" : "Features story arcs that are loosely tied or lack an overarching plot.",
  3730. "Ero Guro" : "Japanese literary and artistic movement originating in the 1930's. Work have a focus on grotesque eroticism, sexual corruption, and decadence.",
  3731. "Espionage" : "Prominently features characters infiltrating an organization in order to steal sensitive information.",
  3732. "Facial" : "Features sexual ejaculation onto an individual's face.",
  3733. "Fairy Tale" : "This work tells a fairy tale, centers around fairy tales, or is based on a classic fairy tale.",
  3734. "Family Life" : "Centers around the activities of a family unit.",
  3735. "Fashion" : "Centers around the fashion industry.",
  3736. "Fellatio" : "Features oral sex performed on male genitalia.",
  3737. "Female Protagonist" : "Main character is female.",
  3738. "Fishing" : "Centers around the sport of fishing.",
  3739. "Fitness" : "Centers around exercise with the aim of improving physical health.",
  3740. "Flash" : "Created using Flash animation techniques.",
  3741. "Flat Chest" : "Features a female character with smaller-than-average breasts.",
  3742. "Food" : "Centers around cooking or food appraisal.",
  3743. "Football" : "Centers around the sport of football (known in the USA as \"soccer\").",
  3744. "Foreign" : "Partly or completely set in a country outside of Japan.",
  3745. "Fugitive" : "Prominently features a character evading capture by an individual or organization.",
  3746. "Full CGI" : "Almost entirely created with computer-generated imagery.",
  3747. "Full Colour" : "Fully coloured or drawn in colour.",
  3748. "Futanari" : "Features female characters with male genitalia.",
  3749. "Gambling" : "Centers around the act of gambling.",
  3750. "Gangs" : "Centers around gang organizations.",
  3751. "Gender Bending" : "Prominently features a character who dresses and behaves in a way characteristic of the opposite sex, or has been transformed into a person of the opposite sex.",
  3752. "Gender Neutral" : "Prominently features agender characters.",
  3753. "Ghost" : "Prominently features a character who is a ghost.",
  3754. "Go" : "Centered around the game of Go.",
  3755. "Gods" : "Prominently features a character of divine or religious nature.",
  3756. "Gore" : "Prominently features graphic bloodshed and violence.",
  3757. "Guns" : "Prominently features the use of guns in combat.",
  3758. "Gyaru" : "Prominently features a female character who has a distinct American-emulated fashion style, such as tanned skin, bleached hair, and excessive makeup. Also known as gal.",
  3759. "Harem" : "Main cast features one male character plus several female characters who are romantically interested in him.",
  3760. "Henshin" : "Prominently features character or costume transformations which often grant special abilities.",
  3761. "Hikikomori" : "Prominently features a character who withdraws from social life, often seeking extreme isolation.",
  3762. "Historical" : "Partly or completely set during a real period of world history.",
  3763. "Human Pet" : "Features characters in a master-slave relationship where one is the \"owner\" and the other is a \"pet.\"",
  3764. "Ice Skating" : "Centers around the sport of ice skating.",
  3765. "Idol" : "Centers around the life and activities of an idol.",
  3766. "Incest" : "Features sexual relations between characters who are related by blood.",
  3767. "Irrumatio" : "Oral rape; features a character thrusting their genitalia into the mouth of another character.",
  3768. "Isekai" : "Features characters being transported into an alternate world setting and having to adapt to their new surroundings.",
  3769. "Iyashikei" : "Primary aim is to heal the audience through serene depictions of characters' daily lives.",
  3770. "Josei" : "Target demographic is adult females.",
  3771. "Kaiju" : "Prominently features giant monsters.",
  3772. "Karuta" : "Centers around the game of karuta.",
  3773. "Kemonomimi" : "Prominently features humanoid characters with animal ears.",
  3774. "Kids" : "Target demographic is young children.",
  3775. "Lacrosse" : "A team game played with a ball and lacrosse sticks.",
  3776. "Large Breasts" : "Features a character with larger-than-average breasts.",
  3777. "LGBTQ Issues" : "Addresses themes of LGBTQ experiences and identity; such as characters questioning their sexuality or gender identity, coming out to friends and family, and dealing with prejudice.",
  3778. "Lost Civilisation" : "Featuring a civilisation with few ruins or records that exist in present day knowledge.",
  3779. "Love Triangle" : "Centered around romantic feelings between more than two people. Includes all love polygons.",
  3780. "Mafia" : "Centered around Italian organised crime syndicates.",
  3781. "Magic" : "Prominently features magical elements or the use of magic.",
  3782. "Mahjong" : "Centered around the game of mahjong.",
  3783. "Maids" : "Prominently features a character who is a maid.",
  3784. "Male Protagonist" : "Main character is male.",
  3785. "Martial Arts" : "Centers around the use of traditional hand-to-hand combat.",
  3786. "Masturbation" : "Features erotic stimulation of one's own genitalia or other erogenous regions.",
  3787. "Memory Manipulation" : "Prominently features a character(s) who has had their memories altered.",
  3788. "Meta" : "Features fourth wall-breaking references to itself or genre tropes.",
  3789. "Miko" : "Prominently features a character who is a shrine maiden.",
  3790. "MILF" : "Features sexual intercourse with older women.",
  3791. "Military" : "Centered around the life and activities of military personnel.",
  3792. "Monster Girl" : "Prominently features a female character who is part-monster.",
  3793. "Mopeds" : "Prominently features mopeds.",
  3794. "Motorcycles" : "Prominently features the use of motorcycles.",
  3795. "Musical" : "Features a performance that combines songs, spoken dialogue, acting, and dance.",
  3796. "Mythology" : "Prominently features mythological elements, especially those from religious or cultural tradition.",
  3797. "Nakadashi" : "Creampie; features sexual ejaculation inside of a character.",
  3798. "Nekomimi" : "Humanoid characters with cat-like features such as cat ears and a tail.",
  3799. "Netorare" : "NTR; features a character with a partner shown being intimate with someone else.",
  3800. "Netorase" : "Features characters in a romantic relationship who agree to be sexually intimate with others.",
  3801. "Netori" : "Features a character shown being intimate with the partner of another character. The opposite of netorare.",
  3802. "Ninja" : "Prominently features Japanese warriors traditionally trained in espionage, sabotage and assasination.",
  3803. "No Dialogue" : "This work contains no dialogue.",
  3804. "Noir" : "Stylized as a cynical crime drama with low-key visuals.",
  3805. "Nudity" : "Features a character wearing no clothing or exposing intimate body parts.",
  3806. "Otaku Culture" : "Centers around the culture of a fanatical fan-base.",
  3807. "Outdoor" : "Centers around hiking, camping or other outdoor activities.",
  3808. "Paizuri" : "Features the stimulation of male genitalia by breasts.",
  3809. "Parody" : "Features deliberate exaggeration of popular tropes or a particular genre to comedic effect.",
  3810. "Philosophy" : "Relating or devoted to the study of the fundamental nature of knowledge, reality, and existence.",
  3811. "Photography" : "Centers around the use of cameras to capture photos.",
  3812. "Pirates" : "Prominently features sea-faring adventurers branded as criminals by the law.",
  3813. "Poker" : "Centers around the game of poker or its variations.",
  3814. "Police" : "Centers around the life and activities of law enforcement officers.",
  3815. "Politics" : "Centers around politics, politicians, or government activities.",
  3816. "Post-Apocalyptic" : "Partly or completely set in a world or civilization after a global disaster.",
  3817. "POV" : "Point of View; features sexual scenes shown from the perspective of the series protagonist.",
  3818. "Pregnant" : "Features pregnant female characters in a sexual context.",
  3819. "Primarily Adult Cast" : "Main cast is mostly composed of characters above a high school age.",
  3820. "Primarily Child Cast" : "Main cast is mostly composed of characters below a high school age.",
  3821. "Primarily Female Cast" : "Main cast is mostly composed of female characters.",
  3822. "Primarily Male Cast" : "Main cast is mostly composed of male characters.",
  3823. "Prostitution" : "Features characters who are paid for sexual favors.",
  3824. "Public Sex" : "Features sexual acts performed in public settings.",
  3825. "Puppetry" : "Animation style involving the manipulation of puppets to act out scenes.",
  3826. "Rakugo" : "Rakugo is the traditional Japanese performance art of comic storytelling.",
  3827. "Rape" : "Features non-consensual sexual penetration.",
  3828. "Real Robot" : "Prominently features mechanical designs loosely influenced by real-world robotics.",
  3829. "Rehabilitation" : "Prominently features the recovery of a character who became incapable of social life or work.",
  3830. "Reincarnation" : "Features a character being born again after death, typically as another person or in another world.",
  3831. "Revenge" : "Prominently features a character who aims to exact punishment in a resentful or vindictive manner.",
  3832. "Reverse Harem" : "Main cast features one female character plus several male characters who are romantically interested in her.",
  3833. "Robots" : "Prominently features humanoid machines.",
  3834. "Rugby" : "Centers around the sport of rugby.",
  3835. "Rural" : "Partly or completely set in the countryside.",
  3836. "Samurai" : "Prominently features warriors of medieval Japanese nobility bound by a code of honor.",
  3837. "Satire" : "Prominently features the use of comedy or ridicule to expose and criticise social phenomena.",
  3838. "Scat" : "Lots of feces.",
  3839. "School" : "Partly or completely set in a primary or secondary educational institution.",
  3840. "School Club" : "Partly or completely set in a school club scene.",
  3841. "Seinen" : "Target demographic is adult males.",
  3842. "Sex Toys" : "Features objects that are designed to stimulate sexual pleasure.",
  3843. "Ships" : "Prominently features the use of sea-based transportation vessels.",
  3844. "Shogi" : "Centers around the game of shogi.",
  3845. "Shoujo" : "Target demographic is teenage and young adult females.",
  3846. "Shoujo Ai" : "Prominently features romance between two females.",
  3847. "Shounen" : "Target demographic is teenage and young adult males.",
  3848. "Shounen Ai" : "Prominently features romance between two males.",
  3849. "Skeleton" : "Prominently features skeleton(s) as a character.",
  3850. "Slapstick" : "Prominently features comedy based on deliberately clumsy actions or embarrassing events.",
  3851. "Slavery" : "Prominently features slaves, slavery, or slave trade.",
  3852. "Space" : "Partly or completely set in outer space.",
  3853. "Space Opera" : "Centers around space warfare, advanced technology, chivalric romance and adventure.",
  3854. "Steampunk" : "Prominently features technology and designs inspired by 19th-century industrial steam-powered machinery.",
  3855. "Stop Motion" : "Animation style characterized by physical objects being moved incrementally between frames to create the illusion of movement.",
  3856. "Sumata" : "Pussyjob; features the stimulation of male genitalia by the thighs and labia majora of a female character.",
  3857. "Super Power" : "Prominently features characters with special abilities that allow them to do what would normally be physically or logically impossible.",
  3858. "Super Robot" : "Prominently features large robots often piloted by hot-blooded protagonists.",
  3859. "Superhero" : "Prominently features super-powered humans who aim to serve the greater good.",
  3860. "Surreal Comedy" : "Prominently features comedic moments that defy casual reasoning, resulting in illogical events.",
  3861. "Survival" : "Centers around the struggle to live in spite of extreme obstacles.",
  3862. "Swimming" : "Centers around the sport of swimming.",
  3863. "Swordplay" : "Prominently features the use of swords in combat.",
  3864. "Table Tennis" : "Centers around the sport of table tennis (also known as \"ping pong\").",
  3865. "Tanks" : "Prominently features the use of tanks or other armoured vehicles.",
  3866. "Teacher" : "Protagonist is an educator, usually in a school setting.",
  3867. "Tekoki" : "Handjob; features the stimulation of genitalia by another's hands.",
  3868. "Tennis" : "Centers around the sport of tennis.",
  3869. "Tentacles" : "Features the long appendages most commonly associated with octopuses or squid, often sexually penetrating a character.",
  3870. "Terrorism" : "Centers around the activities of a terrorist or terrorist organization.",
  3871. "Threesome" : "Features sexual acts between three people.",
  3872. "Time Manipulation" : "Prominently features time-traveling or other time-warping phenomena.",
  3873. "Time Skip" : "Features a gap in time used to advance the story.",
  3874. "Tragedy" : "Centers around tragic events and unhappy endings.",
  3875. "Trains" : "Prominently features trains.",
  3876. "Triads" : "Centered around Chinese organised crime syndicates.",
  3877. "Tsundere" : "Prominently features a character who acts cold and hostile in order to mask warmer emotions.",
  3878. "Twins" : "Prominently features two siblings that were born at one birth.",
  3879. "Urban Fantasy" : "Set in a world similar to the real world, but with the existence of magic or other supernatural elements.",
  3880. "Urination" : "Features one character urinating on another. Also know as a \"golden shower.\"",
  3881. "Vampire" : "Prominently features a character who is a vampire.",
  3882. "Video Games" : "Centers around characters playing video games.",
  3883. "Virgin" : "Features a character who has never had sexual relations (until now).",
  3884. "Virtual World" : "Partly or completely set in the world inside a video game.",
  3885. "Volleyball" : "Centers around the sport of volleyball.",
  3886. "Voyeur" : "Features a character who enjoys seeing the sex acts or sex organs of others.",
  3887. "War" : "Partly or completely set during wartime.",
  3888. "Witch" : "Prominently features a character who is a witch.",
  3889. "Work" : "Centers around the activities of a certain occupation.",
  3890. "Wrestling" : "Centers around the sport of wrestling.",
  3891. "Writing" : "Centers around the profession of writing books or novels.",
  3892. "Wuxia" : "Chinese fiction concerning the adventures of martial artists in Ancient China.",
  3893. "Yakuza" : "Centered around Japanese organised crime syndicates.",
  3894. "Yandere" : "Prominently features a character who is obsessively in love with another, to the point of acting deranged or violent.",
  3895. "Yaoi" : "Features sexual intercourse between two males.",
  3896. "Youkai" : "Prominently features supernatural creatures from Japanese folklore.",
  3897. "Yuri" : "Prominently features romance between two females, not inherently sexual. Also known as Girls' Love.",
  3898. "Zombie" : "Prominently features reanimated corpses which often prey on live humans and turn them into zombies."
  3899.  
  3900. };
  3901.  
  3902. var userRecsList = {
  3903. "16":[{"n":"Dunkan85","s":[{"id":10460,"n":"Kimi to Boku."}]}],"19":[{"n":"hoh","s":[{"id":1483,"n":"Master Keaton"}]}],"158":[{"n":"Dunkan85","s":[{"id":101573,"n":"Yagate Kimi ni Naru"}]}],"210":[{"n":"hoh","s":[{"id":1293,"n":"Urusei Yatsura"}]},{"n":"hoh","s":[{"id":691,"n":"Yawara!"}]}],"227":[{"n":"hoh","s":[{"id":974,"n":"Dead Leaves"}]}],"245":[{"n":"hoh","s":[{"id":268,"n":"Golden Boy"}]}],"267":[{"n":"Erwin","s":[{"id":889,"n":"Black Lagoon"},{"id":1519,"n":"Black Lagoon: The Second Barrage"},{"id":14719,"n":"JoJo no Kimyou na Bouken"},{"id":20474,"n":"JoJo no Kimyou na Bouken: Stardust Crusaders"},{"id":20773,"n":"Gangsta."},{"id":20799,"n":"JoJo no Kimyou na Bouken: Stardust Crusaders - Egypt-hen"},{"id":21450,"n":"JoJo no Kimyou na Bouken: Diamond wa Kudakenai"},{"id":100388,"n":"BANANA FISH"},{"id":102883,"n":"JoJo no Kimyou na Bouken: Ougon no Kaze"}]}],"268":[{"n":"hoh","s":[{"id":245,"n":"Great Teacher Onizuka"}]}],"283":[{"n":"hoh","s":[{"id":2225,"n":"Alps no Shoujo Heidi"}]}],"302":[{"n":"hoh","s":[{"id":513,"n":"Tenkuu no Shiro Laputa"},{"id":1251,"n":"Fushigi no Umi no Nadia"}]}],"437":[{"n":"hoh","s":[{"id":759,"n":"Tokyo Godfathers"},{"id":1033,"n":"Sennen Joyuu"},{"id":1943,"n":"Paprika"}]}],"440":[{"n":"hoh","s":[{"id":10721,"n":"Mawaru Penguindrum"},{"id":20827,"n":"Yuri Kuma Arashi"}]}],"469":[{"n":"Dunkan85","s":[{"id":21033,"n":"Jitsu wa Watashi wa"}]}],"486":[{"n":"Dunkan85","s":[{"id":21823,"n":"ACCA: 13-ku Kansatsu-ka"}]}],"513":[{"n":"hoh","s":[{"id":302,"n":"Mirai Shounen Conan"},{"id":1251,"n":"Fushigi no Umi no Nadia"}]}],"543":[{"n":"shuurei","s":[{"id":885,"n":"Tenshi no Tamago"}]}],"578":[{"n":"hoh","s":[{"id":2753,"n":"Ushiro no Shoumen Daare"}]}],"604":[{"n":"hoh","s":[{"id":2044,"n":"Mahou no Tenshi Creamy Mami"}]}],"665":[{"n":"hoh","s":[{"id":20474,"n":"JoJo no Kimyou na Bouken: Stardust Crusaders"}]}],"666":[{"n":"hoh","s":[{"id":20799,"n":"JoJo no Kimyou na Bouken: Stardust Crusaders - Egypt-hen"}]},{"n":"hoh","s":[{"id":967,"n":"Hokuto no Ken"}]}],"691":[{"n":"hoh","s":[{"id":210,"n":"Ranma ½"}]}],"759":[{"n":"hoh","s":[{"id":437,"n":"Perfect Blue"},{"id":1033,"n":"Sennen Joyuu"},{"id":1943,"n":"Paprika"}]}],"785":[{"n":"hoh","s":[{"id":2050,"n":"Honoo no Tenkousei"}]}],"885":[{"n":"shuurei","s":[{"id":543,"n":"Vampire Hunter D: Bloodlust"}]},{"n":"hoh","s":[{"id":1921,"n":"Urusei Yatsura Movie 2: Beautiful Dreamer"}]}],"889":[{"n":"Erwin","s":[{"id":267,"n":"Gungrave"},{"id":1519,"n":"Black Lagoon: The Second Barrage"},{"id":14719,"n":"JoJo no Kimyou na Bouken"},{"id":20474,"n":"JoJo no Kimyou na Bouken: Stardust Crusaders"},{"id":20773,"n":"Gangsta."},{"id":20799,"n":"JoJo no Kimyou na Bouken: Stardust Crusaders - Egypt-hen"},{"id":21450,"n":"JoJo no Kimyou na Bouken: Diamond wa Kudakenai"},{"id":100388,"n":"BANANA FISH"},{"id":102883,"n":"JoJo no Kimyou na Bouken: Ougon no Kaze"}]}],"967":[{"n":"hoh","s":[{"id":666,"n":"JoJo no Kimyou na Bouken"}]}],"974":[{"n":"hoh","s":[{"id":227,"n":"FLCL"}]},{"n":"hoh","s":[{"id":6675,"n":"Redline"}]}],"1033":[{"n":"hoh","s":[{"id":437,"n":"Perfect Blue"},{"id":759,"n":"Tokyo Godfathers"},{"id":1943,"n":"Paprika"}]}],"1065":[{"n":"hoh","s":[{"id":2231,"n":"Miyuki"}]}],"1089":[{"n":"hoh","s":[{"id":1935,"n":"Megazone 23"}]}],"1251":[{"n":"hoh","s":[{"id":302,"n":"Mirai Shounen Conan"},{"id":513,"n":"Tenkuu no Shiro Laputa"}]}],"1293":[{"n":"hoh","s":[{"id":210,"n":"Ranma ½"}]}],"1462":[{"n":"hoh","s":[{"id":1951,"n":"Neo Tokyo"}]}],"1483":[{"n":"hoh","s":[{"id":19,"n":"Monster"}]}],"1519":[{"n":"Erwin","s":[{"id":267,"n":"Gungrave"},{"id":889,"n":"Black Lagoon"},{"id":14719,"n":"JoJo no Kimyou na Bouken"},{"id":20474,"n":"JoJo no Kimyou na Bouken: Stardust Crusaders"},{"id":20773,"n":"Gangsta."},{"id":20799,"n":"JoJo no Kimyou na Bouken: Stardust Crusaders - Egypt-hen"},{"id":21450,"n":"JoJo no Kimyou na Bouken: Diamond wa Kudakenai"},{"id":100388,"n":"BANANA FISH"},{"id":102883,"n":"JoJo no Kimyou na Bouken: Ougon no Kaze"}]}],"1637":[{"n":"hoh","s":[{"id":2621,"n":"Natsu e no Tobira"}]}],"1689":[{"n":"hoh","s":[{"id":21519,"n":"Kimi no Na wa."}]}],"1921":[{"n":"hoh","s":[{"id":885,"n":"Tenshi no Tamago"}]}],"1935":[{"n":"hoh","s":[{"id":1089,"n":"Choujikuu Yousai Macross: Ai Oboete Imasu ka"}]}],"1943":[{"n":"hoh","s":[{"id":437,"n":"Perfect Blue"},{"id":759,"n":"Tokyo Godfathers"},{"id":1033,"n":"Sennen Joyuu"}]}],"1951":[{"n":"hoh","s":[{"id":1462,"n":"Memories"}]}],"1961":[{"n":"hoh","s":[{"id":2199,"n":"Chirin no Suzu"}]}],"2001":[{"n":"hoh","s":[{"id":18679,"n":"Kill la Kill"}]}],"2044":[{"n":"hoh","s":[{"id":604,"n":"Mahou no Stage Fancy Lala"}]}],"2050":[{"n":"hoh","s":[{"id":785,"n":"Otaku no Video"}]}],"2199":[{"n":"hoh","s":[{"id":1961,"n":"Arashi no Yoru ni"}]}],"2225":[{"n":"hoh","s":[{"id":283,"n":"Akage no Anne"}]}],"2231":[{"n":"hoh","s":[{"id":1065,"n":"Touch"}]}],"2621":[{"n":"hoh","s":[{"id":1637,"n":"Kaze to Ki no Uta Sanctus: Sei Naru Kana"}]}],"2694":[{"n":"hoh","s":[{"id":9996,"n":"Hyouge Mono"}]}],"2753":[{"n":"hoh","s":[{"id":578,"n":"Hotaru no Haka"}]}],"2755":[{"n":"hoh","s":[{"id":3038,"n":"Senya Ichiya Monogatari"},{"id":3220,"n":"Kanashimi no Belladonna"}]}],"3002":[{"n":"Dunkan85","s":[{"id":98314,"n":"Kakegurui"}]}],"3038":[{"n":"hoh","s":[{"id":2755,"n":"Cleopatra"},{"id":3220,"n":"Kanashimi no Belladonna"}]}],"3220":[{"n":"hoh","s":[{"id":2755,"n":"Cleopatra"},{"id":3038,"n":"Senya Ichiya Monogatari"}]}],"4081":[{"n":"Dunkan85","s":[{"id":21643,"n":"Fukigen na Mononokean"},{"id":103002,"n":"Right Places: Sono Toki, Boku no Irubeki Basho"}]}],"5081":[{"n":"RJBScarletRain","s":[{"id":101291,"n":"Seishun Buta Yarou wa Bunny Girl-senpai no Yume wo Minai"}]}],"6347":[{"n":"Dunkan85","s":[{"id":20031,"n":"D-Frag!"}]}],"6574":[{"n":"Dunkan85","s":[{"id":98503,"n":"Gakuen Babysitters"}]}],"6675":[{"n":"hoh","s":[{"id":974,"n":"Dead Leaves"}]}],"6880":[{"n":"Dunkan85","s":[{"id":10620,"n":"Mirai Nikki (TV)"}]}],"6956":[{"n":"Dunkan85","s":[{"id":97994,"n":"Blend S"}]}],"8425":[{"n":"Dunkan85","s":[{"id":8915,"n":"Dantalian no Shoka"}]}],"8426":[{"n":"Dunkan85","s":[{"id":20527,"n":"Isshuukan Friends."}]}],"8769":[{"n":"Dunkan85","s":[{"id":21685,"n":"Eromanga Sensei"},{"id":100382,"n":"Ore ga Suki nano wa Imouto dakedo Imouto ja Nai"}]}],"8915":[{"n":"Dunkan85","s":[{"id":8425,"n":"Gosick"}]}],"9996":[{"n":"hoh","s":[{"id":2694,"n":"Hidamari no Ki"}]}],"10162":[{"n":"Dunkan85","s":[{"id":21631,"n":"Udon no Kuni no Kiniro Kemari"},{"id":21659,"n":"Amaama to Inazuma"}]},{"n":"hoh","s":[{"id":12355,"n":"Ookami Kodomo no Ame to Yuki"}]}],"10460":[{"n":"Dunkan85","s":[{"id":16,"n":"Hachimitsu to Clover"}]}],"10572":[{"n":"Dunkan85","s":[{"id":97683,"n":"Tenshi no 3P!"}]}],"10620":[{"n":"Dunkan85","s":[{"id":6880,"n":"Deadman Wonderland"}]}],"10721":[{"n":"hoh","s":[{"id":440,"n":"Shoujo Kakumei Utena"},{"id":20827,"n":"Yuri Kuma Arashi"}]}],"11785":[{"n":"Dunkan85","s":[{"id":16157,"n":"Choujigen Game Neptune: The Animation"}]}],"12189":[{"n":"Dunkan85","s":[{"id":21213,"n":"Haruchika: Haruta to Chika wa Seishun Suru"}]}],"12355":[{"n":"hoh","s":[{"id":10162,"n":"Usagi Drop"}]}],"12431":[{"n":"shuurei","s":[{"id":99426,"n":"Sora yori mo Tooi Basho"}]}],"12679":[{"n":"Dunkan85","s":[{"id":20972,"n":"Shouwa Genroku Rakugo Shinjuu"}]}],"14669":[{"n":"Dunkan85","s":[{"id":14741,"n":"Chuunibyou demo Koi ga Shitai!"}]}],"14719":[{"n":"Erwin","s":[{"id":267,"n":"Gungrave"},{"id":889,"n":"Black Lagoon"},{"id":1519,"n":"Black Lagoon: The Second Barrage"},{"id":20474,"n":"JoJo no Kimyou na Bouken: Stardust Crusaders"},{"id":20773,"n":"Gangsta."},{"id":20799,"n":"JoJo no Kimyou na Bouken: Stardust Crusaders - Egypt-hen"},{"id":21450,"n":"JoJo no Kimyou na Bouken: Diamond wa Kudakenai"},{"id":100388,"n":"BANANA FISH"},{"id":102883,"n":"JoJo no Kimyou na Bouken: Ougon no Kaze"}]},{"n":"Dunkan85","s":[{"id":99699,"n":"Golden Kamui"}]}],"14741":[{"n":"Dunkan85","s":[{"id":14669,"n":"Aura: Maryuuinkouga Saigo no Tatakai"}]}],"14813":[{"n":"Dunkan85","s":[{"id":101291,"n":"Seishun Buta Yarou wa Bunny Girl-senpai no Yume wo Minai"}]}],"15061":[{"n":"ScarletFairy","s":[{"id":20742,"n":"PriPara"}]}],"16157":[{"n":"Dunkan85","s":[{"id":11785,"n":"Haiyore! Nyaruko-san"}]}],"17549":[{"n":"Dunkan85","s":[{"id":21284,"n":"Flying Witch"}]}],"18679":[{"n":"hoh","s":[{"id":2001,"n":"Tengen Toppa Gurren Lagann"}]}],"20031":[{"n":"Dunkan85","s":[{"id":6347,"n":"Baka to Test to Shoukanjuu"}]}],"20474":[{"n":"Erwin","s":[{"id":267,"n":"Gungrave"},{"id":889,"n":"Black Lagoon"},{"id":1519,"n":"Black Lagoon: The Second Barrage"},{"id":14719,"n":"JoJo no Kimyou na Bouken"},{"id":20773,"n":"Gangsta."},{"id":20799,"n":"JoJo no Kimyou na Bouken: Stardust Crusaders - Egypt-hen"},{"id":21450,"n":"JoJo no Kimyou na Bouken: Diamond wa Kudakenai"},{"id":100388,"n":"BANANA FISH"},{"id":102883,"n":"JoJo no Kimyou na Bouken: Ougon no Kaze"}]},{"n":"hoh","s":[{"id":665,"n":"JoJo no Kimyou na Bouken (2000)"}]}],"20517":[{"n":"Dunkan85","s":[{"id":97994,"n":"Blend S"}]}],"20527":[{"n":"Dunkan85","s":[{"id":8426,"n":"Hourou Musuko"}]},{"n":"Dunkan85","s":[{"id":21495,"n":"Tanaka-kun wa Itsumo Kedaruge"}]}],"20742":[{"n":"ScarletFairy","s":[{"id":15061,"n":"Aikatsu!"}]}],"20773":[{"n":"Erwin","s":[{"id":267,"n":"Gungrave"},{"id":889,"n":"Black Lagoon"},{"id":1519,"n":"Black Lagoon: The Second Barrage"},{"id":14719,"n":"JoJo no Kimyou na Bouken"},{"id":20474,"n":"JoJo no Kimyou na Bouken: Stardust Crusaders"},{"id":20799,"n":"JoJo no Kimyou na Bouken: Stardust Crusaders - Egypt-hen"},{"id":21450,"n":"JoJo no Kimyou na Bouken: Diamond wa Kudakenai"},{"id":100388,"n":"BANANA FISH"},{"id":102883,"n":"JoJo no Kimyou na Bouken: Ougon no Kaze"}]}],"20799":[{"n":"Erwin","s":[{"id":267,"n":"Gungrave"},{"id":889,"n":"Black Lagoon"},{"id":1519,"n":"Black Lagoon: The Second Barrage"},{"id":14719,"n":"JoJo no Kimyou na Bouken"},{"id":20474,"n":"JoJo no Kimyou na Bouken: Stardust Crusaders"},{"id":20773,"n":"Gangsta."},{"id":21450,"n":"JoJo no Kimyou na Bouken: Diamond wa Kudakenai"},{"id":100388,"n":"BANANA FISH"},{"id":102883,"n":"JoJo no Kimyou na Bouken: Ougon no Kaze"}]},{"n":"hoh","s":[{"id":666,"n":"JoJo no Kimyou na Bouken"}]}],"20827":[{"n":"hoh","s":[{"id":440,"n":"Shoujo Kakumei Utena"},{"id":10721,"n":"Mawaru Penguindrum"}]}],"20912":[{"n":"Dunkan85","s":[{"id":21213,"n":"Haruchika: Haruta to Chika wa Seishun Suru"}]}],"20923":[{"n":"Dunkan85","s":[{"id":21204,"n":"Wakako-zake"},{"id":97617,"n":"Isekai Shokudou"}]}],"20972":[{"n":"Dunkan85","s":[{"id":12679,"n":"Joshiraku"}]}],"21033":[{"n":"Dunkan85","s":[{"id":469,"n":"Karin"}]}],"21108":[{"n":"Dunkan85","s":[{"id":21315,"n":"Pan de Peace!"}]}],"21171":[{"n":"Dunkan85","s":[{"id":21197,"n":"Bakuon!!"}]}],"21197":[{"n":"Dunkan85","s":[{"id":21171,"n":"Long Riders!"}]}],"21204":[{"n":"Dunkan85","s":[{"id":20923,"n":"Shokugeki no Souma"},{"id":97617,"n":"Isekai Shokudou"}]}],"21213":[{"n":"Dunkan85","s":[{"id":12189,"n":"Hyouka"}]},{"n":"Dunkan85","s":[{"id":20912,"n":"Hibike! Euphonium"}]}],"21284":[{"n":"Dunkan85","s":[{"id":17549,"n":"Non Non Biyori"}]}],"21291":[{"n":"Dunkan85","s":[{"id":98505,"n":"Princess Principal"},{"id":101014,"n":"RELEASE THE SPYCE"}]}],"21315":[{"n":"Dunkan85","s":[{"id":21108,"n":"Wakaba*Girl"}]}],"21450":[{"n":"Erwin","s":[{"id":267,"n":"Gungrave"},{"id":889,"n":"Black Lagoon"},{"id":1519,"n":"Black Lagoon: The Second Barrage"},{"id":14719,"n":"JoJo no Kimyou na Bouken"},{"id":20474,"n":"JoJo no Kimyou na Bouken: Stardust Crusaders"},{"id":20773,"n":"Gangsta."},{"id":20799,"n":"JoJo no Kimyou na Bouken: Stardust Crusaders - Egypt-hen"},{"id":100388,"n":"BANANA FISH"},{"id":102883,"n":"JoJo no Kimyou na Bouken: Ougon no Kaze"}]}],"21455":[{"n":"Dunkan85","s":[{"id":21597,"n":"Stella no Mahou"}]}],"21495":[{"n":"Dunkan85","s":[{"id":20527,"n":"Isshuukan Friends."}]}],"21519":[{"n":"hoh","s":[{"id":1689,"n":"Byousoku 5 Centimeter"}]}],"21597":[{"n":"Dunkan85","s":[{"id":21455,"n":"New Game!"}]}],"21613":[{"n":"Dunkan85","s":[{"id":21838,"n":"Shuumatsu no Izetta"}]}],"21631":[{"n":"Dunkan85","s":[{"id":10162,"n":"Usagi Drop"},{"id":21659,"n":"Amaama to Inazuma"}]}],"21643":[{"n":"Dunkan85","s":[{"id":4081,"n":"Natsume Yuujinchou"},{"id":103002,"n":"Right Places: Sono Toki, Boku no Irubeki Basho"}]}],"21659":[{"n":"Dunkan85","s":[{"id":10162,"n":"Usagi Drop"},{"id":21631,"n":"Udon no Kuni no Kiniro Kemari"}]}],"21685":[{"n":"Dunkan85","s":[{"id":8769,"n":"Ore no Imouto ga Konna ni Kawaii Wake ga Nai"},{"id":100382,"n":"Ore ga Suki nano wa Imouto dakedo Imouto ja Nai"}]}],"21731":[{"n":"Dunkan85","s":[{"id":99720,"n":"Märchen Mädchen"},{"id":100382,"n":"Ore ga Suki nano wa Imouto dakedo Imouto ja Nai"}]}],"21823":[{"n":"Dunkan85","s":[{"id":486,"n":"Kino no Tabi: The Beautiful World"}]}],"21835":[{"n":"Dunkan85","s":[{"id":102875,"n":"Himote House"}]}],"21838":[{"n":"Dunkan85","s":[{"id":21613,"n":"Youjo Senki"}]}],"97592":[{"n":"Dunkan85","s":[{"id":101371,"n":"Tonari no Kyuuketsuki-san"}]}],"97617":[{"n":"Dunkan85","s":[{"id":20923,"n":"Shokugeki no Souma"},{"id":21204,"n":"Wakako-zake"}]}],"97683":[{"n":"Dunkan85","s":[{"id":10572,"n":"Ro-Kyu-Bu!"}]}],"97994":[{"n":"Dunkan85","s":[{"id":6956,"n":"Working!!"}]},{"n":"Dunkan85","s":[{"id":20517,"n":"Gochuumon wa Usagi Desu ka?"}]}],"98314":[{"n":"Dunkan85","s":[{"id":3002,"n":"Gyakkyou Burai Kaiji: Ultimate Survivor"}]}],"98503":[{"n":"Dunkan85","s":[{"id":6574,"n":"Hanamaru Youchien"}]}],"98505":[{"n":"Dunkan85","s":[{"id":21291,"n":"Joker Game"},{"id":101014,"n":"RELEASE THE SPYCE"}]}],"98820":[{"n":"Dunkan85","s":[{"id":98977,"n":"Itsudatte Bokura no Koi wa 10cm datta"}]}],"98977":[{"n":"Dunkan85","s":[{"id":98820,"n":"Just Because!"}]}],"99426":[{"n":"shuurei","s":[{"id":12431,"n":"Uchuu Kyoudai"}]}],"99699":[{"n":"Dunkan85","s":[{"id":14719,"n":"JoJo no Kimyou na Bouken"}]}],"99720":[{"n":"Dunkan85","s":[{"id":21731,"n":"Hand Shakers"},{"id":100382,"n":"Ore ga Suki nano wa Imouto dakedo Imouto ja Nai"}]}],"100382":[{"n":"Dunkan85","s":[{"id":8769,"n":"Ore no Imouto ga Konna ni Kawaii Wake ga Nai"},{"id":21685,"n":"Eromanga Sensei"}]},{"n":"Dunkan85","s":[{"id":21731,"n":"Hand Shakers"},{"id":99720,"n":"Märchen Mädchen"}]}],"100388":[{"n":"Erwin","s":[{"id":267,"n":"Gungrave"},{"id":889,"n":"Black Lagoon"},{"id":1519,"n":"Black Lagoon: The Second Barrage"},{"id":14719,"n":"JoJo no Kimyou na Bouken"},{"id":20474,"n":"JoJo no Kimyou na Bouken: Stardust Crusaders"},{"id":20773,"n":"Gangsta."},{"id":20799,"n":"JoJo no Kimyou na Bouken: Stardust Crusaders - Egypt-hen"},{"id":21450,"n":"JoJo no Kimyou na Bouken: Diamond wa Kudakenai"},{"id":102883,"n":"JoJo no Kimyou na Bouken: Ougon no Kaze"}]}],"100665":[{"n":"Dunkan85","s":[{"id":100715,"n":"Mahou Shoujo Ore"}]}],"100715":[{"n":"Dunkan85","s":[{"id":100665,"n":"Back Street Girls: Gokudolls"}]}],"101014":[{"n":"Dunkan85","s":[{"id":21291,"n":"Joker Game"},{"id":98505,"n":"Princess Principal"}]}],"101291":[{"n":"RJBScarletRain","s":[{"id":5081,"n":"Bakemonogatari"}]},{"n":"Dunkan85","s":[{"id":14813,"n":"Yahari Ore no Seishun Love Comedy wa Machigatteiru."}]}],"101371":[{"n":"Dunkan85","s":[{"id":97592,"n":"Demi-chan wa Kataritai"}]}],"101573":[{"n":"Dunkan85","s":[{"id":158,"n":"Maria-sama ga Miteru"}]}],"102875":[{"n":"Dunkan85","s":[{"id":21835,"n":"Mahou Shoujo? Naria☆Girls"}]}],"102883":[{"n":"Erwin","s":[{"id":267,"n":"Gungrave"},{"id":889,"n":"Black Lagoon"},{"id":1519,"n":"Black Lagoon: The Second Barrage"},{"id":14719,"n":"JoJo no Kimyou na Bouken"},{"id":20474,"n":"JoJo no Kimyou na Bouken: Stardust Crusaders"},{"id":20773,"n":"Gangsta."},{"id":20799,"n":"JoJo no Kimyou na Bouken: Stardust Crusaders - Egypt-hen"},{"id":21450,"n":"JoJo no Kimyou na Bouken: Diamond wa Kudakenai"},{"id":100388,"n":"BANANA FISH"}]}],"103002":[{"n":"Dunkan85","s":[{"id":4081,"n":"Natsume Yuujinchou"},{"id":21643,"n":"Fukigen na Mononokean"}]}]
  3904. ,"99748":[{n:"midnightbreeze",s:[{n:"Yuru Camp△",id:98444}]}],"98444":[{n:"midnightbreeze",s:[{n:"Hakumei to Mikochi",id:99748}]}],"658":[{n:"Erwin",s:[{n:"Gyakkyou Burai Kaiji: Ultimate Survivor",id:3002}]}],"3002":[{n:"Erwin",s:[{n:"Touhai Densetsu Akagi: Yami ni Maiorita Tensai",id:658}]}],"30642":[{n:"Erwin",s:[{n:"Berserk",id:30002}]}],"30002":[{n:"Erwin",s:[{n:"Vinland Saga",id:30642}]}],"15061":[{n:"ScarletFairy",s:[{n:"PriPara",id:20742}]}],"20742":[{n:"ScarletFairy",s:[{n:"Aikatsu!",id:15061}]}],"15037":[{n:"ScarletFairy",s:[{n:"Another",id:11111}]}],"11111":[{n:"ScarletFairy",s:[{n:"Corpse Party: Tortured Souls - Bougyakusareta Tamashii no Jukyou",id:15037}]}],"6547":[{n:"ScarletFairy",s:[{n:"Charlotte",id:20997}]}],"20997":[{n:"ScarletFairy",s:[{n:"Angel Beats!",id:6547}]}],"5680":[{n:"ScarletFairy",s:[{n:"Sora yori mo Tooi Basho",id:99426}]}],"99426":[{n:"ScarletFairy",s:[{n:"K-On!",id:5680}]}],"98658":[{n:"ScarletFairy",s:[{n:"Mahou Shoujo Madoka★Magica",id:9756}]}],"9756":[{n:"ScarletFairy",s:[{n:"Shoujo☆Kageki Revue Starlight",id:98658}]}],"97592":[{n:"ScarletFairy",s:[{n:"Centaur no Nayami",id:98519}]}],"98519":[{n:"ScarletFairy",s:[{n:"Demi-chan wa Kataritai",id:97592}]}],"21858":[{n:"ScarletFairy",s:[{n:"Mary to Majo no Hana",id:97981}]}],"97981":[{n:"ScarletFairy",s:[{n:"Little Witch Academia (TV)",id:21858}]}],"8129":[{n:"ScarletFairy",s:[{n:"Kimi ni Todoke",id:6045}]}],"6045":[{n:"ScarletFairy",s:[{n:"Kuragehime",id:8129}]}],"21685":[{n:"ScarletFairy",s:[{n:"Ore no Imouto ga Konna ni Kawaii Wake ga Nai",id:8769},{n:"Imouto sae Ireba Ii.",id:98596},]}],"98596":[{n:"ScarletFairy",s:[{n:"Ore no Imouto ga Konna ni Kawaii Wake ga Nai",id:8769},{n:"Eromanga Sensei",id:21685},]}],"8769":[{n:"ScarletFairy",s:[{n:"Imouto sae Ireba Ii.",id:98596},{n:"Eromanga Sensei",id:21685},]}],"21787":[{n:"ScarletFairy",s:[{n:"Two Car",id:99672},{n:"Ange Vierge",id:21439}]}],"21439":[{n:"ScarletFairy",s:[{n:"Two Car",id:99672},{n:"Battle Girl High School",id:21787}]}],"99672":[{n:"ScarletFairy",s:[{n:"Ange Vierge",id:21439},{n:"Battle Girl High School",id:21787}]}],"14513":[{n:"ScarletFairy",s:[{n:"Fairy Tail",id:6702},{n:"Nanatsu no Taizai",id:20789}]}],"20789":[{n:"ScarletFairy",s:[{n:"Fairy Tail",id:6702},{n:"Magi: The Labyrinth of Magic",id:14513}]}],"6702":[{n:"ScarletFairy",s:[{n:"Nanatsu no Taizai",id:20789},{n:"Magi: The Labyrinth of Magic",id:14513}]}]};
  3905. console.log("Aniscripts " + scriptVersion);
  3906. })();
  3907.  

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址