rzscript

Versión actualizada de MZScript

  1. // ==UserScript==
  2. // @name rzscript
  3. // @namespace rzscript
  4. // @description Versión actualizada de MZScript
  5. // @homepage https://github.com/rhonaldomaster/rzscript
  6. // @include https://www.managerzone.com/?p=
  7. // @grant none
  8. // @version 0.2
  9. // @copyright GNU/GPL v3
  10. // @author rhonaldomaster
  11. // @credits c_c, serbocapo
  12. // @license GPL-3.0-or-later
  13. // @compatible chrome
  14. // @compatible firefox
  15. // @compatible opera
  16. // @compatible safari
  17. // @compatible edge
  18. // ==/UserScript==
  19. const rzscript = (() => {
  20. const sports = ['', 'soccer', 'hockey'];
  21.  
  22. const init = () => {
  23. setStyles();
  24. createQuickLinks();
  25. createForumLinks();
  26. setPageFunctions();
  27. setEvents();
  28. addTeamBadgeToPlayers();
  29. };
  30.  
  31. const setStyles = () => {
  32. const css =
  33. '#pt-wrapper{bottom:52px;filter:alpha(opacity=50);opacity:0.5;}#notifications-wrapper{bottom:-2px;}' +
  34. '.quicklink{background-color:#4A4A4A;border:0;border-radius:4px;box-shadow:0 0 1px 0 #000;color:#FFF;cursor:pointer;display:inline-block;margin-left:4px;padding:2px 4px;text-decoration:none;}' +
  35. '.quicklink:hover{background-color:#000000;box-shadow:0 0 2px 0 #000000;color:#FFFFFF;text-decoration:none;}' +
  36. '.pagelinks{padding:0 4px 8px;}' +
  37. '.quicklinks{text-align:center;}' +
  38. '#fluid-menu-opener > div.sport-line,#top-wrapper-sport-line{background:#5d5b5f none repeat scroll 0 0;}' +
  39. '.preview-results{border:2px solid #2A4CB0;cursor:pointer;float:right;height:20px;padding:4px 0 0 4px;width:20px;}' +
  40. '.bbcode{margin:auto;max-width:640px;}' +
  41. '.player-image.soccer{position: relative;}' +
  42. '.player-image.soccer .player-team-badge{background-position: center; height: auto; padding: 5px; position: absolute; right: 24px; top: 44px; width: auto;}';
  43. if (typeof GM_addStyle != 'undefined') {
  44. GM_addStyle(css);
  45. return;
  46. } else if (typeof PRO_addStyle != 'undefined') {
  47. PRO_addStyle(css);
  48. return;
  49. } else if (typeof addStyle != 'undefined') {
  50. addStyle(css);
  51. return;
  52. }
  53. let heads = document.querySelectorAll('head');
  54. if (heads.length < 1) {
  55. return;
  56. }
  57. let node = document.createElement('style');
  58. node.appendChild(document.createTextNode(css));
  59. heads[0].appendChild(node);
  60. };
  61.  
  62. // Quick links
  63. const createButtonLinks = (data) => {
  64. const container = document.querySelector(data.selector);
  65. if (container) {
  66. return;
  67. }
  68. let html =
  69. '<div ' +
  70. (data.selector.charAt(0) == '.' ? 'class' : 'id') +
  71. '="' +
  72. data.selector.replace(/\./g, '') +
  73. '">';
  74. html += data.links.reduce((prev, curr) => {
  75. return (
  76. prev +
  77. '<a class="quicklink" href="' +
  78. curr.url +
  79. '"' +
  80. (curr.url.indexOf('?p=') < 0 ? ' target="_blank"' : '') +
  81. ' title="' +
  82. curr.title +
  83. '">' +
  84. curr.text +
  85. '</a>'
  86. );
  87. }, '');
  88. html += '</div>';
  89. data.wrapper.insertAdjacentHTML(data.prepend ? 'afterbegin' : 'beforeend', html);
  90. };
  91.  
  92. const createForumLinks = () => {
  93. const options = {
  94. selector: '.js-forum-buttons',
  95. wrapper: document.querySelector('#notifications-wrapper'),
  96. links: [
  97. {
  98. text: 'MER',
  99. title: 'Mercado(Transfers)',
  100. url: '?p=forum&sub=topics&forum_id=254&sport=soccer'
  101. },
  102. { text: 'AMI', title: 'Amistosos', url: '?p=forum&sub=topics&forum_id=249&sport=soccer' },
  103. { text: 'MZH', title: 'MZ Habla', url: '?p=forum&sub=topics&forum_id=253&sport=soccer' },
  104. {
  105. text: 'PYR',
  106. title: 'Preguntas y Respuestas',
  107. url: '?p=forum&sub=topics&forum_id=255&sport=soccer'
  108. },
  109. {
  110. text: 'DA',
  111. title: 'Discusi&oacute;n Abierta',
  112. url: '?p=forum&sub=topics&forum_id=250&sport=soccer'
  113. },
  114. {
  115. text: 'FED',
  116. title: 'Federaciones',
  117. url: '?p=forum&sub=topics&forum_id=251&sport=soccer'
  118. },
  119. {
  120. text: 'HDC',
  121. title: 'Hablemos de copas',
  122. url: '?p=forum&sub=topics&forum_id=252&sport=soccer'
  123. }
  124. ],
  125. prepend: false
  126. };
  127. createButtonLinks(options);
  128. };
  129.  
  130. const createQuickLinks = () => {
  131. const options = {
  132. selector: '.pagelinks .quicklinks',
  133. wrapper: document.querySelector('#contentDiv'),
  134. links: [
  135. { text: 'Monitoreo', title: 'Monitoreo', url: '?p=transfer&sub=yourplayers' },
  136. { text: 'Vista Alternativa', title: 'Ver Vista Alternativa', url: '?p=players&sub=alt' },
  137. { text: 'Seguimiento', title: 'Ir a Seguimiento', url: '?p=shortlist' },
  138. { text: 'Finanzas', title: 'Ver Finanzas', url: '?p=economy' },
  139. { text: 'Mercado', title: 'Ver Mercado', url: '?p=transfer' },
  140. { text: 'Jugados', title: 'Ver los Partidos Jugados', url: '?p=match&sub=played' },
  141. {
  142. text: 'Pr&oacute;ximos',
  143. title: 'Ver los Pr&oacute;ximos Partidos',
  144. url: '?p=match&sub=scheduled'
  145. },
  146. { text: 'T&aacute;cticas', title: 'Ir a T&aacute;cticas', url: '?p=tactics' },
  147. {
  148. text: 'Lesiones/Sanciones',
  149. title: 'Ver Lesionados/Sancionados',
  150. url: '?p=players&sub=unavailable'
  151. },
  152. {
  153. text: 'Reporte entr.',
  154. title: 'Ver el Reporte de Entrenamiento',
  155. url: '?p=training_report'
  156. },
  157. { text: 'Entrenamiento', title: 'Ir al Entrenamiento General', url: '?p=training' },
  158. { text: 'Skiller', title: 'Skiller MZ Player', url: 'http://mzplayer.se' },
  159. { text: 'Top 11', title: 'Ir a top11', url: 'https://oxi.se/top11/' }
  160. ],
  161. prepend: true
  162. };
  163. createButtonLinks(options);
  164. };
  165.  
  166. // End quick links
  167.  
  168. // Signature
  169. const renderSignatureDiv = () => {
  170. const signature = obtainSignature();
  171. if (signature && localStorage.getItem('showAlwaysUserSignature')) {
  172. setSignature(signature, false);
  173. }
  174. let container = document.querySelector('.bbcode');
  175. const html =
  176. '<form class="js-signature-form">' +
  177. '<table style="width:100%;">' +
  178. '<tr>' +
  179. '<td><span>Texto</span> <small>(Usa bbcode)</small></td>' +
  180. '</tr>' +
  181. '<tr>' +
  182. '<td><textarea name="signature" cols="84" rows="5" style="padding:5px;">' +
  183. (signature ? signature : '') +
  184. '</textarea></td>' +
  185. '</tr>' +
  186. '<tr>' +
  187. '<td>' +
  188. '<button type="button" class="quicklink js-signature">Agregar firma</button>' +
  189. '<button type="button" class="quicklink js-save-signature">Guardar firma</button>' +
  190. '<button type="button" class="quicklink js-delete-signature">Borrar firma</button>' +
  191. '</td>' +
  192. '</tr>' +
  193. '</table>' +
  194. '</form>';
  195. container.insertAdjacentHTML('beforeend', html);
  196. };
  197.  
  198. const setSignature = (signature, isFromForm) => {
  199. let textarea = document.querySelector('.markItUpEditor');
  200. const put = !isFromForm && textarea.value !== '' ? false : true;
  201. if (!put) {
  202. return;
  203. }
  204. textarea.value += '\r\n\r\n';
  205. for (let i = 0; i <= 50; i++) {
  206. textarea.value += '-';
  207. }
  208. textarea.value += '\r\n' + signature;
  209. resetCursor(textarea);
  210. };
  211.  
  212. const saveSignature = () => {
  213. let form = document.querySelector('.js-signature-form');
  214. form = JSON.parse(formToJSONString(form));
  215. let signature = form.signature.replace(/^(\s|\&nbsp;)*|(\s|\&nbsp;)*$/g, '');
  216. if (signature !== '' && signature.length > 0 && signature !== null) {
  217. saveUserSignature(signature);
  218. }
  219. let showAlways = window.confirm('Mostrar siempre?');
  220. if (showAlways) {
  221. localStorage.setItem('showAlwaysUserSignature', showAlways);
  222. return;
  223. }
  224. localStorage.removeItem('showAlwaysUserSignature');
  225. };
  226.  
  227. const resetCursor = (element) => {
  228. if (element.setSelectionRange) {
  229. element.focus().setSelectionRange(0, 0);
  230. } else if (element.createTextRange) {
  231. let range = element.createTextRange();
  232. range.moveStart('character', 0).select();
  233. }
  234. };
  235.  
  236. const saveUserSignature = (signature) => {
  237. const savedSignature = localStorage.getItem('userSignature');
  238. if (savedSignature != signature) {
  239. localStorage.setItem('userSignature', signature);
  240. }
  241. };
  242.  
  243. const dropSignature = () => {
  244. localStorage.removeItem('userSignature');
  245. localStorage.removeItem('showAlwaysUserSignature');
  246. alert('La firma fue eliminada');
  247. };
  248.  
  249. const putSignature = (ev) => {
  250. ev.preventDefault();
  251. let form = document.querySelector('.js-signature-form');
  252. form = JSON.parse(formToJSONString(form));
  253. let signature = form.signature.replace(/^(\s|\&nbsp;)*|(\s|\&nbsp;)*$/g, '');
  254. if (signature !== '' && signature.length > 0 && signature !== null) {
  255. setSignature(signature, true);
  256. }
  257. };
  258.  
  259. const obtainSignature = () => {
  260. let signature = '';
  261. if (localStorage.getItem('userSignature')) {
  262. signature = localStorage.getItem('userSignature');
  263. } else if (localStorage.getItem('firmaMZ')) {
  264. signature = localStorage.getItem('firmaMZ');
  265. }
  266. return signature;
  267. };
  268.  
  269. // End signature
  270.  
  271. // Matches data
  272. const linkToSeniorLeague = () => {
  273. const wrapper = document.querySelector('#match-info-wrapper');
  274. if (!wrapper) {
  275. return;
  276. }
  277. let h1 = wrapper.querySelector('h1');
  278. const text = h1.innerHTML;
  279. const i18nLeague = ['Liga', 'League'];
  280. if (i18nLeague.indexOf(text) > -1) {
  281. h1.innerHTML = '<a href="?p=league&type=senior">' + text + '</a>';
  282. }
  283. };
  284.  
  285. const getPlayerData = (teamXML, playerId) => {
  286. let player = null;
  287. const players = teamXML.getElementsByTagName('Player');
  288. for (let i = 0; i < players.length; i++) {
  289. if (playerId == players[i].getAttribute('id')) {
  290. player = players[i];
  291. }
  292. }
  293. return player;
  294. };
  295.  
  296. const playersMatchValue = () => {
  297. if (ajaxSport == 'soccer') {
  298. footballMatchValues();
  299. } else if (ajaxSport == 'hockey') {
  300. hockeyMatchValues();
  301. }
  302. };
  303.  
  304. const footballMatchValues = () => {
  305. let teamsDiv = document.querySelectorAll('.matchStats:not(.matchStats--detailed)');
  306. if (!teamsDiv) {
  307. return;
  308. }
  309.  
  310. const teamHeadings = document.querySelectorAll('.team-table');
  311. for (let i = 0; i < teamHeadings.length; i++) {
  312. const links = teamHeadings[i].querySelectorAll('a');
  313. renderFootballTeamValue(links[0].href.split('&tid=')[1], teamsDiv[i]);
  314. }
  315. };
  316.  
  317. const renderFootballTeamValue = (teamId, teamTable) => {
  318. if (!teamTable) {
  319. return;
  320. }
  321. const ajax = $.ajax({
  322. url: '/xml/team_playerlist.php',
  323. type: 'GET',
  324. data: { sport_id: sports.indexOf(ajaxSport), team_id: teamId }
  325. });
  326. ajax.done((data) => {
  327. const currency = data.getElementsByTagName('TeamPlayers')[0].getAttribute('teamCurrency');
  328. let playing11Value = 0,
  329. playing11 = 0;
  330. const firstRow = teamTable.querySelector('thead tr');
  331. const tableBody = teamTable.querySelector('tbody');
  332. const tableFoot = teamTable.querySelector('tfoot');
  333. const totalsRow = tableFoot.rows[2];
  334.  
  335. firstRow.innerHTML = '<td>Valor</td>' + firstRow.innerHTML;
  336. for (let i = 0; i < tableBody.rows.length; i++) {
  337. if (tableBody.rows[i].querySelector('img')) {
  338. tableBody.rows[i].cells[0].colSpan = '16';
  339. } else {
  340. const link = tableBody.rows[i].querySelector('a');
  341. const playerData = link
  342. ? getPlayerData(data, link.href.split('&')[1].split('=')[1])
  343. : null;
  344.  
  345. if (playerData) {
  346. let playerValue = toLocaleCurrency(playerData.getAttribute('value'), currency);
  347. playing11 += 1;
  348.  
  349. const playerNameCell = tableBody.rows[i].querySelector('.player-label')?.parentElement;
  350. if (playerNameCell) {
  351. const row = playerNameCell.parentElement;
  352. row.innerHTML =
  353. '<td style="width:62px;text-align:right;padding-right:15px">' +
  354. formatMoney(playerValue) +
  355. '</td>' +
  356. row.innerHTML;
  357. }
  358.  
  359. if (playing11 < 12) {
  360. playing11Value += playerValue;
  361. }
  362. }
  363. }
  364. }
  365. tableFoot.rows[1].cells[0].colSpan = '2';
  366. totalsRow.innerHTML = '<td>' + formatMoney(playing11Value) + '</td><td colspan="8"></td>';
  367. });
  368. };
  369.  
  370. const hockeyMatchValues = () => {
  371. let teamsDiv = document.querySelectorAll('.team-table');
  372. if (!teamsDiv) {
  373. return;
  374. }
  375. for (let i = 0; i < teamsDiv.length; i++) {
  376. let links = teamsDiv[i].querySelectorAll('a');
  377. renderHockeyTeamValue(links[0].href.split('&')[1].split('=')[1], i);
  378. }
  379. const teamHeadings = document.querySelectorAll('.team-table');
  380. for (let i = 0; i < teamHeadings.length; i++) {
  381. const links = teamHeadings[i].querySelectorAll('a');
  382. renderHockeyTeamValue(links[0].href.split('&tid=')[1], teamsDiv[i]);
  383. }
  384. };
  385.  
  386. const renderHockeyTeamValue = (teamId, teamTable) => {
  387. if (!teamTable) {
  388. return;
  389. }
  390. const ajax = $.ajax({
  391. url: '/xml/team_playerlist.php',
  392. type: 'GET',
  393. data: { sport_id: sports.indexOf(ajaxSport), team_id: teamId }
  394. });
  395. ajax.done((data) => {
  396. const currency = data.getElementsByTagName('TeamPlayers')[0].getAttribute('teamCurrency');
  397. let playing21Value = 0,
  398. playing21 = 0;
  399. let firstRow = teamTable.rows[0];
  400. let secondRow = teamTable.rows[1],
  401. tableBody = teamTable.querySelector('tbody');
  402. let tableFoot = teamTable.querySelector('tfoot'),
  403. totalsRow = tableFoot.rows[1];
  404. firstRow.cells[0].colSpan = 10;
  405. teamTable.rows[2].cells[0].colSpan = 19;
  406. secondRow.innerHTML = '<td>Valor</td>' + secondRow.innerHTML;
  407. let goalkeeperTable = document.querySelectorAll(
  408. '#match-statistics .hitlist_wrapper_background table'
  409. )[tableIndex + 1];
  410. let goalkeeperLink = goalkeeperTable.querySelector('a');
  411. let goalkeeperData = getPlayerData(data, goalkeeperLink.href.split('&')[1].split('=')[1]);
  412. let goalkeeperValue = 0;
  413. if (goalkeeperData) {
  414. goalkeeperValue = toLocaleCurrency(goalkeeperData.getAttribute('value'), currency);
  415. }
  416. for (let i = 0; i < tableBody.rows.length; i++) {
  417. if (tableBody.rows[i].querySelector('img')) {
  418. tableBody.rows[i].cells[0].colSpan = '19';
  419. } else {
  420. if (tableBody.rows[i].cells[0] !== '') {
  421. let link = tableBody.rows[i].querySelector('a');
  422. if (link) {
  423. let playerData = getPlayerData(data, link.href.split('&')[1].split('=')[1]);
  424. if (playerData) {
  425. let playerValue = toLocaleCurrency(playerData.getAttribute('value'), currency);
  426. playing21 += 1;
  427. tableBody.rows[i].innerHTML =
  428. '<td style="width:62px;text-align:right;padding-right:15px">' +
  429. formatMoney(playerValue) +
  430. '</td>' +
  431. tableBody.rows[i].innerHTML;
  432. if (playing21 < 21) {
  433. playing21Value += playerValue;
  434. }
  435. }
  436. } else {
  437. tableBody.rows[i].innerHTML =
  438. '<td style="width:62px;text-align:right;padding-right:15px"></td>' +
  439. tableBody.rows[i].innerHTML;
  440. }
  441. } else if (tableBody.rows[i].cells < 2) {
  442. tableBody.rows[i].innerHTML =
  443. '<td style="width:62px;text-align:right;padding-right:15px"></td>' +
  444. tableBody.rows[i].innerHTML;
  445. }
  446. }
  447. }
  448. totalsRow.innerHTML =
  449. '<td style="width:62px;text-align:right;padding-right:15px">' +
  450. (formatMoney(playing21Value + goalkeeperValue) +
  451. '<br><small>Incluye valor de portero</small>') +
  452. '</td>' +
  453. totalsRow.innerHTML;
  454. tableFoot.rows[3].cells[0].colSpan = '19';
  455.  
  456. let goalkeeperTableHead = goalkeeperTable.querySelector('thead');
  457. goalkeeperTableHead.rows[0].innerHTML =
  458. '<td>Valor</td>' + goalkeeperTableHead.rows[0].innerHTML;
  459. let goalkeeperTableBody = goalkeeperTable.querySelector('tbody');
  460. goalkeeperTableBody.rows[0].innerHTML =
  461. '<td style="width:62px;text-align:right;padding-right:15px">' +
  462. formatMoney(goalkeeperValue) +
  463. '</td>' +
  464. goalkeeperTableBody.rows[0].innerHTML;
  465. goalkeeperTable.querySelector('tfoot').rows[0].cells[0].colSpan = '19';
  466. });
  467. };
  468.  
  469. const previewResultsButton = () => {
  470. let container = document.querySelector('#results-fixtures-wrapper');
  471. const html =
  472. '<button type="button" class="results-fixtures-type flex-grow-0 js-preview-results">' +
  473. 'Ver resultados' +
  474. '</button>';
  475. container.insertAdjacentHTML('afterbegin', html);
  476. };
  477.  
  478. const getMatchesResults = () => {
  479. let matches = document.querySelectorAll('#fixtures-results-list > .odd');
  480. for (let i = 0; i < matches.length; i++) {
  481. let scoreBlock = matches[i].querySelector('.score-cell-wrapper > a');
  482. let tacticWrapper = $.trim(matches[i].querySelector('.set-default-wrapper').innerHTML);
  483. if (tacticWrapper === '') {
  484. let matchId = scoreBlock.href.split('&')[2].split('=')[1];
  485. renderMatchScore(matchId, scoreBlock);
  486. }
  487. }
  488. };
  489.  
  490. const renderMatchScore = (matchId, matchBlock) => {
  491. const ajax = $.ajax({
  492. url: '/xml/match_info.php',
  493. type: 'GET',
  494. data: { sport_id: sports.indexOf(ajaxSport), match_id: matchId }
  495. });
  496. ajax.done((data) => {
  497. if (data.getElementsByTagName('ManagerZone_Error')[0]) {
  498. return;
  499. }
  500. let myTeamId = matchBlock.href.split('&')[3].split('=')[1];
  501. let score = {
  502. local: data.getElementsByTagName('Team')[0].getAttribute('goals') * 1,
  503. visitor: data.getElementsByTagName('Team')[1].getAttribute('goals') * 1
  504. };
  505. matchBlock.innerHTML = score.local + ' - ' + score.visitor;
  506. if (score.local == score.visitor) {
  507. matchBlock.className = 'yellow';
  508. } else if (myTeamId == data.getElementsByTagName('Team')[0].getAttribute('id')) {
  509. matchBlock.className = score.local > score.visitor ? 'green' : 'red';
  510. } else if (myTeamId == data.getElementsByTagName('Team')[1].getAttribute('id')) {
  511. matchBlock.className = score.local > score.visitor ? 'red' : 'green';
  512. }
  513. });
  514. };
  515.  
  516. // End matches data
  517.  
  518. // Cups and FL
  519. const renderCupCountryAndDivChecker = () => {
  520. const categories = [
  521. 'private_cup&sub',
  522. 'cup&sub',
  523. 'u18',
  524. 'u21',
  525. 'u23',
  526. 'world',
  527. 'u18_world',
  528. 'friendlyseries&sub'
  529. ];
  530. const url = window.location.href;
  531. let appliesIn = categories.filter((elem) => {
  532. return url.indexOf(elem) > -1;
  533. });
  534. if (appliesIn.length < 1) {
  535. return;
  536. }
  537. let containerSelector, clickedElementSelector, targetContainerSelector;
  538. if (url.indexOf('cup&sub') > -1) {
  539. containerSelector = '#cup-div';
  540. clickedElementSelector = '#ui-id-4';
  541. targetContainerSelector = '#group-stages';
  542. } else if (url.indexOf('friendlyseries&sub') > -1) {
  543. containerSelector = '#friendly-series-div';
  544. clickedElementSelector = '#ui-id-2';
  545. targetContainerSelector = '#ui-tabs-2';
  546. }
  547. if (typeof containerSelector === undefined) {
  548. return;
  549. }
  550. $(document).on('click', '.js-view-div-country', () => {
  551. renderDivAndCountry(targetContainerSelector);
  552. });
  553. if (typeof clickedElementSelector !== undefined) {
  554. $(containerSelector).on('click', clickedElementSelector, () => {
  555. setTimeout(() => {
  556. renderDivAndCountryButton();
  557. }, 1500);
  558. });
  559. }
  560. };
  561.  
  562. const renderDivAndCountryButton = () => {
  563. let tableHeader = document.querySelectorAll('.nice_table thead tr.seriesHeader')[0];
  564. let firstCell = tableHeader.cells[0];
  565. firstCell.innerHTML =
  566. '<img class="js-view-div-country" src="https://i.imgur.com/IwaQRmF.png" title="Ver divisi&oacute;n y pa&iacute;s" style="cursor:pointer;">';
  567. };
  568.  
  569. const renderDivAndCountry = (containerSelector) => {
  570. if (containerSelector === '' || !containerSelector) {
  571. return;
  572. }
  573. let container = document.querySelector(containerSelector);
  574. if (!container) {
  575. return;
  576. }
  577. let rows = container.querySelectorAll('.nice_table tbody > tr');
  578. for (let i = 0; i < rows.length; i++) {
  579. let row = rows[i];
  580. let link = row.querySelectorAll('a')[0];
  581. let teamId = link.href.split('&')[1].replace('tid=', '');
  582. const ajax = $.ajax({
  583. url: '/xml/manager_data.php',
  584. type: 'GET',
  585. data: { sport_id: sports.indexOf(ajaxSport), team_id: teamId }
  586. });
  587. (function (container) {
  588. ajax.done((data) => {
  589. let index = sports.indexOf(ajaxSport) - 1;
  590. let divName = data.getElementsByTagName('Team')[index].getAttribute('seriesName'),
  591. country = data.getElementsByTagName('UserData')[0].getAttribute('countryShortname');
  592. let divId = data.getElementsByTagName('Team')[index].getAttribute('seriesId'),
  593. idTeam = data.getElementsByTagName('Team')[index].getAttribute('teamId');
  594.  
  595. let countryHtml =
  596. '<img src="http://static.managerzone.com/nocache-581/img/flags/12/' +
  597. country.toLowerCase() +
  598. '.png">&nbsp;';
  599. let divHtml =
  600. '&nbsp;- &gt; <a href="?p=league&type=senior&sid=' +
  601. divId +
  602. '&tid=' +
  603. idTeam +
  604. '">' +
  605. divName +
  606. '</a>';
  607. container.insertAdjacentHTML('beforeend', divHtml);
  608. container.insertAdjacentHTML('afterbegin', countryHtml);
  609. });
  610. })(link.parentNode);
  611. }
  612. };
  613.  
  614. // End cups and FL
  615.  
  616. // Training
  617. const visualTrainingBalls = () => {
  618. setTimeout(() => {
  619. const container = document.querySelector('#training_report');
  620. if (!container) {
  621. return;
  622. }
  623. const table = container.childNodes[2],
  624. tbody = table.querySelector('tbody');
  625. for (let i = 0; i < tbody.rows.length; i++) {
  626. let cell = tbody.rows[i].cells[4];
  627. let balls = cell.querySelectorAll('img').length;
  628. cell.querySelector('div').innerHTML += '<b>(' + balls + ')</b>';
  629. }
  630. }, 2500);
  631. };
  632.  
  633. // End training
  634.  
  635. // General utils
  636. const onlyNumbers = (e) => {
  637. if (
  638. $.inArray(e.keyCode, [46, 8, 9, 27, 13]) !== -1 ||
  639. // Allow: Ctrl+A
  640. (e.keyCode == 65 && e.ctrlKey === true) ||
  641. // Allow: Ctrl+C
  642. (e.keyCode == 67 && e.ctrlKey === true) ||
  643. // Allow: Ctrl+X
  644. (e.keyCode == 88 && e.ctrlKey === true) ||
  645. // Allow: home, end, left, right
  646. (e.keyCode >= 35 && e.keyCode <= 39)
  647. ) {
  648. return;
  649. }
  650. if ((e.shiftKey || e.keyCode < 48 || e.keyCode > 57) && (e.keyCode < 96 || e.keyCode > 105)) {
  651. e.preventDefault();
  652. }
  653. };
  654.  
  655. const formToJSONString = (form) => {
  656. let obj = {};
  657. let elements = form.querySelectorAll('input, select, textarea');
  658. for (let i = 0; i < elements.length; ++i) {
  659. if (elements[i].name) {
  660. obj[elements[i].name] = elements[i].value.trim();
  661. }
  662. }
  663. return JSON.stringify(obj);
  664. };
  665.  
  666. const treatAsUTC = (date) => {
  667. let result = new Date(date);
  668. return result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
  669. };
  670.  
  671. const reformatDate = (strDate) => {
  672. let splittedDate = strDate.split('-');
  673. return splittedDate[2] + '-' + splittedDate[1] + '-' + splittedDate[0];
  674. };
  675.  
  676. const daysBetween = (startDate, endDate) => {
  677. let millisecondsPerDay = 24 * 60 * 60 * 1000;
  678. return (treatAsUTC(endDate) - treatAsUTC(startDate)) / millisecondsPerDay;
  679. };
  680.  
  681. const toLocaleCurrency = (value, currency) => {
  682. const currencies = {
  683. USD: 7.4234,
  684. EUR: 9.1775,
  685. SEK: 1,
  686. MM: 1,
  687. UYU: 0.256963,
  688. R$: 2.62589,
  689. GBP: 13.35247,
  690. DKK: 1.23522,
  691. NOK: 1.07245,
  692. CHF: 5.86737,
  693. CAD: 5.70899,
  694. AUD: 5.66999,
  695. ILS: 1.6953,
  696. MXN: 0.68576,
  697. ARS: 2.64445,
  698. BOB: 0.939,
  699. PYG: 0.001309,
  700. RUB: 0.26313,
  701. PLN: 1.95278,
  702. ISK: 0.10433,
  703. BGL: 4.70738,
  704. BGN: 4.70738,
  705. ZAR: 1.23733,
  706. US$: 7.4234,
  707. THB: 0.17079,
  708. SIT: 0.03896,
  709. SKK: 0.24946,
  710. JPY: 0.06,
  711. INR: 0.17,
  712. MZ: 1
  713. };
  714. const toSEK = 1 / currencies[currency],
  715. cCurrency = localStorage.getItem('moneda');
  716. if (cCurrency) {
  717. return Math.round((1 / currencies[cMoneda]) * (value / toSEK));
  718. }
  719. return Math.round((1 / currencies['USD']) * (value / toSEK));
  720. };
  721.  
  722. const formatMoney = (value) => {
  723. let result = '',
  724. number = value.toString();
  725. while (number.length > 3) {
  726. result = '.' + number.substr(number.length - 3) + result;
  727. number = number.substring(0, number.length - 3);
  728. }
  729. return number + result;
  730. };
  731.  
  732. // end general utils
  733.  
  734. // Taxes
  735. const calculateTaxes = (config) => {
  736. const days = daysBetween(reformatDate(config.boughtDate), reformatDate(config.soldDate));
  737. if (days < 0) {
  738. alert('Por favor revise las fechas ingresadas');
  739. return;
  740. }
  741. let tax = { value: 0, percentage: 0 },
  742. profit = config.soldPrice - config.boughtPrice;
  743. if (profit > 0) {
  744. tax.percentage = days > 69 ? 15 : days > 26 ? 50 : 95;
  745. if (config.originalPlayer) {
  746. tax.percentage = 15;
  747. } else if (config.exYouth) {
  748. tax.percentage = config.playerAge < 20 ? 25 : config.playerAge < 21 ? 20 : 15;
  749. }
  750. }
  751. tax.value = Math.round(profit * (tax.percentage / 100));
  752. return tax;
  753. };
  754.  
  755. const calculateTaxesAction = (ev) => {
  756. ev.preventDefault();
  757. let form = ev.target;
  758. let jsonForm = formToJSONString(form);
  759. jsonForm = JSON.parse(jsonForm);
  760. let taxConfig = {
  761. originalPlayer: jsonForm.origin * 1 == 2,
  762. exYouth: jsonForm.origin * 1 == 1,
  763. playerAge: jsonForm.playerAge * 1,
  764. boughtDate: jsonForm.boughtDate,
  765. soldDate: jsonForm.soldDate,
  766. boughtPrice: jsonForm.origin * 1 === 0 ? jsonForm.boughtValue * 1 : jsonForm.playerValue,
  767. soldPrice: jsonForm.soldValue * 1
  768. };
  769.  
  770. let taxes = calculateTaxes(taxConfig);
  771. let html =
  772. 'Se descuentan ' +
  773. formatMoney(taxes.value) +
  774. ' en impuestos (' +
  775. taxes.percentage +
  776. '%)<br>Recibes ' +
  777. formatMoney(taxConfig.soldPrice - taxes.value);
  778. document.querySelector('.js-tax-result').innerHTML = html;
  779. };
  780.  
  781. const getTaxesForm = () => {
  782. return (
  783. '<article style="padding-left:5px;">' +
  784. '<h3>Calcular impuestos</h3>' +
  785. '<div>' +
  786. '<form class="js-calculate-tax">' +
  787. '<table style="width:100%;">' +
  788. '<tr>' +
  789. '<td><span>Origen jugador</span></td>' +
  790. '<td>' +
  791. '<select name="origin">' +
  792. '<option value="0">Comprado</option>' +
  793. '<option value="1">Ex juvenil</option>' +
  794. '<option value="2">Original del club</option>' +
  795. '</select>' +
  796. '</td>' +
  797. '</tr>' +
  798. '<tr>' +
  799. '<td><span>Valor jugador</span> <span style="color:#A3A30D;">*</span></td>' +
  800. '<td><input type="text" name="playerValue" value="0" class="js-only-numbers"></td>' +
  801. '</tr>' +
  802. '<tr>' +
  803. '<td><span>Edad jugador</span> <span style="color:#A3A30D;">*</span></td>' +
  804. '<td>' +
  805. '<select name="playerAge">' +
  806. '<option value="19">19</option>' +
  807. '<option value="20">20</option>' +
  808. '<option value="21">M&aacute;s de 20</option>' +
  809. '</select>' +
  810. '</td>' +
  811. '</tr>' +
  812. '<tr>' +
  813. '<td><span>Valor compra</span> <span style="color:#FF043D;">*</span></td>' +
  814. '<td><input type="text" name="boughtValue" class="js-only-numbers"></td>' +
  815. '</tr>' +
  816. '<tr>' +
  817. '<td><span>Valor venta</span></td>' +
  818. '<td><input type="text" name="soldValue" class="js-only-numbers"></td>' +
  819. '</tr>' +
  820. '<tr>' +
  821. '<td><span>Fecha compra</span> <span style="color:#FF043D;">*</span></td>' +
  822. '<td><input type="text" name="boughtDate" placeholder="dd-mm-aaaa"></td>' +
  823. '</tr>' +
  824. '<tr>' +
  825. '<td><span>Fecha venta</span></td>' +
  826. '<td><input type="text" name="soldDate" placeholder="dd-mm-aaaa"></td>' +
  827. '</tr>' +
  828. '</table>' +
  829. '<div>' +
  830. '<span style="color:#FF043D;">*</span> <span>Si el jugador fue comprado</span><br>' +
  831. '<span style="color:#A3A30D;">*</span> <span>Si el jugador es original del club o ex juvenil</span>' +
  832. '</div>' +
  833. '<div style="margin-top:4px;">' +
  834. '<button type="submit" class="quicklink"><span class="buttonClassMiddle">Calcular</span></button>' +
  835. '</div>' +
  836. '<div>' +
  837. '<p class="js-tax-result"></p>' +
  838. '</div>' +
  839. '</form>' +
  840. '</div>' +
  841. '</article>'
  842. );
  843. };
  844.  
  845. const renderTaxCalculation = (ev) => {
  846. ev.preventDefault();
  847. let html = getTaxesForm();
  848. let container = document.querySelector('.dg_playerview_info');
  849. container.insertAdjacentHTML('beforeend', html);
  850. };
  851.  
  852. const renderTaxCalculationButton = () => {
  853. let parent = document.querySelector('.dg_playerview_info');
  854. let container = parent.querySelector('p');
  855. let html =
  856. '<a href="#" class="js-render-tax mzbtn buttondiv button_red">' +
  857. '<span class="buttonClassMiddle" style="white-space:nowrap;">Impuestos</span><span class="buttonClassRight">&nbsp;</span>' +
  858. '</a>';
  859. container.insertAdjacentHTML('beforeend', html);
  860. };
  861.  
  862. // End taxes
  863.  
  864. // Forum
  865. const forumPagination = () => {
  866. const posts = document.querySelectorAll('#topics-list > dd');
  867. for (let i = 0; i < posts.length; i++) {
  868. let link = posts[i]
  869. .querySelector('.topics-col-title')
  870. .querySelector('a')
  871. .getAttribute('href');
  872. let counterDiv = posts[i].querySelector('.topics-col-counter');
  873. let text = (counterDiv.innerText || counterDiv.textContent).split(' / ');
  874. let messageCount = parseInt(text[1]);
  875. let pageQuantity = Math.floor(parseInt(messageCount) / 50);
  876. if (pageQuantity > 0 && messageCount > 50) {
  877. let html = '';
  878. let limit = pageQuantity > 5 ? 5 : pageQuantity + 1;
  879. for (let j = 2; j < limit; j++) {
  880. html +=
  881. '<a href="' +
  882. link +
  883. '&offset=' +
  884. (j - 1) * 50 +
  885. '" title="Ir a p&aacute;gina ' +
  886. j +
  887. '">' +
  888. j +
  889. '</a>&#160;';
  890. }
  891. }
  892. }
  893. };
  894.  
  895. const getCCButtons = () => {
  896. return (
  897. '<div>' +
  898. '<div class="mzbtn buttondiv button_account" title="Borrar texto del area de mensaje">' +
  899. '<span class="buttonClassMiddle js-empty-post-textarea" style="white-space: nowrap">Vaciar</span><span class="buttonClassRight">&nbsp;</span>' +
  900. '</div>' +
  901. '<div class="js-icons-container">' +
  902. '<img src="https://i.imgur.com/3YitWv3.gif" alt=">"/>&nbsp;' +
  903. '<img src="https://i.imgur.com/Q3B4Dqz.gif" title="(y)" alt="(y)"/>&nbsp;' +
  904. '<img src="https://i.imgur.com/vWFv3Gt.gif" title="(n)" alt="(n)"/>&nbsp;' +
  905. '<img src="https://i.imgur.com/jaT1cb4.gif" height="20px" title="wtf" alt="wtf"/>&nbsp;' +
  906. '<img src="https://i.imgur.com/VfbyDHO.gif" height="20px" title="fail" alt="fail"/>&nbsp;' +
  907. '<img src="https://i.imgur.com/cheJFuk.gif" height="20px" title="repost" alt="repost"/>&nbsp;' +
  908. '<img src="https://i.imgur.com/jDjyKTf.gif" title="cri" alt="cri"/>&nbsp;' +
  909. '<img src="https://i.imgur.com/6PopX5q.gif" title="ha-ha" alt="ha-ha"/>' +
  910. '<img src="https://i.imgur.com/nRp5BpE.gif" title=":)" alt=":)"/>&nbsp;' +
  911. '<img src="https://i.imgur.com/CcuKTNz.gif" title=":D" alt=":D"/>&nbsp;' +
  912. '<img src="https://i.imgur.com/Dfl5ZGS.gif" title="D" alt="D"/>&nbsp;' +
  913. '<img src="https://i.imgur.com/8t9ZJse.gif" title="xD" alt="xD"/>&nbsp;' +
  914. '<img src="https://i.imgur.com/1kJhHCs.gif" title=":/" alt=":/"/>&nbsp;' +
  915. '<img src="https://i.imgur.com/1ncAraF.gif" title=":(" alt=":("/>&nbsp;' +
  916. '<img src="https://i.imgur.com/xp6xUJJ.gif" title=":*(" alt=":*("/>&nbsp;' +
  917. '<img src="https://i.imgur.com/qOigaWi.png" title=":S" alt=":S"/>&nbsp;' +
  918. '<img src="https://i.imgur.com/nITjZn5.gif" title="erm" alt="erm"/>&nbsp;' +
  919. '<img src="https://i.imgur.com/rSqmTPO.gif" title="8-)" alt="8-)"/>&nbsp;' +
  920. '<img src="https://i.imgur.com/qP1rAQ5.png" title="¬¬" alt="¬¬"/>&nbsp;' +
  921. '<img src="https://i.imgur.com/HdNdWN0.png" title="porfi" alt="porfi"/>&nbsp;' +
  922. '<img src="https://i.imgur.com/QuXS7fE.gif" title="O.O" alt="O.O"/>&nbsp;' +
  923. '<img src="https://i.imgur.com/RUQN2Hy.gif" title="_hm" alt="_hm"/>&nbsp;' +
  924. '<img src="https://i.imgur.com/QLCdFIE.gif" title=">:(" alt=">:("/>&nbsp;' +
  925. '<img src="https://i.imgur.com/55sAO1r.gif" title=">:)" alt=">:)"/>&nbsp;' +
  926. '<img src="https://i.imgur.com/KbQOSgw.gif" title="flirt" alt="flirt"/>&nbsp;' +
  927. '<img src="https://i.imgur.com/t5dALqK.gif" title=":P" alt=":P"/>&nbsp;' +
  928. '<img src="https://i.imgur.com/zpY2A6I.gif" title="|-(" alt="|-("/>&nbsp;' +
  929. '<img src="https://i.imgur.com/yPtUjin.gif" title=";)" alt=";)"/>&nbsp;' +
  930. '<img src="https://i.imgur.com/OOsLDaW.gif" title="(h)" alt="(h)"/>&nbsp;' +
  931. '<img src="https://i.imgur.com/LdCQyai.png" title="u.u" alt="u.u"/>&nbsp;' +
  932. '<img src="https://i.imgur.com/KnhAURP.gif" title="shh" alt="shh"/>&nbsp;' +
  933. '<img src="https://i.imgur.com/BzPDfzF.gif" title="nana" alt="nana"/>' +
  934. '<img src="https://i.imgur.com/XEHiXuO.gif" height="23px" title="rock" alt="rock"/>' +
  935. '<img src="https://i.imgur.com/CsCrOnE.gif" title="grr" alt="grr"/>&nbsp;' +
  936. '<img src="https://i.imgur.com/K2d1Mbv.gif" height="23px" title="jaja" alt="jaja"/>' +
  937. '<img src="https://i.imgur.com/SMcjsnf.gif" title="eah" alt="eah"/>' +
  938. '<img src="https://i.imgur.com/aaPvRo4.gif" title="clap" alt="clap"/>' +
  939. '<img src="https://i.imgur.com/av8bxvU.gif" title="bla" alt="bla"/>' +
  940. '<img src="https://i.imgur.com/oQYWBTO.gif" title="l" alt="l"/>&nbsp;' +
  941. '<img src="https://i.imgur.com/z64hDgz.gif" title="grr" alt="grr"/>&nbsp;' +
  942. '<img src="https://i.imgur.com/NA84WqF.gif" title="angel" alt="angel"/>&nbsp;' +
  943. '<img src="https://i.imgur.com/N2cdFNy.gif" title="diablo" alt="diablo"/>&nbsp;' +
  944. '<img src="https://i.imgur.com/YWe8hno.gif" title="baba" alt="baba"/>' +
  945. '<img src="https://i.imgur.com/1t7YpCo.gif" height="23px" title="x)" alt="x)"/>&nbsp;' +
  946. '<img src="https://i.imgur.com/UR5t0o6.gif" title="plz" alt="plz"/>&nbsp;' +
  947. '<img src="https://i.imgur.com/KKx3thu.gif" title="umm" alt="umm"/>' +
  948. '<img src="https://i.imgur.com/sC8Mgmi.gif" title="facepalm" alt="facepalm"/>&nbsp;' +
  949. '<img src="https://i.imgur.com/gJw92DZ.gif title="zzz" alt="zzz"/>' +
  950. '<img src="https://i.imgur.com/RzjaSKr.gif" title="om" alt="om"/>' +
  951. '<img src="https://i.imgur.com/7iCxtYD.gif" title="uh" alt="uh"/>' +
  952. '</div>' +
  953. '</div>'
  954. );
  955. };
  956.  
  957. const postItem = (html) => {
  958. let textarea = document.querySelector('.markItUpEditor');
  959. let scrollTop = textarea.scrollTop;
  960. let selectionStart = textarea.selectionStart;
  961. let selectionEnd = textarea.selectionEnd;
  962. textarea.value =
  963. textarea.value.substr(0, selectionStart) +
  964. html +
  965. textarea.value.substr(selectionEnd, textarea.value.length);
  966. textarea.scrollTop = scrollTop;
  967. };
  968.  
  969. const postSmiley = (ev) => {
  970. let img = ev.target;
  971. let url = img.getAttribute('src');
  972. let html = '[image url=' + url + ']';
  973. postItem(html);
  974. };
  975.  
  976. const emptyPostTextarea = (ev) => {
  977. let textarea = document.querySelector('#forum_form_message');
  978. textarea.value = '';
  979. };
  980.  
  981. const renderCCBar = () => {
  982. setTimeout(() => {
  983. let container = document.querySelector('.bbcode');
  984. if (container) {
  985. let html = getCCButtons();
  986. container.insertAdjacentHTML('afterbegin', html);
  987. }
  988. }, 1500);
  989. };
  990.  
  991. const renderPostQuicklinks = () => {
  992. const posts = document.querySelectorAll('.forum_body');
  993. const titles = ['Ir al GB', 'Posts recientes del usuario', 'Invitar amistoso'],
  994. texts = ['Guestbook', 'Posts', 'Amistosos'];
  995. const url = window.location.href;
  996. const forum = url[3].replace('forum_id=', '');
  997. for (let i = 0; i < posts.length; i++) {
  998. let author = posts[i].querySelector('.post-author');
  999. let authorContainer = author.querySelector('a');
  1000. let authorId = authorContainer.href.split('&')[1].replace('uid=', '');
  1001. let authorName = authorContainer.innerHTML;
  1002. let badgeContainer = posts[i].querySelector('.forum-post-badges');
  1003. let authorTeamId = badgeContainer
  1004. .querySelector('img')
  1005. .src.split('=')[1]
  1006. .replace('&sport', '');
  1007. let html =
  1008. '<a class="quicklink" href="/?p=guestbook&uid=' +
  1009. authorId +
  1010. '" title="' +
  1011. titles[0] +
  1012. '">' +
  1013. texts[0] +
  1014. '</a>' +
  1015. '<a class="quicklink" href="?p=forum&sub=search&search_keywords=&search_keyword_type=any&search_author=' +
  1016. authorName +
  1017. '&search_forum=' +
  1018. forum +
  1019. '&search_range=7&search_sort_by=post_date&search_sort_order=desc" title="' +
  1020. titles[1] +
  1021. '">' +
  1022. texts[1] +
  1023. '</a>' +
  1024. '<a class="quicklink" href="?p=team&sub=challenge&tid=' +
  1025. authorTeamId +
  1026. '" title="' +
  1027. titles[2] +
  1028. '">' +
  1029. texts[2] +
  1030. '</a>';
  1031. author.insertAdjacentHTML('beforeend', html);
  1032. }
  1033. };
  1034.  
  1035. // End forum
  1036.  
  1037. // General config
  1038. const setPageFunctions = () => {
  1039. const url = window.location.href;
  1040. if (
  1041. url.indexOf('topics&forum_id') > -1 ||
  1042. url.indexOf('topic&topic_id') > -1 ||
  1043. url.indexOf('guestbook') > -1
  1044. ) {
  1045. renderCCBar();
  1046. renderSignatureDiv();
  1047. renderPostQuicklinks();
  1048. forumPagination();
  1049. } else if (url.indexOf('p=match&sub=result') > -1) {
  1050. linkToSeniorLeague();
  1051. playersMatchValue();
  1052. } else if (url.indexOf('training') > -1) {
  1053. visualTrainingBalls();
  1054. } else if (url.indexOf('sub=scheduled') > -1) {
  1055. previewResultsButton();
  1056. } else if (url.indexOf('players&pid') > -1) {
  1057. renderTaxCalculationButton();
  1058. } else if (url.indexOf('standings&fsid') > -1) {
  1059. setTimeout(() => {
  1060. renderDivAndCountryButton();
  1061. }, 1500);
  1062. }
  1063. renderCupCountryAndDivChecker();
  1064. };
  1065.  
  1066. const addTeamBadgeToPlayers = () => {
  1067. const currentPage = window.location.href;
  1068. if (!currentPage.includes('p=players')) {
  1069. return;
  1070. } else if (currentPage.includes('&') && currentPage.indexOf('&pid=') < 0) {
  1071. return;
  1072. }
  1073.  
  1074. const playerContainers = Array.prototype.slice.call(
  1075. document.querySelectorAll('.player-image.soccer')
  1076. );
  1077. let teamID = null;
  1078. let badgeHTML = '';
  1079. for (let i = 0; i < playerContainers.length; i++) {
  1080. const playerContainer = playerContainers[i];
  1081. const playerLink = playerContainer
  1082. .closest('.playerContainer')
  1083. ?.querySelector('a.subheader')
  1084. ?.getAttribute('href');
  1085.  
  1086. if (!teamID) {
  1087. teamID = playerLink.split('&')[2].replace(/\D+/, '');
  1088. badgeHTML = `<div class="player-team-badge" style="background-image: url(dynimg/badge.php?team_id=${teamID}&sport=soccer&location=icon)"></div>`;
  1089. }
  1090.  
  1091. playerContainer.insertAdjacentHTML('afterbegin', badgeHTML);
  1092. }
  1093. };
  1094.  
  1095. const setEvents = () => {
  1096. $(document)
  1097. .on('click', '.js-delete-signature', dropSignature)
  1098. .on('click', '.js-empty-post-textarea', emptyPostTextarea)
  1099. .on('click', '.js-icons-container img', postSmiley)
  1100. .on('click', '.js-preview-results', getMatchesResults)
  1101. .on('click', '.js-save-signature', saveSignature)
  1102. .on('click', '.js-signature', putSignature)
  1103. .on('click', '.js-render-tax', renderTaxCalculation)
  1104. .on('click', '.training_report_header', visualTrainingBalls)
  1105. .on('submit', '.js-calculate-tax', calculateTaxesAction)
  1106. .on('keydown change', '.js-only-numbers', onlyNumbers);
  1107. };
  1108.  
  1109. return {
  1110. init: init
  1111. };
  1112. })();
  1113.  
  1114. window.addEventListener('load', () => {
  1115. rzscript.init();
  1116. });

QingJ © 2025

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