Greasy Fork镜像 支持简体中文。

MazyarTools

Mazyar Tools & Utilities

目前為 2024-11-15 提交的版本,檢視 最新版本

此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.gf.qytechs.cn/scripts/513041/1484499/MazyarTools.js

  1. // ==UserScript==
  2. // @name MazyarTools
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.3
  5. // @description Mazyar Tools & Utilities
  6. // @copyright z7z from managerzone.com
  7. // @author z7z from managerzone.com
  8. // @license MIT
  9. // @match https://www.managerzone.com/*
  10. // @match https://test.managerzone.com/*
  11. // @icon https://www.google.com/s2/favicons?sz=64&domain=managerzone.com
  12. // @supportURL https://github.com/mz-ir/mazyar
  13. // ==/UserScript==
  14.  
  15. // --------------------------------------- Formatter -----------------------------
  16.  
  17. function mazyarFormatBigNumber(n, sep = " ") {
  18. if (n) {
  19. const numberString = n.toString();
  20. let formattedParts = [];
  21. for (let i = numberString.length - 1; i >= 0; i -= 3) {
  22. let part = numberString.substring(Math.max(i - 2, 0), i + 1);
  23. formattedParts.unshift(part);
  24. }
  25. return formattedParts.join(sep);
  26. }
  27. return "0";
  28. }
  29.  
  30. function mazyarFormatAverageAge(age, fractionDigits = 1) {
  31. if (age) {
  32. return age.toFixed(fractionDigits);
  33. }
  34. return "0.0";
  35. }
  36.  
  37. function mazyarFormatFileSize(b) {
  38. const s = 1024;
  39. let u = 0;
  40. while (b >= s || -b >= s) {
  41. b /= s;
  42. u++;
  43. }
  44. return (u ? b.toFixed(1) + " " : b) + " KMGTPEZY"[u] + "B";
  45. }
  46.  
  47. // -------------------------------- Parser -------------------------------------
  48.  
  49. function mazyarParseMzDate(dateString) {
  50. const [day, month, year] = dateString.split('-').map(Number);
  51. return new Date(year, month - 1, day);
  52. }
  53.  
  54. function mazyarParseMzDateTime(dateTimeString) {
  55. const [date, time] = dateTimeString.split(' ');
  56. const [day, month, year] = date.split('-').map(Number);
  57. const [hours, minutes] = time.split(':').map(Number);
  58. return new Date(year, month - 1, day, hours, minutes);
  59. }
  60.  
  61. function mazyarGenerateUuidV4() {
  62. return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
  63. const r = (Math.random() * 16) | 0,
  64. v = c == "x" ? r : (r & 0x3) | 0x8;
  65. return v.toString(16);
  66. });
  67. }
  68.  
  69. function mazyarIsFilterHitsValid(hits) {
  70. return typeof hits === "number" && hits >= 0;
  71. }
  72.  
  73. function mazyarHasDuplicates(array) {
  74. return new Set(array).size !== array.length;
  75. }
  76.  
  77. function mazyarExtractSportType(doc = document) {
  78. const zone = doc.querySelector("a#shortcut_link_thezone");
  79. if (zone) {
  80. return zone.href.indexOf("hockey") > -1 ? "hockey" : "soccer";
  81. }
  82. return "soccer";
  83. }
  84.  
  85. function mazyarExtractClubCurrency(doc) {
  86. const players = doc.getElementById("playerAltViewTable")?.querySelectorAll("tbody tr");
  87. if (players && players.length > 0) {
  88. const parts = players[0].querySelector("td:nth-child(3)")?.innerText.split(" ");
  89. return parts[parts.length - 1].trim();
  90. }
  91. return "";
  92. }
  93.  
  94. function mazyarExtractNationalCurrency(doc) {
  95. // works for both domestic and foreign countries
  96. const playerNode = doc.getElementById("thePlayers_0")?.querySelector("table tbody tr:nth-child(6)");
  97. if (playerNode) {
  98. const parts = playerNode.innerText.split(" ");
  99. return parts[parts.length - 1].trim();
  100. }
  101. return "";
  102. }
  103.  
  104. function mazyarExtractTeamId(link) {
  105. const regex = /tid=(\d+)/;
  106. const match = regex.exec(link);
  107. return match ? match[1] : null;
  108. }
  109.  
  110. function mazyarExtractPlayerIdFromProfileLink(link) {
  111. const regex = /pid=(\d+)/;
  112. const match = regex.exec(link);
  113. return match ? match[1] : null;
  114. }
  115.  
  116. function mazyarExtractMatchId(link) {
  117. const regex = /mid=(\d+)/;
  118. const match = regex.exec(link);
  119. return match ? match[1] : null;
  120. }
  121.  
  122. function mazyarExtractPlayerIdFromTransferMonitor(link) {
  123. const regex = /u=(\d+)/;
  124. const match = regex.exec(link);
  125. return match ? match[1] : null;
  126. }
  127.  
  128. function mazyarExtractPlayerIdFromContainer(player) {
  129. return player?.querySelector("h2 span.player_id_span")?.innerText;
  130. }
  131.  
  132. function mazyarIsMatchInProgress(resultText) {
  133. const scoreRegex = /\b(X|0|[1-9]\d*) - (X|0|[1-9]\d*)\b/;
  134. return !scoreRegex.test(resultText);
  135. }
  136.  
  137. function mazyarIsPlayerSentToCamp(doc) {
  138. if (location.hostname.startsWith("test")) {
  139. return !!doc.querySelector(`#thePlayers_0 span.player_icon_wrapper i.fa-traffic-cone.tc-status-icon:not(.tc-status-icon--disabled)`);
  140. }
  141. return !!doc.querySelector(`#thePlayers_0 span.player_icon_image[style*="icon_trainingcamp_dg"]`);
  142. }
  143.  
  144. function mazyarExtractSkillNamesFromPlayerInfo(player) {
  145. const skills = player?.querySelectorAll("table.player_skills > tbody > tr > td > span.clippable");
  146. return [...skills].map((el) => el.innerText);
  147. }
  148.  
  149. function mazyarExtractSkillsFromScoutReport(section, skillList) {
  150. const skills = section.querySelectorAll("div.flex-grow-1 ul li.blurred span");
  151. return [...skills].map((el) => skillList.indexOf(el.innerText));
  152. }
  153.  
  154. function mazyarExtractStarsFromScoutReport(section) {
  155. return section.querySelectorAll(".stars i.lit")?.length;
  156. }
  157.  
  158. function mazyarExtractResidencyDaysAndPrice(doc = document) {
  159. if (!doc) {
  160. return { days: 0, price: '' };
  161. }
  162. const transfers = doc?.querySelector("div.baz > div > div.win_back > table.hitlist");
  163. const history = transfers?.querySelector("tbody");
  164. if (history?.children.length > 1) {
  165. const arrived = history?.lastChild?.querySelector("td")?.innerText;
  166. const days = Math.floor((new Date() - mazyarParseMzDate(arrived)) / 86_400_000);
  167. const price = history.lastChild?.querySelector("td:last-child")?.innerText;
  168. const currency = transfers?.querySelector("thead tr td:last-child")?.innerText?.match(/.*\((.*)\)/)?.[1];
  169. return { days, price: price + ' ' + currency };
  170. }
  171. return { days: -1, price: '' };
  172. }
  173.  
  174. async function mazyarExtractPlayerProfile(playerId) {
  175. const url = `https://${location.hostname}/?p=players&pid=${playerId}`;
  176. const doc = await mazyarFetchHtml(url);
  177. if (doc) {
  178. const { days, price } = mazyarExtractResidencyDaysAndPrice(doc);
  179. const camp = mazyarIsPlayerSentToCamp(doc);
  180. const skills = doc.querySelectorAll("#thePlayers_0 table.player_skills tbody tr");
  181. let i = 0;
  182. const maxed = [];
  183. for (const skill of skills) {
  184. if (skill.querySelector(".maxed")) {
  185. maxed.push(i);
  186. }
  187. i++;
  188. }
  189. return {
  190. pid: playerId,
  191. maxed,
  192. days,
  193. price,
  194. camp,
  195. };
  196. }
  197. return null;
  198. }
  199.  
  200. async function mazyarExtractPlayerScoutReport(pid, skills, sport = "soccer") {
  201. const url = `https://${location.hostname}/ajax.php?p=players&sub=scout_report&pid=${pid}&sport=${sport}`;
  202. const doc = await mazyarFetchHtml(url);
  203. if (doc) {
  204. const report = doc.querySelectorAll(".paper-content.clearfix dl dd");
  205. if (report.length == 3) {
  206. const high = mazyarExtractStarsFromScoutReport(report[0]);
  207. const highSkills = mazyarExtractSkillsFromScoutReport(report[0], skills);
  208. const low = mazyarExtractStarsFromScoutReport(report[1]);
  209. const lowSkills = mazyarExtractSkillsFromScoutReport(report[1], skills);
  210. const trainingSpeed = mazyarExtractStarsFromScoutReport(report[2]);
  211. return {
  212. pid,
  213. H: high,
  214. HS: highSkills,
  215. L: low,
  216. LS: lowSkills,
  217. S: trainingSpeed,
  218. };
  219. }
  220. }
  221. return null;
  222. }
  223.  
  224. function mazyarExtractClubPlayersDetails(doc, currency) {
  225. const players = [];
  226. const playerNodes = doc.querySelectorAll("table#playerAltViewTable tr");
  227. for (const playerNode of playerNodes) {
  228. const age = playerNode.querySelector("td:nth-child(5)")?.innerText.replace(/\s/g, "");
  229. if (age) {
  230. const value = playerNode.querySelector("td:nth-child(3)")?.innerText.replaceAll(currency, "").replace(/\s/g, "");
  231. const shirtNumber = playerNode.querySelector("td:nth-child(0)")?.innerText.replace(/\s/g, "");
  232. const pid = playerNode.querySelector("a")?.href;
  233. players.push({
  234. shirtNumber,
  235. age: parseInt(age, 10),
  236. value: parseInt(value, 10),
  237. id: mazyarExtractPlayerIdFromProfileLink(pid),
  238. });
  239. }
  240. }
  241. return players;
  242. }
  243.  
  244. function mazyarExtractNumberOfFlags(infoTable) {
  245. const images = infoTable.getElementsByTagName("img");
  246. return images ? [...images].filter((img) => img.src.indexOf("/flags/") > -1).length : 0;
  247. }
  248.  
  249. function mazyarIsPlayerDomestic(infoTable) {
  250. return mazyarExtractNumberOfFlags(infoTable) === 1;
  251. }
  252.  
  253. function mazyarExtractNationalPlayersDetails(doc, currency) {
  254. const players = [];
  255. const playerNodes = doc.querySelectorAll("div.playerContainer");
  256. for (const playerNode of playerNodes) {
  257. const id = mazyarExtractPlayerIdFromProfileLink(playerNode.querySelector("h2 a")?.href);
  258. const infoTable = playerNode.querySelector("div.dg_playerview_info table");
  259. const age = infoTable.querySelector("tbody tr:nth-child(1) td strong").innerText;
  260. const selector = mazyarIsPlayerDomestic(infoTable) ? "tbody tr:nth-child(5) td span" : "tbody tr:nth-child(6) td span";
  261. const value = infoTable.querySelector(selector)?.innerText.replaceAll(currency, "").replace(/\s/g, "");
  262. players.push({
  263. age: parseInt(age, 10),
  264. value: parseInt(value, 10),
  265. id,
  266. });
  267. }
  268. return players;
  269. }
  270.  
  271. function mazyarGetNumberOfPlayers(players, ageLow = 0, ageHigh = 99) {
  272. return players.filter((player) => player.age <= ageHigh && player.age >= ageLow).length;
  273. }
  274.  
  275. // ----------------------------------- Fetch ---------------------------------
  276.  
  277. async function mazyarFetchHtml(url) {
  278. return await fetch(url)
  279. .then((resp) => resp.text())
  280. .then((content) => {
  281. const parser = new DOMParser();
  282. return parser.parseFromString(content, "text/html");
  283. })
  284. .catch((error) => {
  285. console.warn(error);
  286. return null;
  287. });
  288. }
  289.  
  290. async function mazyarFetchXml(url) {
  291. return await fetch(url)
  292. .then((resp) => resp.text())
  293. .then((content) => {
  294. const parser = new DOMParser();
  295. return parser.parseFromString(content, "text/xml");
  296. })
  297. .catch((error) => {
  298. console.warn(error);
  299. return null;
  300. });
  301. }
  302.  
  303. async function mazyarFetchJson(url) {
  304. return await fetch(url)
  305. .then((resp) => resp.json())
  306. .catch((error) => {
  307. console.warn(error);
  308. return null;
  309. });
  310. }
  311.  
  312. function mazyarGetSquadSummaryUrl(tid) {
  313. return `https://${location.hostname}/?p=players&sub=alt&tid=${tid}`;
  314. }
  315.  
  316. function mazyarExtractSquadSummaryDetails(players, sport = "soccer") {
  317. if (!players) {
  318. return [];
  319. }
  320. const rows = [];
  321. if (sport === "hockey") {
  322. {
  323. const all = mazyarFilterPlayers(players);
  324. const top21 = mazyarFilterPlayers(players, 21);
  325. rows.push({
  326. title: "All",
  327. count: players.length,
  328. all: all.values,
  329. allAge: all.avgAge,
  330. top21: top21.values,
  331. top21Age: top21.avgAge,
  332. });
  333. }
  334. {
  335. const all = mazyarFilterPlayers(players, 0, 0, 23);
  336. const top21 = mazyarFilterPlayers(players, 21, 0, 23);
  337. rows.push({
  338. title: "U23",
  339. count: mazyarGetNumberOfPlayers(players, 0, 23),
  340. all: all.values,
  341. allAge: all.avgAge,
  342. top21: top21.values,
  343. top21Age: top21.avgAge,
  344. });
  345. }
  346. {
  347. const all = mazyarFilterPlayers(players, 0, 0, 21);
  348. const top21 = mazyarFilterPlayers(players, 21, 0, 21);
  349. rows.push({
  350. title: "U21",
  351. count: mazyarGetNumberOfPlayers(players, 0, 21),
  352. all: all.values,
  353. allAge: all.avgAge,
  354. top21: top21.values,
  355. top21Age: top21.avgAge,
  356. });
  357. }
  358. {
  359. const all = mazyarFilterPlayers(players, 0, 0, 18);
  360. const top21 = mazyarFilterPlayers(players, 21, 0, 18);
  361. rows.push({
  362. title: "U18",
  363. count: mazyarGetNumberOfPlayers(players, 0, 18),
  364. all: all.values,
  365. allAge: all.avgAge,
  366. top21: top21.values,
  367. top21Age: top21.avgAge,
  368. });
  369. }
  370. } else {
  371. {
  372. const all = mazyarFilterPlayers(players);
  373. const top16 = mazyarFilterPlayers(players, 16);
  374. const top11 = mazyarFilterPlayers(players, 11);
  375. rows.push({
  376. title: "All",
  377. count: players.length,
  378. all: all.values,
  379. allAge: all.avgAge,
  380. top16: top16.values,
  381. top16Age: top16.avgAge,
  382. top11: top11.values,
  383. top11Age: top11.avgAge,
  384. });
  385. }
  386. {
  387. const all = mazyarFilterPlayers(players, 0, 0, 23);
  388. const top16 = mazyarFilterPlayers(players, 16, 0, 23);
  389. const top11 = mazyarFilterPlayers(players, 11, 0, 23);
  390. rows.push({
  391. title: "U23",
  392. count: mazyarGetNumberOfPlayers(players, 0, 23),
  393. all: all.values,
  394. allAge: all.avgAge,
  395. top16: top16.values,
  396. top16Age: top16.avgAge,
  397. top11: top11.values,
  398. top11Age: top11.avgAge,
  399. });
  400. }
  401. {
  402. const all = mazyarFilterPlayers(players, 0, 0, 21);
  403. const top16 = mazyarFilterPlayers(players, 16, 0, 21);
  404. const top11 = mazyarFilterPlayers(players, 11, 0, 21);
  405. rows.push({
  406. title: "U21",
  407. count: mazyarGetNumberOfPlayers(players, 0, 21),
  408. all: all.values,
  409. allAge: all.avgAge,
  410. top16: top16.values,
  411. top16Age: top16.avgAge,
  412. top11: top11.values,
  413. top11Age: top11.avgAge,
  414. });
  415. }
  416. {
  417. const all = mazyarFilterPlayers(players, 0, 0, 18);
  418. const top16 = mazyarFilterPlayers(players, 16, 0, 18);
  419. const top11 = mazyarFilterPlayers(players, 11, 0, 18);
  420. rows.push({
  421. title: "U18",
  422. count: mazyarGetNumberOfPlayers(players, 0, 18),
  423. all: all.values,
  424. allAge: all.avgAge,
  425. top16: top16.values,
  426. top16Age: top16.avgAge,
  427. top11: top11.values,
  428. top11Age: top11.avgAge,
  429. });
  430. }
  431. }
  432. return rows;
  433. }
  434.  
  435. function mazyarFilterPlayers(players, count = 0, ageLow = 0, ageHigh = 99) {
  436. if (players.length === 0) {
  437. return { values: 0, avgAge: 0.0 };
  438. }
  439.  
  440. const n = count === 0 ? players.length : count;
  441. const filtered = players
  442. .filter((player) => player.age <= ageHigh && player.age >= ageLow)
  443. .sort((a, b) => b.value - a.value)
  444. .slice(0, n);
  445. if (filtered.length === 0) {
  446. return { values: 0, avgAge: 0.0 };
  447. }
  448. const values = filtered.map((player) => player.value).reduce((a, b) => a + b, 0);
  449. const avgAge = filtered.map((player) => player.age).reduce((a, b) => a + b, 0) / filtered.length;
  450. return { values, avgAge };
  451. }
  452.  
  453. async function mazyarFetchNationalPlayersAndCurrency(tid, sport) {
  454. const url = `https://${location.hostname}/ajax.php?p=nationalTeams&sub=players&ntid=${tid}&sport=${sport}`;
  455. const doc = await mazyarFetchHtml(url);
  456. if (doc) {
  457. const currency = mazyarExtractNationalCurrency(doc);
  458. const players = mazyarExtractNationalPlayersDetails(doc, currency);
  459. return { players, currency };
  460. }
  461. return { players: [], currency: '' };
  462. }
  463.  
  464. async function mazyarFetchClubPlayersAndCurrency(tid) {
  465. const url = mazyarGetSquadSummaryUrl(tid);
  466. const doc = await mazyarFetchHtml(url);
  467. if (doc) {
  468. const currency = mazyarExtractClubCurrency(doc);
  469. const players = mazyarExtractClubPlayersDetails(doc, currency);
  470. return { players, currency };
  471. }
  472. return { players: [], currency: '' };
  473. }
  474.  
  475. async function mazyarFetchPlayersAndCurrency(tid, sport) {
  476. const url = mazyarGetSquadSummaryUrl(tid);
  477. const isNational = await fetch(url, { method: "HEAD" })
  478. .then((resp) => (resp.url.search("p=national_teams") > -1));
  479. return isNational ? await mazyarFetchNationalPlayersAndCurrency(tid, sport) : await mazyarFetchClubPlayersAndCurrency(tid);
  480. }
  481.  
  482. function mazyarExtractClubTopPlyers(doc) {
  483. const currency = mazyarExtractClubCurrency(doc);
  484. const players = mazyarExtractClubPlayersDetails(doc, currency);
  485. const sport = mazyarExtractSportType(doc);
  486. const count = sport === "soccer" ? 11 : 21;
  487. return players ? mazyarFilterPlayers(players, count) : { values: 0, avgAge: 0 };
  488. }
  489.  
  490. async function mazyarExtractPlayersProfileDetails(teamId) {
  491. if (!teamId) {
  492. return null;
  493. }
  494. const url = `https://${location.hostname}/?p=players&tid=${teamId}`;
  495. const doc = await mazyarFetchHtml(url);
  496. if (doc) {
  497. const players = doc.getElementById("players_container")?.querySelectorAll("div.playerContainer");
  498. const info = {};
  499. for (const player of players) {
  500. const playerId = player.querySelector("span.player_id_span")?.innerText;
  501. const inMarket = [...player.querySelectorAll("a")].find((el) => el.href?.indexOf("p=transfer&sub") > -1);
  502. info[playerId] = {
  503. detail: player,
  504. shared: !!player.querySelector("i.special_player.fa-share-alt"),
  505. market: !!inMarket,
  506. marketLink: inMarket?.href,
  507. name: player.querySelector("span.player_name")?.innerText,
  508. age: player.querySelector(".dg_playerview_info__table tbody tr:nth-child(1) td:nth-child(1) strong")?.innerText,
  509. }
  510. }
  511. return info;
  512. }
  513. return null;
  514. }
  515.  
  516. // -------------------------------------------- Icons ------------------------------------------
  517.  
  518. function mazyarStartSpinning(element) {
  519. element.classList.add("fa-spin");
  520. }
  521.  
  522. function mazyarStopSpinning(element) {
  523. element.classList.remove("fa-spin");
  524. }
  525.  
  526. function mazyarCreateIconFromFontAwesomeClass(classes = [], title = "") {
  527. const icon = document.createElement("i");
  528. icon.classList.add(...classes);
  529. icon.setAttribute("aria-hidden", "true");
  530. icon.style.cursor = "pointer";
  531. if (title) {
  532. icon.title = title;
  533. }
  534. return icon;
  535. }
  536.  
  537. function mazyarCreateMoveIcon(title) {
  538. return mazyarCreateIconFromFontAwesomeClass(["fa-solid", "fa-up-down-left-right"], title);
  539. }
  540.  
  541. function mazyarCreateSharedIcon(title) {
  542. return mazyarCreateIconFromFontAwesomeClass(["fa", "fa-share-alt"], title);
  543. }
  544.  
  545. function mazyarCreateMarketIcon(title) {
  546. return mazyarCreateIconFromFontAwesomeClass(["fa", "fa-legal"], title);
  547. }
  548.  
  549. function mazyarCreateCogIcon(title = "") {
  550. return mazyarCreateIconFromFontAwesomeClass(["fa", "fa-cog"], title);
  551. }
  552.  
  553. function mazyarCreateCommentIcon(title = "") {
  554. return mazyarCreateIconFromFontAwesomeClass(["fa-solid", "fa-comment"], title);
  555. }
  556.  
  557. function mazyarCreateSearchIcon(title = "") {
  558. return mazyarCreateIconFromFontAwesomeClass(["fa", "fa-search"], title);
  559. }
  560.  
  561. function mazyarCreateNoteIcon(title = "") {
  562. return mazyarCreateIconFromFontAwesomeClass(["fa-solid", "fa-note-sticky"], title);
  563. }
  564.  
  565. function mazyarCreateRefreshIcon(title = "") {
  566. return mazyarCreateIconFromFontAwesomeClass(["fa", "fa-refresh"], title);
  567. }
  568.  
  569. function mazyarCreateLegalIcon(title = "") {
  570. return mazyarCreateIconFromFontAwesomeClass(["fa", "fa-legal"], title);
  571. }
  572.  
  573. function mazyarCreateTrashIcon(title = "") {
  574. return mazyarCreateIconFromFontAwesomeClass(["fas", "fa-trash"], title);
  575. }
  576.  
  577. function mazyarCreateSignalIcon(title = "") {
  578. return mazyarCreateIconFromFontAwesomeClass(["fa-solid", "fa-signal-stream"], title);
  579. }
  580.  
  581. function mazyarCreateLoadingIcon(title = "") {
  582. const icon = mazyarCreateIconFromFontAwesomeClass(["fa", "fa-spinner", "fa-spin"], title);
  583. icon.style.cursor = "unset";
  584. return icon;
  585. }
  586.  
  587. function mazyarCreateLoadingIcon2(title = "") {
  588. const icon = mazyarCreateIconFromFontAwesomeClass(["fa-solid", "fa-loader", "fa-pulse", "fa-fw"], title);
  589. icon.style.cursor = "unset";
  590. return icon;
  591. }
  592.  
  593. function mazyarCreateDeadlineIndicator() {
  594. const div = document.createElement("div");
  595. const transferIcon = mazyarCreateLegalIcon();
  596.  
  597. div.classList.add("mazyar-flex-container");
  598. div.style.position = "fixed";
  599. div.style.zIndex = "9997";
  600. div.style.top = "48%";
  601. div.style.right = "35px";
  602. div.style.color = "white";
  603. div.style.textAlign = "center";
  604.  
  605. transferIcon.style.fontSize = "2rem";
  606.  
  607. div.appendChild(transferIcon);
  608.  
  609. return div;
  610. }
  611.  
  612. function mazyarCreateDeleteIcon(title) {
  613. const icon = document.createElement("span");
  614. icon.classList.add("mazyar-icon-delete");
  615. if (title) {
  616. icon.title = title;
  617. }
  618. return icon;
  619. }
  620.  
  621. function mazyarCreateAddToDeadlineIcon(title, color) {
  622. const icon = mazyarCreateLegalIcon();
  623. icon.style.verticalAlign = "unset";
  624. icon.style.borderRadius = "50%";
  625. icon.style.border = "solid 1px";
  626. icon.style.padding = "3px";
  627.  
  628. const span = document.createElement("span");
  629. span.style.color = color;
  630. span.classList.add("floatRight");
  631. if (title) {
  632. span.title = title;
  633. }
  634. span.appendChild(icon);
  635. return span;
  636. }
  637.  
  638. // -------------------------------- DOM Utils ------------------------------
  639.  
  640. function mazyarMakeElementDraggable(element, dragHandleElement, dragEndCallback = null) {
  641. let deltaX = 0, deltaY = 0, lastX = 0, lastY = 0;
  642.  
  643. dragHandleElement.style.cursor = "move";
  644. dragHandleElement.onmousedown = dragMouseDown;
  645.  
  646. function dragMouseDown(e) {
  647. e = e || window.event;
  648. e.preventDefault();
  649. // get the mouse cursor position at startup:
  650. lastX = e.clientX;
  651. lastY = e.clientY;
  652. document.onmouseup = closeDragElement;
  653. // call a function whenever the cursor moves:
  654. document.onmousemove = elementDrag;
  655. }
  656.  
  657. function elementDrag(e) {
  658. e = e || window.event;
  659. e.preventDefault();
  660.  
  661. // calculate the new cursor position:
  662. deltaX = lastX - e.clientX;
  663. deltaY = lastY - e.clientY;
  664. lastX = e.clientX;
  665. lastY = e.clientY;
  666.  
  667. // set the element's new position:
  668. let newTop = Math.max(0, element.offsetTop - deltaY);
  669. let newLeft = Math.max(0, element.offsetLeft - deltaX);
  670.  
  671. const { right, bottom, width, height } = element.getBoundingClientRect();
  672. if (right > window.innerWidth) {
  673. newLeft = window.innerWidth - width;
  674. }
  675. if (bottom > window.innerHeight) {
  676. newTop = window.innerHeight - height;
  677. }
  678.  
  679. element.style.top = newTop + "px";
  680. element.style.left = newLeft + "px";
  681. }
  682.  
  683. function closeDragElement() {
  684. // stop moving when mouse button is released:
  685. document.onmouseup = null;
  686. document.onmousemove = null;
  687. if (dragEndCallback) {
  688. dragEndCallback();
  689. }
  690. }
  691. }
  692.  
  693. function mazyarColorizeMaxedSkills(player, maxed = []) {
  694. if (maxed) {
  695. const playerSkills = player.querySelectorAll("table.player_skills tr td.skillval span");
  696. for (const skill of maxed) {
  697. playerSkills[skill]?.classList.add("maxed");
  698. }
  699. }
  700. }
  701.  
  702. function mazyarColorizeSkills(player, report = { H: 4, L: 2, HS: [0, 1], LS: [2, 3] }) {
  703. if (report) {
  704. const playerSkills = player?.querySelectorAll("table.player_skills tr td:nth-child(1)");
  705. playerSkills[report.HS[0]]?.classList.add("mazyar-scout-h", `mazyar-scout-${report.H}`);
  706. playerSkills[report.HS[1]]?.classList.add("mazyar-scout-h", `mazyar-scout-${report.H}`);
  707. playerSkills[report.LS[0]]?.classList.add(`mazyar-scout-${report.L}`);
  708. playerSkills[report.LS[1]]?.classList.add(`mazyar-scout-${report.L}`);
  709. }
  710. }
  711.  
  712. function mazyarGetMzButtonColorClass(color) {
  713. if (color) {
  714. if (color === "red") {
  715. return "button_red";
  716. } else if (color === "blue") {
  717. return "button_blue";
  718. } else if (color === "grey") {
  719. return "buttondiv_disabled";
  720. }
  721. }
  722. // green or other values
  723. return "button_account";
  724. }
  725.  
  726. function mazyarCreateMzStyledButton(title, color = "", floatDirection = null) {
  727. const div = document.createElement("div");
  728. div.style.margin = "auto 0.3rem";
  729. if (floatDirection) {
  730. // floatDirection: floatRight, floatLeft
  731. div.classList.add(floatDirection);
  732. }
  733.  
  734. const button = document.createElement("div");
  735. button.classList.add("mzbtn", "buttondiv", mazyarGetMzButtonColorClass(color));
  736. button.innerHTML = `<span class="buttonClassMiddle"><span style="white-space: nowrap">${title}</span></span><span class="buttonClassRight">&nbsp;</span>`;
  737.  
  738. div.appendChild(button);
  739. return div;
  740. }
  741.  
  742. function mazyarCreateSettingsSectionButton(text = "", style = { backgroundColor: null }) {
  743. const button = document.createElement("button");
  744. button.innerText = text;
  745. button.classList.add("mazyar-settings-section-button");
  746. if (style?.backgroundColor) {
  747. button.style.backgroundColor = style.backgroundColor;
  748. }
  749. return button;
  750. }
  751.  
  752. function mazyarCreateMzStyledCloseButton(callback) {
  753. const div = document.createElement("div");
  754. div.classList.add("mazyar-cross-close-button");
  755.  
  756. div.innerHTML = `
  757. <span class="fa-stack fa-lg">
  758. <i class="fa fa-circle fa-stack-2x fa-inverse"></i>
  759. <i class="fa fa-close fa-stack-1x"></i>
  760. </span>`;
  761.  
  762. div.addEventListener("click", callback);
  763. return div;
  764. }
  765.  
  766. function mazyarCreateMzStyledTitle(text = "", closeCallback = null) {
  767. const div = document.createElement("div");
  768. div.classList.add("mazyar-modal-title", "mazyar-flex-container-row");
  769.  
  770. const title = document.createElement("span");
  771. title.innerText = text;
  772. title.style.flexGrow = "1";
  773. title.style.fontWeight = "bold";
  774. title.style.fontSize = "larger";
  775. title.style.padding = "5px";
  776.  
  777. div.appendChild(title);
  778.  
  779. if (closeCallback) {
  780. const close = mazyarCreateMzStyledCloseButton(closeCallback);
  781. div.appendChild(close);
  782. }
  783. return div;
  784. }
  785.  
  786. function mazyarCreateSuggestionList(items) {
  787. const datalist = document.createElement("datalist");
  788. datalist.id = mazyarGenerateUuidV4();
  789. for (const item of items) {
  790. const option = document.createElement("option");
  791. option.value = item.toString();
  792. datalist.appendChild(option);
  793. }
  794. return datalist;
  795. }
  796.  
  797. function mazyarCreateMenuTextInput(title = "input", placeholder = "example", datalistId = "") {
  798. const div = document.createElement("div");
  799. div.classList.add("mazyar-flex-container-row");
  800. div.style.justifyItems = "space-between";
  801. div.innerHTML = `
  802. <label style="margin: 0.5rem; font-weight: bold;">${title}: </label>
  803. <input list="${datalistId}" style="margin: 0.5rem;" type="text" value="" placeholder="${placeholder}">
  804. `;
  805. return div;
  806. }
  807.  
  808. function mazyarCreateSubMenuTextInput(title = "input", placeholder = "example", initialValue = 0, style = {
  809. margin: "0.1rem 2.2rem",
  810. inputSize: "5px"
  811. }) {
  812. const div = document.createElement("div");
  813. div.classList.add("mazyar-flex-container-row");
  814. div.style.justifyItems = "space-between";
  815. div.style.margin = style?.margin ?? "0.1rem 2.2rem";
  816. div.innerHTML = `
  817. <label style="margin-left: 0.5rem;">${title}: </label>
  818. <input style="margin-left: 0.5rem;" type="text" size="${style?.inputSize ?? "5px"}" placeholder="${placeholder}", value="${initialValue}">
  819. `;
  820. return div;
  821. }
  822.  
  823. function mazyarCreateMenuCheckBox(
  824. label,
  825. initialValue = true,
  826. style = {
  827. alignSelf: "flex-start",
  828. margin: "0.3rem 0.7rem",
  829. }
  830. ) {
  831. const id = mazyarGenerateUuidV4();
  832.  
  833. const div = document.createElement("div");
  834. div.style.alignSelf = style?.alignSelf ?? "flex-start";
  835. div.style.margin = style?.margin ?? "0.3rem 0.7rem";
  836.  
  837. const checkbox = document.createElement("input");
  838. checkbox.id = id;
  839. checkbox.type = "checkbox";
  840. checkbox.checked = initialValue;
  841.  
  842. const labelElement = document.createElement("label");
  843. labelElement.htmlFor = id;
  844. labelElement.innerHTML = label;
  845.  
  846. div.appendChild(checkbox);
  847. div.appendChild(labelElement);
  848. return div;
  849. }
  850.  
  851. function mazyarCreateMenuGroup(title = "") {
  852. const group = document.createElement("div");
  853. group.classList.add("mazyar-flex-container");
  854. group.style.alignSelf = "flex-start";
  855. group.style.alignItems = "flex-start";
  856. group.style.margin = "0.2rem 0.6rem";
  857. const header = document.createElement("h4");
  858. header.innerText = title;
  859. header.style.margin = "0.3rem 0rem";
  860. group.appendChild(header);
  861. return group;
  862. }
  863.  
  864. function mazyarAppendOptionList(parent, options, selected) {
  865. // options = a object full of 'key: {value, label}'
  866. for (const key in options) {
  867. if (options.hasOwnProperty(key)) {
  868. const child = document.createElement("option");
  869. child.value = options[key].value;
  870. child.innerText = options[key].label;
  871. if (child.value === selected) {
  872. child.selected = true;
  873. }
  874. parent.appendChild(child);
  875. }
  876. }
  877. }
  878.  
  879. function mazyarCreateDropDownMenu(label, options, initialValue) {
  880. // options = a object full of 'key: {value, label}'
  881. // initialValue = one of the options.value
  882.  
  883. const div = document.createElement("div");
  884. const labelElement = document.createElement("label");
  885. const dropdown = document.createElement("select");
  886.  
  887. div.style.alignSelf = "flex-start";
  888. div.style.margin = "0.3rem 0.7rem";
  889.  
  890. labelElement.innerText = label;
  891. labelElement.style.paddingRight = "0.5rem";
  892.  
  893. mazyarAppendOptionList(dropdown, options, initialValue);
  894.  
  895. div.appendChild(labelElement);
  896. div.appendChild(dropdown);
  897. return div;
  898. }
  899.  
  900. function mazyarCreateDeleteButtonWithTrashIcon(title = "Delete") {
  901. const icon = mazyarCreateDeleteIcon();
  902.  
  903. const text = document.createElement("span");
  904. text.innerText = title;
  905.  
  906. const button = document.createElement("button");
  907. button.classList.add("mazyar-flex-container-row", "mazyar-button");
  908. button.style.margin = "0.6rem 0 0";
  909.  
  910. button.appendChild(icon);
  911. button.appendChild(text);
  912. return button;
  913. }
  914.  
  915. function mazyarCreateTableHeaderForFiltersView() {
  916. const tr = document.createElement("tr");
  917.  
  918. const name = document.createElement("th");
  919. name.classList.add("header");
  920. name.innerText = "Name";
  921. name.title = "Filter' name";
  922. name.style.textAlign = "left";
  923. name.style.textDecoration = "none";
  924. name.style.width = "11rem";
  925.  
  926. const totalHits = document.createElement("th");
  927. totalHits.classList.add("header");
  928. totalHits.innerText = "Total";
  929. totalHits.title = "Total hits founds for this filter";
  930. totalHits.style.textAlign = "center";
  931. totalHits.style.textDecoration = "none";
  932.  
  933. const scoutHits = document.createElement("th");
  934. scoutHits.classList.add("header");
  935. scoutHits.innerText = "Scout";
  936. scoutHits.title = "Hits found after applying scout filters";
  937. scoutHits.style.textAlign = "center";
  938. scoutHits.style.textDecoration = "none";
  939.  
  940. const tools = document.createElement("th");
  941. tools.classList.add("header");
  942. tools.innerHTML = " ";
  943. tools.style.textAlign = "center";
  944. tools.style.textDecoration = "none";
  945.  
  946. tr.appendChild(tools);
  947. tr.appendChild(name);
  948. tr.appendChild(totalHits);
  949. tr.appendChild(scoutHits);
  950.  
  951. const thead = document.createElement("thead");
  952. thead.appendChild(tr);
  953. return thead;
  954. }
  955.  
  956. function mazyarCreateToolbar() {
  957. const toolbar = document.createElement("div");
  958. const logo = document.createElement("span");
  959. const menu = mazyarCreateCogIcon("Settings");
  960. const note = mazyarCreateNoteIcon("Notebook");
  961. const live = mazyarCreateSignalIcon("In Progress Results");
  962. const separator = document.createElement("span");
  963. const transfer = document.createElement("div");
  964. const transferIcon = mazyarCreateSearchIcon("Transfer");
  965. const transferCount = document.createElement("span");
  966.  
  967. toolbar.classList.add("mazyar-flex-container");
  968. toolbar.style.position = "fixed";
  969. toolbar.style.zIndex = "9998";
  970. toolbar.style.top = "40%";
  971. toolbar.style.right = "5px";
  972. toolbar.style.background = "black";
  973. toolbar.style.color = "white";
  974. toolbar.style.textAlign = "center";
  975.  
  976. logo.innerText = "MZY";
  977. logo.style.fontSize = "0.6rem";
  978. logo.style.fontWeight = "bold";
  979. logo.style.margin = "2px";
  980. logo.style.padding = "1px";
  981.  
  982. menu.style.fontSize = "large";
  983.  
  984. note.style.fontSize = "large";
  985. note.style.marginTop = "5px";
  986.  
  987. live.style.fontSize = "large";
  988. live.style.marginTop = "5px";
  989. live.id = "mazyar-in-progress-icon";
  990.  
  991. transferIcon.style.fontSize = "large";
  992.  
  993. separator.innerText = "-------";
  994. separator.style.textAlign = "center";
  995. separator.style.fontSize = "0.6rem";
  996. separator.style.fontWeight = "bolder";
  997. separator.style.margin = "0";
  998. separator.style.padding = "0";
  999.  
  1000. transfer.classList.add("mazyar-flex-container");
  1001. transfer.style.cursor = "pointer";
  1002.  
  1003. transferCount.id = "mazyar-transfer-filter-hits";
  1004. transferCount.innerText = "0";
  1005. transferCount.style.fontSize = "0.6rem";
  1006. transferCount.style.fontWeight = "bold";
  1007. transferCount.style.margin = "1px 0";
  1008. transferCount.style.padding = "1px";
  1009.  
  1010. transfer.appendChild(transferIcon);
  1011. transfer.appendChild(transferCount);
  1012.  
  1013. toolbar.appendChild(logo);
  1014. toolbar.appendChild(menu);
  1015. toolbar.appendChild(note);
  1016. toolbar.appendChild(live);
  1017. toolbar.appendChild(separator);
  1018. toolbar.appendChild(transfer);
  1019.  
  1020. return { toolbar, menu, transfer, note, live };
  1021. }
  1022.  
  1023.  
  1024. /* *********************** Monitor ********************************** */
  1025.  
  1026. function mazyarCreateSectionSeparatorForMonitor() {
  1027. const tr = document.createElement("tr");
  1028. tr.style.height = "10px";
  1029. tr.innerHTML = '<td></td>';
  1030. return tr;
  1031. }
  1032.  
  1033. function mazyarCreateRowSeparatorForMonitor(color) {
  1034. const tr = document.createElement("tr");
  1035. tr.classList.add("mazyar-monitor-player-row");
  1036. tr.style.height = "1px";
  1037. tr.style.backgroundColor = color;
  1038. tr.innerHTML = '<td></td>';
  1039. return tr;
  1040. }
  1041.  
  1042. function monitorAddRowSeparator() {
  1043. return [
  1044. mazyarCreateRowSeparatorForMonitor("#999999"),
  1045. mazyarCreateRowSeparatorForMonitor("#FFFFFF")
  1046. ];
  1047. }
  1048.  
  1049. function mazyarCreateSectionForMonitor(title, id) {
  1050. const tr = document.createElement("tr");
  1051. tr.innerHTML = `
  1052. <td><div id="${id}">
  1053. <table width="100%" cellpadding="0" cellspacing="0">
  1054. <tbody><tr>
  1055. <td style="background-image: url(img/subheader_right.gif);">
  1056. <table border="0" cellpadding="0" cellspacing="0" width="100%">
  1057. <tbody><tr>
  1058. <td class="subheader" valign="bottom">${title}</td>
  1059. </tr></tbody>
  1060. </table>
  1061. </td>
  1062. </tr></tbody>
  1063. </table>
  1064. </div></td>`;
  1065. return tr;
  1066. }
  1067.  
  1068. function mazyarClearPlayerRowsInMonitor(tbody) {
  1069. const players = tbody.querySelectorAll(".mazyar-monitor-player-row");
  1070. for (const player of players) {
  1071. tbody.removeChild(player);
  1072. }
  1073. }
  1074.  
  1075. async function mazyarFetchPlayerMarketDetail(pid, sport = "soccer") {
  1076. const url = `https://${location.hostname}/ajax.php?p=transfer&sub=transfer-search&sport=${sport}&u=${pid}`;
  1077. const result = await mazyarFetchJson(url);
  1078. if (result) {
  1079. if (result.totalHits > 0) {
  1080. const parser = new DOMParser();
  1081. const playerDiv = parser.parseFromString(result?.players, "text/html").body.firstChild;
  1082. const deadline = playerDiv.querySelector(".transfer-control-area div.box_dark:nth-child(1) table:nth-child(1) tr:nth-child(3) strong")?.innerText;
  1083. const fee = playerDiv.querySelector(".transfer-control-area > div > div:nth-child(1) > table > tbody > tr:last-child strong")?.innerText;
  1084. const latestBid = playerDiv.querySelector(".transfer-control-area > div > div:nth-child(2) > table > tbody > tr:last-child strong")?.innerText;
  1085. const flag = playerDiv.querySelector(`img[src*="/flags/"]`)?.src;
  1086. const player = {
  1087. name: playerDiv.querySelector(".player_name")?.innerText,
  1088. pid,
  1089. deadline: 1 + Math.ceil((mazyarParseMzDateTime(deadline.trim()) - new Date()) / 60_000),
  1090. deadlineFull: deadline.trim(),
  1091. latestBid,
  1092. fee,
  1093. source: "mzy",
  1094. flag,
  1095. };
  1096. return { player, remove: false };
  1097. }
  1098. return { player: null, remove: true };
  1099. }
  1100. return { player: null, remove: false };
  1101. }
  1102.  
  1103.  
  1104. function mazyarCreatePlayerRowForMonitor(
  1105. player = { pid: "", name: "", deadline: 0, deadlineFull: "", latestBid: "", flag: "" },
  1106. timeout = 0) {
  1107. const tr = document.createElement("tr");
  1108. tr.classList.add("mazyar-monitor-player-row");
  1109. if (player.deadline <= timeout) {
  1110. tr.classList.add("mazyar-deadline-monitor-throb");
  1111. }
  1112. tr.innerHTML = `
  1113. <td valign="top" style="" width="100%">
  1114. <table width="100%" border="0">
  1115. <tbody>
  1116. <tr style="height: 25px;">
  1117. <td colspan="2">
  1118. <table cellpadding="0" cellspacing="0" width="100%" border="0">
  1119. <tbody>
  1120. <tr>
  1121. <td width="220">
  1122. <table>
  1123. <tbody>
  1124. <tr>
  1125. <td><img src="${player.flag}"></td>
  1126. <td><a target="_blank", href="/?p=transfer&sub=players&u=${player.pid}">${player.name}</a></td>
  1127. <td></td>
  1128. </tr>
  1129. </tbody>
  1130. </table>
  1131. </td>
  1132. <td>
  1133. <table class="deadline-table">
  1134. <tbody>
  1135. <tr>
  1136. <td><img src="img/icon_deadline.gif" width="13" height="15"></td>
  1137. <td>${player.deadlineFull}</td>
  1138. </tr>
  1139. </tbody>
  1140. </table>
  1141. </td>
  1142. <td align="right">
  1143. <table border="0">
  1144. <tbody>
  1145. <tr>
  1146. <td>Latest bid:</td>
  1147. <td align="right" style="font-size: 11px; font-weight: bold;">${player.latestBid}</td>
  1148. <td>&nbsp;</td>
  1149. </tr>
  1150. </tbody>
  1151. </table>
  1152. </td>
  1153. </tr>
  1154. </tbody>
  1155. </table>
  1156. </td>
  1157. </tr>
  1158. </tbody>
  1159. </table>
  1160. </td>
  1161. `;
  1162. return tr;
  1163. }

QingJ © 2025

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