(改)网盘直链下载助手

可以获取网盘文件真实下载地址。现已支持百度阿里天翼迅雷夸克移动六大网盘,基于【网盘直链下载助手】修改自6.0.4版本,自用,去推广,修原有BUG,修改界面,比原版还好用!

当前为 2023-05-08 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name (改)网盘直链下载助手
  3. // @namespace https://github.com/syhyz1990/baiduyun
  4. // @version 1.0.6.2
  5. // @author Hmjz100、油小猴
  6. // @icon data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxMjggMTI4Ij48cGF0aCBkPSJNMTAzLjYgMTA3LjRjMy41LTIuMiA4LjktNi4xIDEzLjgtMTIuNXM3LjMtMTIuNSA4LjUtMTYuNWMuNS0xLjcgMi4yLTcuNSAyLjItMTQuNyAwLTEwLjEtMy4zLTI1LjEtMTUuNC0zNi44LTE0LjUtMTQtMzIuMS0xNC4zLTM1LjctMTQuMy04IDAtMTUuNyAxLjktMjIuNiA1LjJDNDQgMjMgMzUuNyAzMS40IDMwLjggNDEuN2MtMS4zIDIuOC00IDQuNy03LjEgNS00IC4zLTcuNSA0LjQtOC45IDkuNi0uNSAxLjktMS42IDMuNS0zLjEgNC43QzQuNCA2Ni44IDAgNzUuNyAwIDg1YzAgNi44IDIuMyAxMy4xIDYuMSAxOC4yIDUuNSA3LjQgMTQuMiAxMi4yIDI0IDEyLjJoNDcuMWM0LjQgMCAxMS0uNSAxOC4zLTMuNSAzLjItMS40IDUuOS0zIDguMS00LjV6IiBmaWxsPSIjNDQ0Ii8+PHBhdGggZD0iTTExOS44IDY0LjNjLjEtMTcuMS0xMC40LTI4LTEyLjUtMzAuMUM5NSAyMi4xIDc5LjkgMjEuOCA3Ni45IDIxLjhjLTE3LjYgMC0zMy4zIDEwLjUtMzkuOSAyNi43LS42IDEuMy0xLjggMi4zLTMuNCAyLjNoLS40Yy01LjggMC0xMC42IDQuOC0xMC42IDEwLjd2LjVjMCAxLjQtLjggMi42LTEuOSAzLjNDMTMuNCA2OSA4LjggNzYuOCA4LjggODVjMCAxMi4yIDkuOSAyMi4zIDIyLjIgMjIuM2g0NS4yYzMuNi0uMSAxNy42LS45IDI5LjYtMTIgMi45LTIuOCAxMy45LTEzLjcgMTQtMzF6IiBmaWxsPSIjMTM5N2Q4Ii8+PHBhdGggZD0iTTExMC44IDU3LjRsLjIgMy4zYzAgMS4zLTEuMSAyLjQtMi4zIDIuNC0xLjMgMC0yLjMtMS4xLTIuMy0yLjRsLS4xLTIuOHYtLjNjMC0xLjIuOS0yLjIgMi4xLTIuM2guM2MuNyAwIDEuMy4zIDEuNy43LS4yLjEuMy41LjQgMS40em0tMy4zLTEwLjNjMCAxLjItMSAyLjMtMi4yIDIuM2gtLjFjLS44IDAtMS42LS41LTItMS4yLTQuNi04LjMtMTMuMy0xMy41LTIyLjgtMTMuNS0xLjIgMC0yLjMtMS0yLjMtMi4ydi0uMWMwLTEuMiAxLTIuMyAyLjItMi4zaC4xYTMwLjM3IDMwLjM3IDAgMCAxIDE1LjggNC40YzQuNiAyLjggOC40IDYuOCAxMS4xIDExLjUuMS4zLjIuNy4yIDEuMXpNODguMyA3My44TDczLjUgOTMuMmMtMS41IDEuOS0zLjUgMy4xLTUuNyAzLjVoLS4yYy0uNC4xLS44LjEtMS4yLjEtLjYgMC0xLjEtLjEtMS42LS4yLTIuMi0uNC00LjItMS43LTUuNi0zLjVMNDQuMyA3My45Yy0yLTIuNi0yLjUtNS40LTEuNC03LjcuMS0uMS4xLS4yLjItLjIgMS4yLTIgMy41LTMuMiA2LjQtMy4yaDYuNnYtNS43YzAtNi44IDQuNy0xMiAxMC45LTEyIDQuOCAwIDguNSAyLjYgMTAuMyA3LjIuNSAxLjMtLjIgMi43LTEuNSAzLjJzLTIuOC0uMS0zLjMtMS40Yy0xLjEtMi43LTIuOS00LTUuNS00LTMuNSAwLTYgMy02IDd2OC4xYzAgLjUtLjIgMS0uNiAxLjQtLjYuNy0xLjcgMS4xLTIuNiAxLjFoLTguNGMtMS4zIDAtMiAuNC0yLjEuNy0uMi40IDAgMS4zLjkgMi40TDYzLjEgOTBjLjkgMS4yIDIuMSAxLjggMy4zIDEuOHMyLjMtLjYgMy4xLTEuN2wxNC44LTE5LjNjLjktMS4xIDEuMS0yIC45LTIuNC0uMi0uMy0uOS0uNy0yLjEtLjdoLTcuNmMtLjkgMC0xLjctLjUtMi4xLTEuMi0uMy0uNC0uNC0uOC0uNC0xLjMgMC0xLjQgMS4xLTIuNSAyLjUtMi41aDcuNmMzLjEgMCA1LjUgMS4zIDYuNiAzLjVsLjMuN2MuNyAyLjEuMSA0LjYtMS43IDYuOXoiIGZpbGw9IiM0NDQiLz48L3N2Zz4=
  7. // @description 可以获取网盘文件真实下载地址。现已支持百度阿里天翼迅雷夸克移动六大网盘,基于【网盘直链下载助手】修改自6.0.4版本,自用,去推广,修原有BUG,修改界面,比原版还好用!
  8. // @license MIT
  9. // @homepage https://github.com/hmjz100/Online-disk-direct-link-download-assistant/
  10. // @supportURL https://github.com/hmjz100/Online-disk-direct-link-download-assistant/issues
  11. // @match *://pan.baidu.com/disk/home*
  12. // @match *://yun.baidu.com/disk/home*
  13. // @match *://pan.baidu.com/disk/main*
  14. // @match *://yun.baidu.com/disk/main*
  15. // @match *://pan.baidu.com/s/*
  16. // @match *://yun.baidu.com/s/*
  17. // @match *://pan.baidu.com/share/*
  18. // @match *://yun.baidu.com/share/*
  19. // @match *://www.aliyundrive.com/s/*
  20. // @match *://www.aliyundrive.com/drive*
  21. // @match *://cloud.189.cn/web/*
  22. // @match *://pan.xunlei.com/*
  23. // @match *://pan.quark.cn/*
  24. // @match *://yun.139.com/*
  25. // @match *://caiyun.139.com/*
  26. // @match *://*.youxiaohou.com/*
  27. // @require https://unpkg.com/jquery@3.6.0/dist/jquery.min.js
  28. // @require https://unpkg.com/sweetalert2@11/dist/sweetalert2.js
  29. // @require https://unpkg.com/js-md5@0.7.3/build/md5.min.js
  30. // @connect baidu.com
  31. // @connect baidupcs.com
  32. // @connect aliyundrive.com
  33. // @connect 189.cn
  34. // @connect xunlei.com
  35. // @connect quark.cn
  36. // @connect youxiaohou.com
  37. // @connect localhost
  38. // @connect *
  39. // @run-at document-idle
  40. // @compatible Chrome
  41. // @compatible Firefox
  42. // @compatible Safari
  43. // @compatible Opera
  44. // @grant unsafeWindow
  45. // @grant GM_xmlhttpRequest
  46. // @grant GM_setClipboard
  47. // @grant GM_setValue
  48. // @grant GM_getValue
  49. // @grant GM_openInTab
  50. // @grant GM_info
  51. // @grant GM_registerMenuCommand
  52. // @grant GM_cookie
  53. // @grant GM_addStyle
  54. // @grant GM_getResourceText
  55. // ==/UserScript==
  56.  
  57. (function () {
  58. 'use strict';
  59. function generateRandomNumberInRange(min, max) {
  60. return Math.floor(Math.random() * (max - min + 1) + min);
  61. };
  62. /*--- waitForKeyElements(): A utility function, for Greasemonkey scripts,
  63. that detects and handles AJAXed content.
  64. Usage example:
  65. waitForKeyElements (
  66. "div.comments"
  67. , commentCallbackFunction
  68. );
  69. //--- Page-specific function to do what we want when the node is found.
  70. function commentCallbackFunction (jNode) {
  71. jNode.text ("This comment changed by waitForKeyElements().");
  72. }
  73. IMPORTANT: This function requires your script to have loaded jQuery.
  74. */
  75. function waitForKeyElements(selectorTxt, actionFunction, bWaitOnce, iframeSelector) {
  76. var targetNodes, btargetsFound;
  77.  
  78. if (typeof iframeSelector == "undefined")
  79. targetNodes = $(selectorTxt);
  80. else
  81. targetNodes = $(iframeSelector).contents()
  82. .find(selectorTxt);
  83.  
  84. if (targetNodes && targetNodes.length > 0) {
  85. btargetsFound = true;
  86. targetNodes.each(function () {
  87. var jThis = $(this);
  88. var alreadyFound = jThis.data('alreadyFound') || false;
  89.  
  90. if (!alreadyFound) {
  91. //--- Call the payload function.
  92. var cancelFound = actionFunction(jThis);
  93. if (cancelFound) btargetsFound = false;
  94. else jThis.data('alreadyFound', true);
  95. }
  96. });
  97. } else {
  98. btargetsFound = false;
  99. }
  100.  
  101. //--- Get the timer-control variable for this selector.
  102. var controlObj = waitForKeyElements.controlObj || {};
  103. var controlKey = selectorTxt.replace(/[^\w]/g, "_");
  104. var timeControl = controlObj[controlKey];
  105.  
  106. //--- Now set or clear the timer as appropriate.
  107. if (btargetsFound && bWaitOnce && timeControl) {
  108. //--- The only condition where we need to clear the timer.
  109. clearInterval(timeControl);
  110. delete controlObj[controlKey]
  111. } else {
  112. //--- Set a timer, if needed.
  113. if (!timeControl) {
  114. timeControl = setInterval(function () {
  115. waitForKeyElements(selectorTxt, actionFunction, bWaitOnce, iframeSelector);
  116. }, 300);
  117. controlObj[controlKey] = timeControl;
  118. }
  119. }
  120. waitForKeyElements.controlObj = controlObj;
  121. }
  122. let pt = '', selectList = [], params = {}, mode = '', width = 800, pan = {}, color = '',
  123. doc = $(document), progress = {}, request = {}, ins = {}, idm = {};
  124.  
  125. //用于油小猴服务器检测的脚本内容
  126. const scriptInfo = GM_info.script;
  127.  
  128. //用于油小猴服务器检测的脚本版本
  129. const realversion = scriptInfo.version;
  130. const version = 9999999999999;//防止显示更新
  131. //const version = generateRandomNumberInRange(1000,9999999999);
  132.  
  133. //用于油小猴服务器检测的脚本作者
  134. const realauthor = scriptInfo.author;
  135. const author = '油小猴';
  136.  
  137. //用于油小猴服务器检测的脚本名称
  138. const realname = scriptInfo.name;
  139. const name = '网盘直链下载助手';
  140.  
  141. const customClass = {
  142. popup: 'pl-popup',
  143. header: 'pl-header',
  144. title: 'pl-title',
  145. closeButton: 'pl-close',
  146. content: 'pl-content',
  147. input: 'pl-input',
  148. footer: 'pl-footer'
  149. };//准备好要用到的元素
  150.  
  151.  
  152. //准备好Shell类型(用于curl下载)
  153. const terminalType = {
  154. wc: "Microsoft Windows 命令提示符",
  155. wp: "Microsoft Windows PowerShell",
  156. lt: "Linux 终端",
  157. ls: "Linux Shell",
  158. mt: "Apple MacOS 终端",
  159. };
  160.  
  161. //准备好信息界面的*假隐私设置*(实际上油小猴就是通过服务器获取的“暗号”)
  162. const getuserinfo = {
  163. yes: "允许",
  164. };
  165. const hideidm = {
  166. yes: "隐藏",
  167. no: "显示"
  168. };
  169.  
  170. //准备好右上角的Toast提示
  171. let toast = Swal.mixin({
  172. toast: true,
  173. position: 'top-end',
  174. showConfirmButton: false,
  175. timer: 3500,
  176. timerProgressBar: true,
  177. showCloseButton: true,
  178. didOpen: (toast) => {
  179. toast.addEventListener('mouseenter', Swal.stopTimer);
  180. toast.addEventListener('mouseleave', Swal.resumeTimer);
  181. }
  182. });
  183.  
  184. //提示的信息内容
  185. const message = {
  186. success: (text) => {
  187. toast.fire({title: text, icon: 'success'});
  188. },
  189. error: (text) => {
  190. toast.fire({title: text, icon: 'error'});
  191. },
  192. warning: (text) => {
  193. toast.fire({title: text, icon: 'warning'});
  194. },
  195. info: (text) => {
  196. toast.fire({title: text, icon: 'info'});
  197. },
  198. question: (text) => {
  199. toast.fire({title: text, icon: 'question'});
  200. }
  201. };
  202.  
  203. let base = {
  204. //脚本正常情况下默认加载的菜单
  205. registerMenuCommand() {
  206. GM_registerMenuCommand('⚙️ 设置', () => {
  207. base.showSetting();
  208. });
  209. GM_registerMenuCommand('更新日志', () => {
  210. base.showUpdateLog();
  211. });
  212. GM_registerMenuCommand('分析信息', () => {
  213. base.showInfo();
  214. });
  215. GM_registerMenuCommand('取消点亮按钮', () => {
  216. base.registerSetting();
  217. });
  218. },
  219.  
  220. registerPanMenuCommand() {
  221. GM_registerMenuCommand('⚙️ 设置', () => {
  222. base.showSetting();
  223. });
  224. GM_registerMenuCommand('更新日志', () => {
  225. base.showUpdateLog();
  226. });
  227. GM_registerMenuCommand('分析信息', () => {
  228. base.showPanInfo();
  229. });
  230. },
  231.  
  232. //取消点亮按钮按下后运行的
  233. registerSetting() {
  234. console.log("正在注入取消点亮按钮设置项目...");
  235. message.warning("正在注入取消点亮按钮设置项目...(您可以再次点亮按钮)");
  236. base.setValue('setting_init_code', 111111);
  237. history.go(0)
  238. },
  239.  
  240. //获取网页Cookie
  241. getCookie(name) {
  242. let arr = document.cookie.replace(/\s/g, "").split(';');
  243. for (let i = 0, l = arr.length; i < l; i++) {
  244. let tempArr = arr[i].split('=');
  245. if (tempArr[0] === name) {
  246. return decodeURIComponent(tempArr[1]);
  247. }
  248. }
  249. return '';
  250. },
  251.  
  252. isType(obj) {
  253. return Object.prototype.toString.call(obj).replace(/^\[object (.+)\]$/, '$1').toLowerCase();
  254. },
  255.  
  256. getValue(name) {
  257. return GM_getValue(name);
  258. },
  259.  
  260. setValue(name, value) {
  261. GM_setValue(name, value);
  262. },
  263.  
  264. getStorage(key) {
  265. try {
  266. return JSON.parse(localStorage.getItem(key));
  267. } catch (e) {
  268. return localStorage.getItem(key);
  269. }
  270. },
  271.  
  272. setStorage(key, value) {
  273. if (this.isType(value) === 'object' || this.isType(value) === 'array') {
  274. return localStorage.setItem(key, JSON.stringify(value));
  275. }
  276. return localStorage.setItem(key, value);
  277. },
  278.  
  279. setClipboard(text) {
  280. GM_setClipboard(text, 'text');
  281. },
  282.  
  283. e(str) {
  284. return btoa(unescape(encodeURIComponent(str)));
  285. },
  286.  
  287. d(str) {
  288. return decodeURIComponent(escape(atob(str)));
  289. },
  290.  
  291. getExtension(name) {
  292. const reg = /(?!\.)\w+$/;
  293. if (reg.test(name)) {
  294. let match = name.match(reg);
  295. return match[0].toUpperCase();
  296. }
  297. return '';
  298. },
  299.  
  300. sizeFormat(value) {
  301. if (value === +value) {
  302. let unit = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
  303. let index = Math.floor(Math.log(value) / Math.log(1024));
  304. let size = value / Math.pow(1024, index);
  305. size = size.toFixed(1);
  306. return size + unit[index];
  307. }
  308. return '';
  309. },
  310.  
  311. sortByName(arr) {
  312. const handle = () => {
  313. return (a, b) => {
  314. const p1 = a.filename ? a.filename : a.server_filename;
  315. const p2 = b.filename ? b.filename : b.server_filename;
  316. return p1.localeCompare(p2, "zh-CN");
  317. };
  318. };
  319. arr.sort(handle());
  320. },
  321.  
  322. fixFilename(name) {
  323. return name.replace(/[!?&|`"'*\/:<>\\]/g, '_');
  324. },
  325.  
  326. blobDownload(blob, filename) {
  327. if (blob instanceof Blob) {
  328. const url = URL.createObjectURL(blob);
  329. const a = document.createElement('a');
  330. a.href = url;
  331. a.download = filename;
  332. a.click();
  333. URL.revokeObjectURL(url);
  334. }
  335. },
  336.  
  337. post(url, data, headers, type) {
  338. if (this.isType(data) === 'object') {
  339. data = JSON.stringify(data);
  340. }
  341. return new Promise((resolve, reject) => {
  342. GM_xmlhttpRequest({
  343. method: "POST", url, headers, data,
  344. responseType: type || 'json',
  345. onload: (res) => {
  346. type === 'blob' ? resolve(res) : resolve(res.response || res.responseText);
  347. },
  348. onerror: (err) => {
  349. reject(err);
  350. },
  351. });
  352. });
  353. },
  354.  
  355. get(url, headers, type, extra) {
  356. return new Promise((resolve, reject) => {
  357. let requestObj = GM_xmlhttpRequest({
  358. method: "GET", url, headers,
  359. responseType: type || 'json',
  360. onload: (res) => {
  361. if (res.status === 204) {
  362. requestObj.abort();
  363. idm[extra.index] = true;
  364. }
  365. if (type === 'blob') {
  366. res.status === 200 && base.blobDownload(res.response, extra.filename);
  367. resolve(res);
  368. } else {
  369. resolve(res.response || res.responseText);
  370. }
  371. },
  372. onprogress: (res) => {
  373. if (extra && extra.filename && extra.index) {
  374. res.total > 0 ? progress[extra.index] = (res.loaded * 100 / res.total).toFixed(2) : progress[extra.index] = 0.00;
  375. }
  376. },
  377. onloadstart() {
  378. extra && extra.filename && extra.index && (request[extra.index] = requestObj);
  379. },
  380. onerror: (err) => {
  381. reject(err);
  382. },
  383. });
  384. });
  385. },
  386.  
  387. getFinalUrl(url, headers) {
  388. return new Promise((resolve, reject) => {
  389. let requestObj = GM_xmlhttpRequest({
  390. method: "GET", url, headers,
  391. onload: (res) => {
  392. resolve(res.finalUrl);
  393. },
  394. onerror: (err) => {
  395. reject(err);
  396. },
  397. });
  398. });
  399. },
  400.  
  401. addStyle(id, tag, css) {
  402. tag = tag || 'style';
  403. let doc = document, styleDom = doc.getElementById(id);
  404. if (styleDom) return;
  405. let style = doc.createElement(tag);
  406. style.rel = 'stylesheet';
  407. style.id = id;
  408. tag === 'style' ? style.innerHTML = css : style.href = css;
  409. doc.getElementsByTagName('head')[0].appendChild(style);
  410. },
  411.  
  412. sleep(time) {
  413. return new Promise(resolve => setTimeout(resolve, time));
  414. },
  415.  
  416. findReact(dom, traverseUp = 0) {
  417. const key = Object.keys(dom).find(key => {
  418. return key.startsWith("__reactFiber$")
  419. || key.startsWith("__reactInternalInstance$");
  420. });
  421. const domFiber = dom[key];
  422. if (domFiber == null) return null;
  423.  
  424. if (domFiber._currentElement) {
  425. let compFiber = domFiber._currentElement._owner;
  426. for (let i = 0; i < traverseUp; i++) {
  427. compFiber = compFiber._currentElement._owner;
  428. }
  429. return compFiber._instance;
  430. }
  431.  
  432. const GetCompFiber = fiber => {
  433. let parentFiber = fiber.return;
  434. while (typeof parentFiber.type == "string") {
  435. parentFiber = parentFiber.return;
  436. }
  437. return parentFiber;
  438. };
  439. let compFiber = GetCompFiber(domFiber);
  440. for (let i = 0; i < traverseUp; i++) {
  441. compFiber = GetCompFiber(compFiber);
  442. }
  443. return compFiber.stateNode || compFiber;
  444. },
  445.  
  446. //注册(不可用)默认设置
  447. initDefaultConfig() {
  448. let value = [{
  449. name: 'setting_rpc_domain',
  450. value: 'http://localhost'
  451. }, {
  452. name: 'setting_rpc_port',
  453. value: '16800'
  454. }, {
  455. name: 'setting_rpc_path',
  456. value: '/jsonrpc'
  457. }, {
  458. name: 'setting_rpc_token',
  459. value: ''
  460. }, {
  461. name: 'setting_rpc_dir',
  462. value: 'D:'
  463. }, {
  464. name: 'setting_terminal_type',
  465. value: 'wc'
  466. }, {
  467. name: 'setting_theme_color',
  468. value: '#574ab8'
  469. }, {
  470. name: 'setting_init_code',
  471. value: ''
  472. }, {
  473. name: 'setting_getuser_info',
  474. value: 'yes'
  475. }, {
  476. name: 'setting_hide_idm',
  477. value: 'no'
  478. }];
  479.  
  480. value.forEach((v) => {
  481. base.getValue(v.name) === undefined && base.setValue(v.name, v.value);
  482. });
  483. },
  484.  
  485. showSetting() {
  486. let dom = '', btn = '',
  487. colorList = ['#09AAFF', '#cc3235', '#526efa', '#518c17', '#ed944b', '#f969a5', '#bca280', '#574ab8', '#F8D800', '#0396FF', '#32CCBC', '#F6416C', '#2271b1', '#59524c', '#1d2327', '#18a497', '#10171d', '#2828ff'];
  488. dom += `<label class="pl-setting-label"><div class="pl-label">RPC主机</div><input type="text" placeholder="主机地址,需带上http(s)://" class="pl-input listener-domain" value="${base.getValue('setting_rpc_domain')}"></label>`;
  489. dom += `<label class="pl-setting-label"><div class="pl-label">RPC端口</div><input type="text" placeholder="端口号,例如:Motrix为16800" class="pl-input listener-port" value="${base.getValue('setting_rpc_port')}"></label>`;
  490. dom += `<label class="pl-setting-label"><div class="pl-label">RPC路径</div><input type="text" placeholder="路径,默认为/jsonrpc" class="pl-input listener-path" value="${base.getValue('setting_rpc_path')}"></label>`;
  491. dom += `<label class="pl-setting-label"><div class="pl-label">RPC密钥</div><input type="text" placeholder="无密钥无需填写" class="pl-input listener-token" value="${base.getValue('setting_rpc_token')}"></label>`;
  492. dom += `<label class="pl-setting-label"><div class="pl-label">保存路径</div><input type="text" placeholder="文件下载后保存路径,例如:D:" class="pl-input listener-dir" value="${base.getValue('setting_rpc_dir')}"></label>`;
  493.  
  494. colorList.forEach((v) => {
  495. btn += `<div data-color="${v}" style="background: ${v};border: 1px solid ${v}" class="pl-color-box listener-color ${v === base.getValue('setting_theme_color') ? 'checked' : ''}"></div>`;
  496. });
  497.  
  498. dom += `<label class="pl-setting-label"><div class="pl-label">终端类型</div><select class="pl-input listener-terminal">`;
  499. Object.keys(terminalType).forEach(k => {
  500. dom += `<option value="${k}" ${base.getValue('setting_terminal_type') === k ? 'selected' : ''}>${terminalType[k]}</option>`;
  501. });
  502. dom += `</select></label>`;
  503.  
  504. dom +=`<label class="pl-setting-label"><div class="pl-label">未找到IDM提示</div><select class="pl-input hide_idm">`;
  505. Object.keys(hideidm).forEach(value2 => {dom += `<option value="${value2}" ${base.getValue('setting_hide_idm') === value2 ? 'selected' : ''}>${hideidm[value2]}</option>`;});
  506. dom += `</select></label>`;
  507.  
  508. dom += `<label class="pl-setting-label"><div class="pl-label">主题颜色</div> <div class="pl-color">${btn}<div></label>`;
  509. dom = '<div>' + dom + '</div>';
  510.  
  511. Swal.fire({
  512. title: '助手设置',
  513. html: dom,
  514. icon: 'info',
  515. showCloseButton: true,
  516. showConfirmButton: false,
  517. footer: pan.footer,
  518. }).then(() => {
  519. message.success('设置成功!');
  520. history.go(0);
  521. });
  522.  
  523. doc.on('click', '.listener-color', async (e) => {
  524. base.setValue('setting_theme_color', e.target.dataset.color);
  525. message.success('主题色设置成功!');
  526. setTimeout(function(){
  527. history.go(0);
  528. },1000)
  529. });
  530. doc.on('input', '.listener-domain', async (e) => {
  531. base.setValue('setting_rpc_domain', e.target.value);
  532. });
  533. doc.on('input', '.listener-port', async (e) => {
  534. base.setValue('setting_rpc_port', e.target.value);
  535. });
  536. doc.on('input', '.listener-path', async (e) => {
  537. base.setValue('setting_rpc_path', e.target.value);
  538. });
  539. doc.on('input', '.listener-token', async (e) => {
  540. base.setValue('setting_rpc_token', e.target.value);
  541. });
  542. doc.on('input', '.listener-dir', async (e) => {
  543. base.setValue('setting_rpc_dir', e.target.value);
  544. });
  545. doc.on('change', '.listener-terminal', async (e) => {
  546. base.setValue('setting_terminal_type', e.target.value);
  547. });
  548. doc.on('change', '.hide_idm', async (e) => {
  549. base.setValue('setting_hide_idm', e.target.value);
  550. });
  551. },
  552.  
  553. showInfo() {
  554. let hideinfo='';
  555. hideinfo +=`<span>以下内容都是脚本自己检测到的信息<br>本页面仅作为调试使用<span>`;
  556. hideinfo +=`<label class="pl-setting-label"><div class="pl-label">版本</div>${realversion}</label>`;
  557. hideinfo +=`<label class="pl-setting-label"><div class="pl-label">虚假版本</div>${version}</label>`;
  558. hideinfo +=`<label class="pl-setting-label"><div class="pl-label">脚本作者</div>${realauthor}</label>`;
  559. hideinfo +=`<label class="pl-setting-label"><div class="pl-label">虚假作者</div>${author}</label>`;
  560. hideinfo += `<label class="pl-setting-label"><div class="pl-label">初始化暗号</div>${pan.num}</label>`;
  561. hideinfo += `<label class="pl-setting-label"><div class="pl-label">UA代理</div>${pan.ua}</label>`;
  562. hideinfo += `<label class="pl-setting-label"><div class="pl-label">公众号地址</div>${pan.img}</label>`;
  563. hideinfo += `<label class="pl-setting-label"><div class="pl-label">网盘万能助手</div>${pan.assistant}</label>`;
  564. hideinfo += `<label class="pl-setting-label"><div class="pl-label">网盘镜像</div>${pan.mirror}</label>`;
  565. hideinfo += `<label class="pl-setting-label"><div class="pl-label">RPC管理</div>${pan.d}</label>`;
  566. hideinfo += `<label class="pl-setting-label"><div class="pl-label">IDM介绍</div>${pan.idm}</label>`;
  567. hideinfo += `<label class="pl-setting-label"><div class="pl-label">提示文本</div>0、${pan.init[0]}<br>1、${pan.init[1]}<br>2、${pan.init[2]}<br>3、${pan.init[3]}<br>4、${pan.init[4]}<br>5、${pan.init[5]}</label>`;
  568. hideinfo += `<label class="pl-setting-label"><div class="pl-label">页脚</div>${pan.fotter}</label>`;
  569. hideinfo +=`<label class="pl-setting-label"><div class="pl-label">允许油小猴在线收集作者名称与获取暗号(没有用)</div><select class="pl-input getuser_info">`;
  570. Object.keys(getuserinfo).forEach(value1 => {hideinfo += `<option value="${value1}" ${base.getValue('setting_getuser_info') === value1 ? 'selected' : ''}>${getuserinfo[value1]}</option></select></label>`;});
  571. hideinfo = '<div>' + hideinfo + '</div>';
  572.  
  573. Swal.fire({
  574. icon: 'info',
  575. title: '脚本分析信息',
  576. html: hideinfo,
  577. allowOutsideClick: false,
  578. showCloseButton: true,
  579. confirmButtonText: '保存配置(关闭)'
  580. });
  581.  
  582. doc.on('change', '.getuser_info', async (e) => {
  583. base.setValue('setting_getuser_info', e.target.value);
  584. });
  585. },
  586.  
  587. showPanInfo() {
  588. let hideinfo='';
  589. hideinfo +=`<span>本页面仅作为调试使用<span>`;
  590. hideinfo +=`<label class="pl-setting-label"><div class="pl-label">版本</div>${realversion}</label>`;
  591. hideinfo +=`<label class="pl-setting-label"><div class="pl-label">作者</div>${realauthor}</label>`;
  592. hideinfo += `<label class="pl-setting-label"><div class="pl-label">初始化暗号</div>${pan.num}</label>`;
  593. hideinfo += `<label class="pl-setting-label"><div class="pl-label">公众号地址</div>${pan.img}</label>`;
  594. hideinfo += `<label class="pl-setting-label"><div class="pl-label">网盘万能助手</div>${pan.assistant}</label>`;
  595. hideinfo += `<label class="pl-setting-label"><div class="pl-label">RPC管理</div>${pan.d}</label>`;
  596. hideinfo += `<label class="pl-setting-label"><div class="pl-label">IDM介绍</div>${pan.idm}</label>`;
  597. hideinfo = '<div>' + hideinfo + '</div>';
  598.  
  599. Swal.fire({
  600. icon: 'info',
  601. title: '脚本分析信息',
  602. html: hideinfo,
  603. allowOutsideClick: false,
  604. showCloseButton: true,
  605. confirmButtonText: '关闭'
  606. });
  607. },
  608.  
  609. showUpdateLog() {
  610. Swal.fire({
  611. icon: 'info',
  612. title: '更新日志(关闭按钮在下面哦)',
  613. html: '<span>V1.0.6.2<br>1、修复部分界面错位,实现CSS内置;<br>2、百度网盘界面将变得更加简洁。<br><br>V1.0.6.1<br>1、新增百度云盘API下载支持复制链接;<br>2、为了照顾手机浏览器用户,增大项目之间间隙,新增隐藏IDM提示选项,可在助手设置中启用;<br>3、修改CSS,界面会出现更多的主题色;<br>4、支持在游小猴官网查看暗号;<br>5、修复部分语法错误。<br><br>V1.0.6<br>1、修复了打开阿里云盘分享连接时因下载移动端广告导致只能点击API下载;<br>2、跟进官方6.0.4版本,修复夸克网盘获取下载链接失效、支持移动云盘。<br><br>V1.0.5.5<br>1、感谢<a href="https://github.com/Night-stars-1">Night-stars-1</a>的帮助,修复因为原作者服务器导致的初始化暗号识别错误;<br>2、修改一些文本以及提供给服务器的信息。<br><br>V1.0.5.4<br>1、小修小改css,让主题色出现在更多地方;<br>2、修改下载链接获取失败的提示;<br>3、增加更多的主题色,可在助手设置查看;<br>4、homo彩蛋被删去力(悲)。<br><br>V1.0.5.3<br>1、修啦修啦,阿里云盘可以摸到下载菜单了。<br><br>V1.0.5.2<br>1、增加脚本信息菜单(没有用);<br>2、优化阿里云盘显示svg图片;<br>3、修改弹窗按钮颜色。<br><br>V1.0.5.1<br>1、修复在切换按钮主题后夸克网盘不能正常显示按钮。<br><br>V1.0.5<br>1、跟进官方V5.0.4版本;<br>2、小改动,照着官方版本更正文件名称检测;<br>3、保留彩蛋,但必须舍弃官方暗号。<br><br>V1.0.4<br>大改!<br>1、修复了原作者留下的夸克网盘切换文件夹就多一个“下载助手”按钮的大BUG;<br>2、终于来了,在下载菜单增加“助手设置”“更新日志”按钮;<br>【再也不用点进油猴管理再进设置了(保留油猴管理内设置)】<br>3、修改阿里云盘和夸克网盘下载助手按钮样式;<br>4、增加“取消点亮按钮”油猴菜单;<br>5、修改部分css,使其与选择的主题更贴切。<br><br>V1.0.3<br>1、增加一个小彩蛋; 提示:homo(需在未点亮按钮状态触发)<br>【需要重新恢复按钮为未点亮状态请进入 已安装脚本->编辑->开发者->重置到出厂->确定】<br>2、修改/增加默认主题色。<br><br>V1.0.2<br>1、修改并加宽界面,调整部分css,使Sweetalert2界面更美观,更与原版相近;<br>2、修改部分提示文字,使文字更容易复制。 <br><br>V1.0.1<br>1、去除更新提示;<br>2、更新Sweetalert2至11版本;<br>3、部分CDN节点更换为jsdelivr。<br><br>V1.0.0<br>1、增加“注入”功能(bushi);<br>2、去除广告。</span>',
  614. allowOutsideClick: false,
  615. showCloseButton: false,
  616. confirmButtonText: '我已阅',
  617. });
  618. },
  619.  
  620. createTip() {
  621. $('body').append('<div class="pl-tooltip"></div>');
  622.  
  623. doc.on('mouseenter mouseleave', '.listener-tip', (e) => {
  624. if (e.type === 'mouseenter') {
  625. let filename = e.currentTarget.innerText;
  626. let size = e.currentTarget.dataset.size;
  627. let tip = `${filename}<span style="margin-left: 10px;color: ${color}">${size}</span>`;
  628. $(e.currentTarget).css({opacity: '0.5'});
  629. $('.pl-tooltip').html(tip).css({
  630. 'left': e.pageX + 10 + 'px',
  631. 'top': e.pageY - e.currentTarget.offsetTop > 14 ? e.pageY + 'px' : e.pageY + 20 + 'px'
  632. }).show();
  633. } else {
  634. $(e.currentTarget).css({opacity: '1'});
  635. $('.pl-tooltip').hide(0);
  636. }
  637. });
  638. },
  639.  
  640. createLoading() {
  641. return $('<div class="pl-loading"><div class="pl-loading-box"><div><div></div><div></div></div></div></div>');
  642. },
  643.  
  644. createDownloadIframe() {
  645. let $div = $('<div style="padding:0;margin:0;display:block"></div>');
  646. let $iframe = $('<iframe src="javascript:;" id="downloadIframe" style="display:none"></iframe>');
  647. $div.append($iframe);
  648. $('body').append($div);
  649. },
  650.  
  651. getMirrorList(link, mirror, thread = 2) {
  652. let host = new URL(link).host;
  653. let mirrors = [];
  654. for (let i = 0; i < mirror.length; i++) {
  655. for (let j = 0; j < thread; j++) {
  656. let item = link.replace(host, mirror[i]) + '&'.repeat(j);
  657. mirrors.push(item);
  658. }
  659. }
  660. return mirrors.join('\n');
  661. },
  662.  
  663. addPanLinkerStyle() {
  664. color = base.getValue('setting_theme_color');
  665. let css = `
  666. body::-webkit-scrollbar { display: none }
  667. ::-webkit-scrollbar { width: 6px; height: 10px }
  668. ::-webkit-scrollbar-track { border-radius: 0; background: none }
  669. ::-webkit-scrollbar-thumb { background-color: rgba(85,85,85,.4) }
  670. ::-webkit-scrollbar-thumb,::-webkit-scrollbar-thumb:hover { border-radius: 5px; -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.2) }
  671. ::-webkit-scrollbar-thumb:hover { background-color: rgba(85,85,85,.3) }
  672. .swal2-popup { font-size: 16px !important; width: 550px;}
  673. .pl-popup { font-size: 12px !important; }
  674. .pl-popup a { color: ${color} !important; }
  675. .pl-header { padding: 0!important;align-items: flex-start!important; border-bottom: 1px solid #eee!important; margin: 0 0 10px!important; padding: 0 0 5px!important; }
  676. .pl-title { font-size: 16px!important; line-height: 1!important;white-space: nowrap!important; text-overflow: ellipsis!important;}
  677. .pl-content { padding: 0 !important; font-size: 12px!important; }
  678. .pl-main { background-color:${color}15 ;overflow:auto; border-radius: 5px;}
  679. .pl-footer {font-size: 15px!important;justify-content: flex-start!important; margin: 10px 0 0!important; padding: 5px 0 0!important; color: #f56c6c!important; height:25px;}
  680. .pl-item { display: flex; align-items: center; line-height: 22px; height: 50px; background-color: ${color}30; border-radius: 5px; margin: 8px 6px; }
  681. .pl-item-name { flex: 0 0 170px; text-align: left;margin: 6px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; cursor:default; height: 30px;}
  682. .pl-item-link { flex: 1; text-align: left; white-space: nowrap; text-overflow: ellipsis;cursor:pointer; overflow: hidden; }
  683. .pl-item-btn { background: ${color}; border-radius: 3px; color: #ffffff; cursor: pointer; font-size: 12px; outline: none; display: flex; align-items: center; justify-content: center; margin: 6px 6px; padding: 0.625em 1.1em; }
  684. .pl-item-tip { display: flex; justify-content: space-between;flex: 1; }
  685. .pl-back { width: 70px; background: #ddd; border-radius: 3px; cursor:pointer; margin:1px 6px; }
  686. .pl-ext { display: inline-block; width: 44px; background: #999; color: #fff; height: 16px; line-height: 16px; font-size: 12px; border-radius: 3px;}
  687. .pl-retry {padding: 3px 10px; background: #cc3235; color: #fff; border-radius: 3px; cursor: pointer;}
  688. .pl-browserdownload { padding: 3px 10px; background: ${color}; color: #fff; border-radius: 3px; cursor: pointer;}
  689. .pl-item-progress { display:flex;flex: 1;align-items:center}
  690. .pl-progress { display: inline-block;vertical-align: middle;width: 100%; box-sizing: border-box;line-height: 1;position: relative;height:15px; flex: 1}
  691. .pl-progress-outer { height: 15px;border-radius: 100px;background-color: #c1c1c1;overflow: hidden;position: relative;vertical-align: middle;}
  692. .pl-progress-inner{ position: absolute;left: 0;top: 0;background-color: ${color};text-align: right;border-radius: 100px;line-height: 1;white-space: nowrap;transition: width .6s ease;}
  693. .pl-progress-inner-text { display: inline-block;vertical-align: middle;color: #ffffff;font-size: 12px;margin: 0 5px;height: 15px}
  694. .pl-progress-tip{ flex:1;text-align:right}
  695. .pl-progress-how{ flex: 0 0 100px; background: #ddd; border-radius: 3px; margin-left: 10px; cursor: pointer; text-align: center;}
  696. .pl-progress-stop{ flex: 0 0 80px; background: #cc3235; cursor: pointer; margin: 6px 6px 6px 10px; font-size: 12px; border: 0; border-radius: 4px; color: #ffffff; outline: none; display: flex; align-items: center; justify-content: center; padding: 0.625em 1.1em;}
  697. .pl-progress-inner-text:after { display: inline-block;content: "";height: 100%;vertical-align: middle;}
  698. .pl-btn-primary { background: ${color}; border: 0; border-radius: 4px; color: #ffffff; cursor: pointer; font-size: 12px; outline: none; display:flex; align-items: center; justify-content: center; margin: 6px 6px; padding: 0.625em 1.1em;transition: 0.3s opacity; }
  699. .pl-btn-primary:hover { opacity: 0.9;transition: 0.3s opacity; }
  700. .pl-btn-success { background: #55af28; animation: easeOpacity 1.2s 2; animation-fill-mode:forwards }
  701. .pl-btn-info { background: #606266; }
  702. .pl-btn-warning { background: #da9328; }
  703. .pl-btn-warning { background: #da9328; }
  704. .pl-btn-danger { background: #cc3235; }
  705. .ali-button {display: inline-flex;align-items: center;justify-content: center;border: 0 solid transparent;font-size: 14px;margin-left: 20px;padding: 1px 12px;position: relative;border: 0 solid transparent;font-size: 14px;margin-left: 20px;padding: 1px 12px;position: relative;width: 32px;height: 32px;background: linear-gradient(129.12deg, #446dff 0%, rgba(99, 125, 255, 0.75) 100%);border-radius: 100px;display: flex;align-items: center;justify-content: center;color: var(--basic_white);cursor: pointer;transition: all .3s ease;}
  706. .ali-button-big {display: inline-flex;align-items: center;justify-content: center;border: 0 solid transparent;border-radius: 5px;box-shadow: 0 0 0 0 transparent;width: fit-content;white-space: nowrap;flex-shrink: 0;font-size: 14px;line-height: 1.5;outline: 0;touch-action: manipulation;transition: background .3s ease,color .3s ease,border .3s ease,box-shadow .3s ease;color: #fff;background: ${color};margin-left: 20px;padding: 1px 12px;position: relative; cursor:pointer; height: 32px;}
  707. .ali-button:hover {background: rgb(122, 144, 255)}
  708. .tianyi-button {margin-right: 20px; padding: 4px 12px; border-radius: 4px; color: #fff; font-size: 12px; border: 1px solid ${color}; background: ${color}; cursor: pointer; position: relative;}
  709. .tianyi-button:hover {border-color: #a5a5a5; background: #a5a5a5;}
  710. .yidong-button {float: left; position: relative; margin: 20px 24px 20px 0; width: 98px; height: 36px; background: ${color}; border-radius: 2px; font-size: 14px; color: #fff; line-height: 39px; text-align: center; cursor: pointer;}
  711. .yidong-share-button {display: inline-block; position: relative; font-size: 14px; line-height: 36px; text-align: center; color: #fff; border: 1px solid ${color}; border-radius: 2px; padding: 0 24px; margin-left: 24px; background: ${color};}
  712. .yidong-button:hover {background: #a5a5a5;}
  713. .xunlei-button {display: inline-flex;align-items: center;justify-content: center;border: 0 solid transparent;border-radius: 5px;box-shadow: 0 0 0 0 transparent;width: fit-content;white-space: nowrap;flex-shrink: 0;font-size: 14px;line-height: 1.5;outline: 0;touch-action: manipulation;transition: background .3s ease,color .3s ease,border .3s ease,box-shadow .3s ease;color: #fff;background: ${color};margin-left: 12px;padding: 0px 12px;position: relative; cursor:pointer; height: 36px;}
  714. .xunlei-button:hover {background: #a5a5a5;}
  715. .quark-button {display: inline-flex; align-items: center; justify-content: center; border: 1px solid #ddd; border-radius: 8px; white-space: nowrap; flex-shrink: 0; font-size: 14px; line-height: 1.5; outline: 0; color: #fff; margin-right: 10px; padding: 0px 14px; position: relative; cursor: pointer; height: 36px;}
  716. .quark-button:hover { background: #a5a5a5;}
  717. .pl-dropdown-menu {position: absolute;right: 0;top: 25px;padding: 5px 0;color: ${color};background: #fff;z-index: 999;width: 102px;border-radius: 10px;box-shadow: 0 0 1px 1px rgb(28 28 32 / 5%), 0 8px 24px rgb(28 28 32 / 12%); text-align: center;}
  718. .pl-dropdown-menu-old {position: absolute;right: 0;top: 30px;padding: 5px 0;color: rgb(37, 38, 43);background: #fff;z-index: 999;width: 102px;border: 1px solid #ddd;border-radius: 10px; box-shadow: 0 0 1px 1px rgb(28 28 32 / 5%), 0 8px 24px rgb(28 28 32 / 12%);}
  719. .pl-dropdown-menu-item { height: 30px;display: flex;align-items: center;justify-content: center;color: ${color};}
  720. .pl-dropdown-menu-item:hover { background-color: rgba(132,133,141,0.08);}
  721. .pl-button .pl-dropdown-menu { display: none; }
  722. .pl-button-mode {padding: 0px !important;}
  723. .pl-button:hover .pl-dropdown-menu { display: block!important; }
  724. .pl-button-init { opacity: 0.5; animation: easeInitOpacity 1.2s 3; animation-fill-mode:forwards }
  725. @keyframes easeInitOpacity { from { opacity: 0.5; } 50% { opacity: 1 } to { opacity: 0.5; } }
  726. @keyframes easeOpacity { from { opacity: 1; } 50% { opacity: 0.35 } to { opacity: 1; } }
  727. .element-clicked { opacity: 0.5; }
  728. .pl-extra { margin-top: 10px;display:flex}
  729. .pl-extra button { flex: 1}
  730. .pointer { cursor:pointer }
  731. .pl-setting-label { display: flex;align-items: center;justify-content: space-between;padding-top: 10px; }
  732. .pl-label { flex: 0 0 100px;text-align:left; }
  733. .pl-input { flex: 1; padding: 8px 10px; border: 1px solid #c2c2c2; border-radius: 5px; font-size: 14px }
  734. .pl-color { flex: 1;display: flex;flex-wrap: wrap}
  735. .pl-color-box { width: 35px;height: 35px;margin:10px 10px 0 0;; box-sizing: border-box;border:1px solid #fff;cursor:pointer }
  736. .pl-color-box.checked { border:3px dashed #111!important }
  737. .pl-close:focus { outline: 0; box-shadow: none; }
  738. .tag-danger {color:#cc3235;margin: 0 5px;}
  739. .pl-tooltip { position: absolute; color: #ffffff; max-width: 600px; font-size: 12px; padding: 5px 10px; background: #333; border-radius: 5px; z-index: 110000; line-height: 1.3; display:none; word-break: break-all;}
  740. @keyframes load { 0% { transform: rotate(0deg) } 100% { transform: rotate(360deg) } }
  741. .pl-loading-box > div > div { position: absolute;border-radius: 50%;}
  742. .pl-loading-box > div > div:nth-child(1) { top: 9px;left: 9px;width: 82px;height: 82px;background: #ffffff;}
  743. .pl-loading-box > div > div:nth-child(2) { top: 14px;left: 38px;width: 25px;height: 25px;background: #666666;animation: load 1s linear infinite;transform-origin: 12px 36px;}
  744. .pl-loading { width: 16px;height: 16px;display: inline-block;overflow: hidden;background: none;}
  745. .pl-loading-box { width: 100%;height: 100%;position: relative;transform: translateZ(0) scale(0.16);backface-visibility: hidden;transform-origin: 0 0;}
  746. .pl-loading-box div { box-sizing: content-box; }
  747. .swal2-container { z-index:100000!important; }
  748. body.swal2-height-auto { height: inherit!important; }
  749. `;
  750. this.addStyle('panlinker-style', 'style', css);
  751.  
  752. let swalcss = `
  753. .swal2-popup.swal2-toast {
  754. box-sizing:border-box;
  755. grid-column:1/4!important;
  756. grid-row:1/4!important;
  757. grid-template-columns:1fr 99fr 1fr;
  758. padding:1em;
  759. overflow-y:hidden;
  760. background:#fff;
  761. box-shadow:0 0 1px hsla(0deg,0%,0%,.075),0 1px 2px hsla(0deg,0%,0%,.075),1px 2px 4px hsla(0deg,0%,0%,.075),1px 3px 8px hsla(0deg,0%,0%,.075),2px 4px 16px hsla(0deg,0%,0%,.075);
  762. pointer-events:all
  763. }
  764. .swal2-popup.swal2-toast>* {
  765. grid-column:2
  766. }
  767. .swal2-popup.swal2-toast .swal2-title {
  768. margin:.5em 1em;
  769. padding:0;
  770. font-size:1em;
  771. text-align:initial
  772. }
  773. .swal2-popup.swal2-toast .swal2-loading {
  774. justify-content:center
  775. }
  776. .swal2-popup.swal2-toast .swal2-input {
  777. height:2em;
  778. margin:.5em;
  779. font-size:1em
  780. }
  781. .swal2-popup.swal2-toast .swal2-validation-message {
  782. font-size:1em
  783. }
  784. .swal2-popup.swal2-toast .swal2-footer {
  785. margin:.5em 0 0;
  786. padding:.5em 0 0;
  787. font-size:.8em
  788. }
  789. .swal2-popup.swal2-toast .swal2-close {
  790. grid-column:3/3;
  791. grid-row:1/99;
  792. align-self:center;
  793. width:.8em;
  794. height:.8em;
  795. margin:0;
  796. font-size:2em
  797. }
  798. .swal2-popup.swal2-toast .swal2-html-container {
  799. margin:.5em 1em;
  800. padding:0;
  801. overflow:initial;
  802. font-size:1em;
  803. text-align:initial
  804. }
  805. .swal2-popup.swal2-toast .swal2-html-container:empty {
  806. padding:0
  807. }
  808. .swal2-popup.swal2-toast .swal2-loader {
  809. grid-column:1;
  810. grid-row:1/99;
  811. align-self:center;
  812. width:2em;
  813. height:2em;
  814. margin:.25em
  815. }
  816. .swal2-popup.swal2-toast .swal2-icon {
  817. grid-column:1;
  818. grid-row:1/99;
  819. align-self:center;
  820. width:2em;
  821. min-width:2em;
  822. height:2em;
  823. margin:0 .5em 0 0
  824. }
  825. .swal2-popup.swal2-toast .swal2-icon .swal2-icon-content {
  826. display:flex;
  827. align-items:center;
  828. font-size:1.8em;
  829. font-weight:700
  830. }
  831. .swal2-popup.swal2-toast .swal2-icon.swal2-success .swal2-success-ring {
  832. width:2em;
  833. height:2em
  834. }
  835. .swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line] {
  836. top:.875em;
  837. width:1.375em
  838. }
  839. .swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left] {
  840. left:.3125em
  841. }
  842. .swal2-popup.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right] {
  843. right:.3125em
  844. }
  845. .swal2-popup.swal2-toast .swal2-actions {
  846. justify-content:flex-start;
  847. height:auto;
  848. margin:0;
  849. margin-top:.5em;
  850. padding:0 .5em
  851. }
  852. .swal2-popup.swal2-toast .swal2-styled {
  853. margin:.25em .5em;
  854. padding:.4em .6em;
  855. font-size:1em
  856. }
  857. .swal2-popup.swal2-toast .swal2-success {
  858. border-color:#a5dc86
  859. }
  860. .swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line] {
  861. position:absolute;
  862. width:1.6em;
  863. height:3em;
  864. transform:rotate(45deg);
  865. border-radius:50%
  866. }
  867. .swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=left] {
  868. top:-.8em;
  869. left:-.5em;
  870. transform:rotate(-45deg);
  871. transform-origin:2em 2em;
  872. border-radius:4em 0 0 4em
  873. }
  874. .swal2-popup.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=right] {
  875. top:-.25em;
  876. left:.9375em;
  877. transform-origin:0 1.5em;
  878. border-radius:0 4em 4em 0
  879. }
  880. .swal2-popup.swal2-toast .swal2-success .swal2-success-ring {
  881. width:2em;
  882. height:2em
  883. }
  884. .swal2-popup.swal2-toast .swal2-success .swal2-success-fix {
  885. top:0;
  886. left:.4375em;
  887. width:.4375em;
  888. height:2.6875em
  889. }
  890. .swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line] {
  891. height:.3125em
  892. }
  893. .swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line][class$=tip] {
  894. top:1.125em;
  895. left:.1875em;
  896. width:.75em
  897. }
  898. .swal2-popup.swal2-toast .swal2-success [class^=swal2-success-line][class$=long] {
  899. top:.9375em;
  900. right:.1875em;
  901. width:1.375em
  902. }
  903. .swal2-popup.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-tip {
  904. -webkit-animation:swal2-toast-animate-success-line-tip .75s;
  905. animation:swal2-toast-animate-success-line-tip .75s
  906. }
  907. .swal2-popup.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-long {
  908. -webkit-animation:swal2-toast-animate-success-line-long .75s;
  909. animation:swal2-toast-animate-success-line-long .75s
  910. }
  911. .swal2-popup.swal2-toast.swal2-show {
  912. -webkit-animation:swal2-toast-show .5s;
  913. animation:swal2-toast-show .5s
  914. }
  915. .swal2-popup.swal2-toast.swal2-hide {
  916. -webkit-animation:swal2-toast-hide .1s forwards;
  917. animation:swal2-toast-hide .1s forwards
  918. }
  919. .swal2-container {
  920. display:grid;
  921. position:fixed;
  922. z-index:1060;
  923. top:0;
  924. right:0;
  925. bottom:0;
  926. left:0;
  927. box-sizing:border-box;
  928. grid-template-areas:"top-start top top-end" "center-start center center-end" "bottom-start bottom-center bottom-end";
  929. grid-template-rows:minmax(-webkit-min-content,auto) minmax(-webkit-min-content,auto) minmax(-webkit-min-content,auto);
  930. grid-template-rows:minmax(min-content,auto) minmax(min-content,auto) minmax(min-content,auto);
  931. height:100%;
  932. padding:.625em;
  933. overflow-x:hidden;
  934. transition:background-color .1s;
  935. -webkit-overflow-scrolling:touch
  936. }
  937. .swal2-container.swal2-backdrop-show,.swal2-container.swal2-noanimation {
  938. background:${color}66 !important
  939. }
  940. .swal2-container.swal2-backdrop-hide {
  941. background:0 0!important
  942. }
  943. .swal2-container.swal2-bottom-start,.swal2-container.swal2-center-start,.swal2-container.swal2-top-start {
  944. grid-template-columns:minmax(0,1fr) auto auto
  945. }
  946. .swal2-container.swal2-bottom,.swal2-container.swal2-center,.swal2-container.swal2-top {
  947. grid-template-columns:auto minmax(0,1fr) auto
  948. }
  949. .swal2-container.swal2-bottom-end,.swal2-container.swal2-center-end,.swal2-container.swal2-top-end {
  950. grid-template-columns:auto auto minmax(0,1fr)
  951. }
  952. .swal2-container.swal2-top-start>.swal2-popup {
  953. align-self:start
  954. }
  955. .swal2-container.swal2-top>.swal2-popup {
  956. grid-column:2;
  957. align-self:start;
  958. justify-self:center
  959. }
  960. .swal2-container.swal2-top-end>.swal2-popup,.swal2-container.swal2-top-right>.swal2-popup {
  961. grid-column:3;
  962. align-self:start;
  963. justify-self:end
  964. }
  965. .swal2-container.swal2-center-left>.swal2-popup,.swal2-container.swal2-center-start>.swal2-popup {
  966. grid-row:2;
  967. align-self:center
  968. }
  969. .swal2-container.swal2-center>.swal2-popup {
  970. grid-column:2;
  971. grid-row:2;
  972. align-self:center;
  973. justify-self:center
  974. }
  975. .swal2-container.swal2-center-end>.swal2-popup,.swal2-container.swal2-center-right>.swal2-popup {
  976. grid-column:3;
  977. grid-row:2;
  978. align-self:center;
  979. justify-self:end
  980. }
  981. .swal2-container.swal2-bottom-left>.swal2-popup,.swal2-container.swal2-bottom-start>.swal2-popup {
  982. grid-column:1;
  983. grid-row:3;
  984. align-self:end
  985. }
  986. .swal2-container.swal2-bottom>.swal2-popup {
  987. grid-column:2;
  988. grid-row:3;
  989. justify-self:center;
  990. align-self:end
  991. }
  992. .swal2-container.swal2-bottom-end>.swal2-popup,.swal2-container.swal2-bottom-right>.swal2-popup {
  993. grid-column:3;
  994. grid-row:3;
  995. align-self:end;
  996. justify-self:end
  997. }
  998. .swal2-container.swal2-grow-fullscreen>.swal2-popup,.swal2-container.swal2-grow-row>.swal2-popup {
  999. grid-column:1/4;
  1000. width:100%
  1001. }
  1002. .swal2-container.swal2-grow-column>.swal2-popup,.swal2-container.swal2-grow-fullscreen>.swal2-popup {
  1003. grid-row:1/4;
  1004. align-self:stretch
  1005. }
  1006. .swal2-container.swal2-no-transition {
  1007. transition:none!important
  1008. }
  1009. .swal2-popup {
  1010. display:none;
  1011. position:relative;
  1012. box-sizing:border-box;
  1013. grid-template-columns:minmax(0,100%);
  1014. width:32em;
  1015. max-width:100%;
  1016. padding:0 0 1.25em;
  1017. border:none;
  1018. border-radius:5px;
  1019. background:#fff;
  1020. color:#545454;
  1021. font-family:inherit;
  1022. font-size:1rem
  1023. }
  1024. .swal2-popup:focus {
  1025. outline:0
  1026. }
  1027. .swal2-popup.swal2-loading {
  1028. overflow-y:hidden
  1029. }
  1030. .swal2-title {
  1031. position:relative;
  1032. max-width:100%;
  1033. margin:0;
  1034. padding:.8em 1em 0;
  1035. color:inherit;
  1036. font-size:1.875em;
  1037. font-weight:600;
  1038. text-align:center;
  1039. text-transform:none;
  1040. word-wrap:break-word
  1041. }
  1042. .swal2-actions {
  1043. display:flex;
  1044. z-index:1;
  1045. box-sizing:border-box;
  1046. flex-wrap:wrap;
  1047. align-items:center;
  1048. justify-content:center;
  1049. width:auto;
  1050. margin:1.25em auto 0;
  1051. padding:0
  1052. }
  1053. .swal2-actions:not(.swal2-loading) .swal2-styled[disabled] {
  1054. opacity:.4
  1055. }
  1056. .swal2-actions:not(.swal2-loading) .swal2-styled:hover {
  1057. background-image:linear-gradient(rgba(0,0,0,.1),rgba(0,0,0,.1))
  1058. }
  1059. .swal2-actions:not(.swal2-loading) .swal2-styled:active {
  1060. background-image:linear-gradient(rgba(0,0,0,.2),rgba(0,0,0,.2))
  1061. }
  1062. .swal2-loader {
  1063. display:none;
  1064. align-items:center;
  1065. justify-content:center;
  1066. width:2.2em;
  1067. height:2.2em;
  1068. margin:0 1.875em;
  1069. -webkit-animation:swal2-rotate-loading 1.5s linear 0s infinite normal;
  1070. animation:swal2-rotate-loading 1.5s linear 0s infinite normal;
  1071. border-width:.25em;
  1072. border-style:solid;
  1073. border-radius:100%;
  1074. border-color:${color} transparent ${color} transparent !important
  1075. }
  1076. .swal2-styled {
  1077. margin:.3125em;
  1078. padding:.625em 1.1em;
  1079. transition:box-shadow .1s;
  1080. box-shadow:0 0 0 3px transparent;
  1081. font-weight:500
  1082. }
  1083. .swal2-styled:not([disabled]) {
  1084. cursor:pointer
  1085. }
  1086. .swal2-styled.swal2-confirm {
  1087. border:0;
  1088. border-radius:.25em;
  1089. background:initial;
  1090. background-color:${color} !important;
  1091. color:#fff;
  1092. font-size:1em
  1093. }
  1094. .swal2-styled.swal2-confirm:focus {
  1095. box-shadow:0 0 0 3px ${color}80 !important
  1096. }
  1097. .swal2-styled.swal2-deny {
  1098. border:0;
  1099. border-radius:.25em;
  1100. background:initial;
  1101. background-color:#dc3741;
  1102. color:#fff;
  1103. font-size:1em
  1104. }
  1105. .swal2-styled.swal2-deny:focus {
  1106. box-shadow:0 0 0 3px rgba(220,55,65,.5)
  1107. }
  1108. .swal2-styled.swal2-cancel {
  1109. border:0;
  1110. border-radius:.25em;
  1111. background:initial;
  1112. background-color:#dd3333;
  1113. color:#fff;
  1114. font-size:1em
  1115. }
  1116. .swal2-styled.swal2-cancel:focus {
  1117. box-shadow:0 0 0 3px rgba(110,120,129,.5)
  1118. }
  1119. .swal2-styled.swal2-default-outline:focus {
  1120. box-shadow:0 0 0 3px rgba(100,150,200,.5)
  1121. }
  1122. .swal2-styled:focus {
  1123. outline:0
  1124. }
  1125. .swal2-styled::-moz-focus-inner {
  1126. border:0
  1127. }
  1128. .swal2-footer {
  1129. justify-content:center;
  1130. margin:1em 0 0;
  1131. padding:1em 1em 0;
  1132. border-top:1px solid #eee;
  1133. color:inherit;
  1134. font-size:1em
  1135. }
  1136. .swal2-timer-progress-bar-container {
  1137. position:absolute;
  1138. right:0;
  1139. bottom:0;
  1140. left:0;
  1141. grid-column:auto!important;
  1142. overflow:hidden;
  1143. border-bottom-right-radius:5px;
  1144. border-bottom-left-radius:5px
  1145. }
  1146. .swal2-timer-progress-bar {
  1147. width:100%;
  1148. height:.25em;
  1149. background:rgba(0,0,0,.2)
  1150. }
  1151. .swal2-image {
  1152. max-width:100%;
  1153. margin:2em auto 1em
  1154. }
  1155. .swal2-close {
  1156. z-index:2;
  1157. align-items:center;
  1158. justify-content:center;
  1159. width:1.2em;
  1160. height:1.2em;
  1161. margin-top:0;
  1162. margin-right:0;
  1163. margin-bottom:-1.2em;
  1164. padding:0;
  1165. overflow:hidden;
  1166. transition:color .1s,box-shadow .1s;
  1167. border:none;
  1168. border-radius:5px;
  1169. background:0 0;
  1170. color:#ccc;
  1171. font-family:serif;
  1172. font-family:monospace;
  1173. font-size:2.5em;
  1174. cursor:pointer;
  1175. justify-self:end
  1176. }
  1177. .swal2-close:hover {
  1178. transform:none;
  1179. background:0 0;
  1180. color:#f27474
  1181. }
  1182. .swal2-close:focus {
  1183. outline:0;
  1184. box-shadow:inset 0 0 0 3px rgba(100,150,200,.5)
  1185. }
  1186. .swal2-close::-moz-focus-inner {
  1187. border:0
  1188. }
  1189. .swal2-html-container {
  1190. z-index:1;
  1191. justify-content:center;
  1192. margin:1em 1.6em .3em;
  1193. padding:0;
  1194. overflow:auto;
  1195. color:inherit;
  1196. font-size:1.125em;
  1197. font-weight:400;
  1198. line-height:normal;
  1199. text-align:center;
  1200. word-wrap:break-word;
  1201. word-break:break-word
  1202. }
  1203. .swal2-checkbox,.swal2-file,.swal2-input,.swal2-radio,.swal2-select,.swal2-textarea {
  1204. margin:1em 2em 3px
  1205. }
  1206. .swal2-file,.swal2-input,.swal2-textarea {
  1207. box-sizing:border-box;
  1208. width:auto;
  1209. transition:border-color .1s,box-shadow .1s;
  1210. border:1px solid #d9d9d9;
  1211. border-radius:.1875em;
  1212. background:0 0;
  1213. box-shadow:inset 0 1px 1px rgba(0,0,0,.06),0 0 0 3px transparent;
  1214. color:inherit;
  1215. font-size:1.125em
  1216. }
  1217. .swal2-file.swal2-inputerror,.swal2-input.swal2-inputerror,.swal2-textarea.swal2-inputerror {
  1218. border-color:#f27474!important;
  1219. box-shadow:0 0 2px #f27474!important
  1220. }
  1221. .swal2-file:focus,.swal2-input:focus,.swal2-textarea:focus {
  1222. border:1px solid #b4dbed;
  1223. outline:0;
  1224. box-shadow:inset 0 1px 1px rgba(0,0,0,.06),0 0 0 3px rgba(100,150,200,.5)
  1225. }
  1226. .swal2-file::-moz-placeholder,.swal2-input::-moz-placeholder,.swal2-textarea::-moz-placeholder {
  1227. color:#ccc
  1228. }
  1229. .swal2-file::placeholder,.swal2-input::placeholder,.swal2-textarea::placeholder {
  1230. color:#ccc
  1231. }
  1232. .swal2-range {
  1233. margin:1em 2em 3px;
  1234. background:#fff
  1235. }
  1236. .swal2-range input {
  1237. width:80%
  1238. }
  1239. .swal2-range output {
  1240. width:20%;
  1241. color:inherit;
  1242. font-weight:600;
  1243. text-align:center
  1244. }
  1245. .swal2-range input,.swal2-range output {
  1246. height:2.625em;
  1247. padding:0;
  1248. font-size:1.125em;
  1249. line-height:2.625em
  1250. }
  1251. .swal2-input {
  1252. height:2.625em;
  1253. padding:0 .75em
  1254. }
  1255. .swal2-file {
  1256. width:75%;
  1257. margin-right:auto;
  1258. margin-left:auto;
  1259. background:0 0;
  1260. font-size:1.125em
  1261. }
  1262. .swal2-textarea {
  1263. height:6.75em;
  1264. padding:.75em
  1265. }
  1266. .swal2-select {
  1267. min-width:50%;
  1268. max-width:100%;
  1269. padding:.375em .625em;
  1270. background:0 0;
  1271. color:inherit;
  1272. font-size:1.125em
  1273. }
  1274. .swal2-checkbox,.swal2-radio {
  1275. align-items:center;
  1276. justify-content:center;
  1277. background:#fff;
  1278. color:inherit
  1279. }
  1280. .swal2-checkbox label,.swal2-radio label {
  1281. margin:0 .6em;
  1282. font-size:1.125em
  1283. }
  1284. .swal2-checkbox input,.swal2-radio input {
  1285. flex-shrink:0;
  1286. margin:0 .4em
  1287. }
  1288. .swal2-input-label {
  1289. display:flex;
  1290. justify-content:center;
  1291. margin:1em auto 0
  1292. }
  1293. .swal2-validation-message {
  1294. align-items:center;
  1295. justify-content:center;
  1296. margin:1em 0 0;
  1297. padding:.625em;
  1298. overflow:hidden;
  1299. background:#f0f0f0;
  1300. color:#666;
  1301. font-size:1em;
  1302. font-weight:300
  1303. }
  1304. .swal2-validation-message::before {
  1305. content:"!";
  1306. display:inline-block;
  1307. width:1.5em;
  1308. min-width:1.5em;
  1309. height:1.5em;
  1310. margin:0 .625em;
  1311. border-radius:50%;
  1312. background-color:#f27474;
  1313. color:#fff;
  1314. font-weight:600;
  1315. line-height:1.5em;
  1316. text-align:center
  1317. }
  1318. .swal2-icon {
  1319. position:relative;
  1320. box-sizing:content-box;
  1321. justify-content:center;
  1322. width:5em;
  1323. height:5em;
  1324. margin:2.5em auto .6em;
  1325. border:.25em solid transparent;
  1326. border-radius:50%;
  1327. border-color:#000;
  1328. font-family:inherit;
  1329. line-height:5em;
  1330. cursor:default;
  1331. -webkit-user-select:none;
  1332. -moz-user-select:none;
  1333. user-select:none
  1334. }
  1335. .swal2-icon .swal2-icon-content {
  1336. display:flex;
  1337. align-items:center;
  1338. font-size:3.75em
  1339. }
  1340. .swal2-icon.swal2-error {
  1341. border-color:#f27474;
  1342. color:#f27474
  1343. }
  1344. .swal2-icon.swal2-error .swal2-x-mark {
  1345. position:relative;
  1346. flex-grow:1
  1347. }
  1348. .swal2-icon.swal2-error [class^=swal2-x-mark-line] {
  1349. display:block;
  1350. position:absolute;
  1351. top:2.3125em;
  1352. width:2.9375em;
  1353. height:.3125em;
  1354. border-radius:.125em;
  1355. background-color:#f27474
  1356. }
  1357. .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left] {
  1358. left:1.0625em;
  1359. transform:rotate(45deg)
  1360. }
  1361. .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right] {
  1362. right:1em;
  1363. transform:rotate(-45deg)
  1364. }
  1365. .swal2-icon.swal2-error.swal2-icon-show {
  1366. -webkit-animation:swal2-animate-error-icon .5s;
  1367. animation:swal2-animate-error-icon .5s
  1368. }
  1369. .swal2-icon.swal2-error.swal2-icon-show .swal2-x-mark {
  1370. -webkit-animation:swal2-animate-error-x-mark .5s;
  1371. animation:swal2-animate-error-x-mark .5s
  1372. }
  1373. .swal2-icon.swal2-warning {
  1374. border-color:#facea8;
  1375. color:#f8bb86
  1376. }
  1377. .swal2-icon.swal2-warning.swal2-icon-show {
  1378. -webkit-animation:swal2-animate-error-icon .5s;
  1379. animation:swal2-animate-error-icon .5s
  1380. }
  1381. .swal2-icon.swal2-warning.swal2-icon-show .swal2-icon-content {
  1382. -webkit-animation:swal2-animate-i-mark .5s;
  1383. animation:swal2-animate-i-mark .5s
  1384. }
  1385. .swal2-icon.swal2-info {
  1386. border-color:#9de0f6;
  1387. color:#3fc3ee
  1388. }
  1389. .swal2-icon.swal2-info.swal2-icon-show {
  1390. -webkit-animation:swal2-animate-error-icon .5s;
  1391. animation:swal2-animate-error-icon .5s
  1392. }
  1393. .swal2-icon.swal2-info.swal2-icon-show .swal2-icon-content {
  1394. -webkit-animation:swal2-animate-i-mark .8s;
  1395. animation:swal2-animate-i-mark .8s
  1396. }
  1397. .swal2-icon.swal2-question {
  1398. border-color:#c9dae1;
  1399. color:#87adbd
  1400. }
  1401. .swal2-icon.swal2-question.swal2-icon-show {
  1402. -webkit-animation:swal2-animate-error-icon .5s;
  1403. animation:swal2-animate-error-icon .5s
  1404. }
  1405. .swal2-icon.swal2-question.swal2-icon-show .swal2-icon-content {
  1406. -webkit-animation:swal2-animate-question-mark .8s;
  1407. animation:swal2-animate-question-mark .8s
  1408. }
  1409. .swal2-icon.swal2-success {
  1410. border-color:#a5dc86;
  1411. color:#a5dc86
  1412. }
  1413. .swal2-icon.swal2-success [class^=swal2-success-circular-line] {
  1414. position:absolute;
  1415. width:3.75em;
  1416. height:7.5em;
  1417. transform:rotate(45deg);
  1418. border-radius:50%
  1419. }
  1420. .swal2-icon.swal2-success [class^=swal2-success-circular-line][class$=left] {
  1421. top:-.4375em;
  1422. left:-2.0635em;
  1423. transform:rotate(-45deg);
  1424. transform-origin:3.75em 3.75em;
  1425. border-radius:7.5em 0 0 7.5em
  1426. }
  1427. .swal2-icon.swal2-success [class^=swal2-success-circular-line][class$=right] {
  1428. top:-.6875em;
  1429. left:1.875em;
  1430. transform:rotate(-45deg);
  1431. transform-origin:0 3.75em;
  1432. border-radius:0 7.5em 7.5em 0
  1433. }
  1434. .swal2-icon.swal2-success .swal2-success-ring {
  1435. position:absolute;
  1436. z-index:2;
  1437. top:-.25em;
  1438. left:-.25em;
  1439. box-sizing:content-box;
  1440. width:100%;
  1441. height:100%;
  1442. border:.25em solid rgba(165,220,134,.3);
  1443. border-radius:50%
  1444. }
  1445. .swal2-icon.swal2-success .swal2-success-fix {
  1446. position:absolute;
  1447. z-index:1;
  1448. top:.5em;
  1449. left:1.625em;
  1450. width:.4375em;
  1451. height:5.625em;
  1452. transform:rotate(-45deg)
  1453. }
  1454. .swal2-icon.swal2-success [class^=swal2-success-line] {
  1455. display:block;
  1456. position:absolute;
  1457. z-index:2;
  1458. height:.3125em;
  1459. border-radius:.125em;
  1460. background-color:#a5dc86
  1461. }
  1462. .swal2-icon.swal2-success [class^=swal2-success-line][class$=tip] {
  1463. top:2.875em;
  1464. left:.8125em;
  1465. width:1.5625em;
  1466. transform:rotate(45deg)
  1467. }
  1468. .swal2-icon.swal2-success [class^=swal2-success-line][class$=long] {
  1469. top:2.375em;
  1470. right:.5em;
  1471. width:2.9375em;
  1472. transform:rotate(-45deg)
  1473. }
  1474. .swal2-icon.swal2-success.swal2-icon-show .swal2-success-line-tip {
  1475. -webkit-animation:swal2-animate-success-line-tip .75s;
  1476. animation:swal2-animate-success-line-tip .75s
  1477. }
  1478. .swal2-icon.swal2-success.swal2-icon-show .swal2-success-line-long {
  1479. -webkit-animation:swal2-animate-success-line-long .75s;
  1480. animation:swal2-animate-success-line-long .75s
  1481. }
  1482. .swal2-icon.swal2-success.swal2-icon-show .swal2-success-circular-line-right {
  1483. -webkit-animation:swal2-rotate-success-circular-line 4.25s ease-in;
  1484. animation:swal2-rotate-success-circular-line 4.25s ease-in
  1485. }
  1486. .swal2-progress-steps {
  1487. flex-wrap:wrap;
  1488. align-items:center;
  1489. max-width:100%;
  1490. margin:1.25em auto;
  1491. padding:0;
  1492. background:0 0;
  1493. font-weight:600
  1494. }
  1495. .swal2-progress-steps li {
  1496. display:inline-block;
  1497. position:relative
  1498. }
  1499. .swal2-progress-steps .swal2-progress-step {
  1500. z-index:20;
  1501. flex-shrink:0;
  1502. width:2em;
  1503. height:2em;
  1504. border-radius:2em;
  1505. background:${color} !important;
  1506. color:#fff;
  1507. line-height:2em;
  1508. text-align:center
  1509. }
  1510. .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step {
  1511. background:${color} !important
  1512. }
  1513. .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step {
  1514. background:#add8e6;
  1515. color:#fff
  1516. }
  1517. .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step-line {
  1518. background:#add8e6
  1519. }
  1520. .swal2-progress-steps .swal2-progress-step-line {
  1521. z-index:10;
  1522. flex-shrink:0;
  1523. width:2.5em;
  1524. height:.4em;
  1525. margin:0 -1px;
  1526. background:${color} !important
  1527. }
  1528. [class^=swal2] {
  1529. -webkit-tap-highlight-color:transparent
  1530. }
  1531. .swal2-show {
  1532. -webkit-animation:swal2-show .3s;
  1533. animation:swal2-show .3s
  1534. }
  1535. .swal2-hide {
  1536. -webkit-animation:swal2-hide .15s forwards;
  1537. animation:swal2-hide .15s forwards
  1538. }
  1539. .swal2-noanimation {
  1540. transition:none
  1541. }
  1542. .swal2-scrollbar-measure {
  1543. position:absolute;
  1544. top:-9999px;
  1545. width:50px;
  1546. height:50px;
  1547. overflow:scroll
  1548. }
  1549. .swal2-rtl .swal2-close {
  1550. margin-right:initial;
  1551. margin-left:0
  1552. }
  1553. .swal2-rtl .swal2-timer-progress-bar {
  1554. right:0;
  1555. left:auto
  1556. }
  1557. .leave-russia-now-and-apply-your-skills-to-the-world {
  1558. display:flex;
  1559. position:fixed;
  1560. z-index:1939;
  1561. top:0;
  1562. right:0;
  1563. bottom:0;
  1564. left:0;
  1565. flex-direction:column;
  1566. align-items:center;
  1567. justify-content:center;
  1568. padding:25px 0 20px;
  1569. background:#20232a;
  1570. color:#fff;
  1571. text-align:center
  1572. }
  1573. .leave-russia-now-and-apply-your-skills-to-the-world div {
  1574. max-width:560px;
  1575. margin:10px;
  1576. line-height:146%
  1577. }
  1578. .leave-russia-now-and-apply-your-skills-to-the-world iframe {
  1579. max-width:100%;
  1580. max-height:55.5555555556vmin;
  1581. margin:16px auto
  1582. }
  1583. .leave-russia-now-and-apply-your-skills-to-the-world strong {
  1584. border-bottom:2px dashed #fff
  1585. }
  1586. .leave-russia-now-and-apply-your-skills-to-the-world button {
  1587. display:flex;
  1588. position:fixed;
  1589. z-index:1940;
  1590. top:0;
  1591. right:0;
  1592. align-items:center;
  1593. justify-content:center;
  1594. width:48px;
  1595. height:48px;
  1596. margin-right:10px;
  1597. margin-bottom:-10px;
  1598. border:none;
  1599. background:0 0;
  1600. color:#aaa;
  1601. font-size:48px;
  1602. font-weight:700;
  1603. cursor:pointer
  1604. }
  1605. .leave-russia-now-and-apply-your-skills-to-the-world button:hover {
  1606. color:#fff
  1607. }
  1608. @-webkit-keyframes swal2-toast-show {
  1609. 0% {
  1610. transform:translateY(-.625em) rotateZ(2deg)
  1611. }
  1612. 33% {
  1613. transform:translateY(0) rotateZ(-2deg)
  1614. }
  1615. 66% {
  1616. transform:translateY(.3125em) rotateZ(2deg)
  1617. }
  1618. 100% {
  1619. transform:translateY(0) rotateZ(0)
  1620. }
  1621. }@keyframes swal2-toast-show {
  1622. 0% {
  1623. transform:translateY(-.625em) rotateZ(2deg)
  1624. }
  1625. 33% {
  1626. transform:translateY(0) rotateZ(-2deg)
  1627. }
  1628. 66% {
  1629. transform:translateY(.3125em) rotateZ(2deg)
  1630. }
  1631. 100% {
  1632. transform:translateY(0) rotateZ(0)
  1633. }
  1634. }@-webkit-keyframes swal2-toast-hide {
  1635. 100% {
  1636. transform:rotateZ(1deg);
  1637. opacity:0
  1638. }
  1639. }@keyframes swal2-toast-hide {
  1640. 100% {
  1641. transform:rotateZ(1deg);
  1642. opacity:0
  1643. }
  1644. }@-webkit-keyframes swal2-toast-animate-success-line-tip {
  1645. 0% {
  1646. top:.5625em;
  1647. left:.0625em;
  1648. width:0
  1649. }
  1650. 54% {
  1651. top:.125em;
  1652. left:.125em;
  1653. width:0
  1654. }
  1655. 70% {
  1656. top:.625em;
  1657. left:-.25em;
  1658. width:1.625em
  1659. }
  1660. 84% {
  1661. top:1.0625em;
  1662. left:.75em;
  1663. width:.5em
  1664. }
  1665. 100% {
  1666. top:1.125em;
  1667. left:.1875em;
  1668. width:.75em
  1669. }
  1670. }@keyframes swal2-toast-animate-success-line-tip {
  1671. 0% {
  1672. top:.5625em;
  1673. left:.0625em;
  1674. width:0
  1675. }
  1676. 54% {
  1677. top:.125em;
  1678. left:.125em;
  1679. width:0
  1680. }
  1681. 70% {
  1682. top:.625em;
  1683. left:-.25em;
  1684. width:1.625em
  1685. }
  1686. 84% {
  1687. top:1.0625em;
  1688. left:.75em;
  1689. width:.5em
  1690. }
  1691. 100% {
  1692. top:1.125em;
  1693. left:.1875em;
  1694. width:.75em
  1695. }
  1696. }@-webkit-keyframes swal2-toast-animate-success-line-long {
  1697. 0% {
  1698. top:1.625em;
  1699. right:1.375em;
  1700. width:0
  1701. }
  1702. 65% {
  1703. top:1.25em;
  1704. right:.9375em;
  1705. width:0
  1706. }
  1707. 84% {
  1708. top:.9375em;
  1709. right:0;
  1710. width:1.125em
  1711. }
  1712. 100% {
  1713. top:.9375em;
  1714. right:.1875em;
  1715. width:1.375em
  1716. }
  1717. }@keyframes swal2-toast-animate-success-line-long {
  1718. 0% {
  1719. top:1.625em;
  1720. right:1.375em;
  1721. width:0
  1722. }
  1723. 65% {
  1724. top:1.25em;
  1725. right:.9375em;
  1726. width:0
  1727. }
  1728. 84% {
  1729. top:.9375em;
  1730. right:0;
  1731. width:1.125em
  1732. }
  1733. 100% {
  1734. top:.9375em;
  1735. right:.1875em;
  1736. width:1.375em
  1737. }
  1738. }@-webkit-keyframes swal2-show {
  1739. 0% {
  1740. transform:scale(.7)
  1741. }
  1742. 45% {
  1743. transform:scale(1.05)
  1744. }
  1745. 80% {
  1746. transform:scale(.95)
  1747. }
  1748. 100% {
  1749. transform:scale(1)
  1750. }
  1751. }@keyframes swal2-show {
  1752. 0% {
  1753. transform:scale(.7)
  1754. }
  1755. 45% {
  1756. transform:scale(1.05)
  1757. }
  1758. 80% {
  1759. transform:scale(.95)
  1760. }
  1761. 100% {
  1762. transform:scale(1)
  1763. }
  1764. }@-webkit-keyframes swal2-hide {
  1765. 0% {
  1766. transform:scale(1);
  1767. opacity:1
  1768. }
  1769. 100% {
  1770. transform:scale(.5);
  1771. opacity:0
  1772. }
  1773. }@keyframes swal2-hide {
  1774. 0% {
  1775. transform:scale(1);
  1776. opacity:1
  1777. }
  1778. 100% {
  1779. transform:scale(.5);
  1780. opacity:0
  1781. }
  1782. }@-webkit-keyframes swal2-animate-success-line-tip {
  1783. 0% {
  1784. top:1.1875em;
  1785. left:.0625em;
  1786. width:0
  1787. }
  1788. 54% {
  1789. top:1.0625em;
  1790. left:.125em;
  1791. width:0
  1792. }
  1793. 70% {
  1794. top:2.1875em;
  1795. left:-.375em;
  1796. width:3.125em
  1797. }
  1798. 84% {
  1799. top:3em;
  1800. left:1.3125em;
  1801. width:1.0625em
  1802. }
  1803. 100% {
  1804. top:2.8125em;
  1805. left:.8125em;
  1806. width:1.5625em
  1807. }
  1808. }@keyframes swal2-animate-success-line-tip {
  1809. 0% {
  1810. top:1.1875em;
  1811. left:.0625em;
  1812. width:0
  1813. }
  1814. 54% {
  1815. top:1.0625em;
  1816. left:.125em;
  1817. width:0
  1818. }
  1819. 70% {
  1820. top:2.1875em;
  1821. left:-.375em;
  1822. width:3.125em
  1823. }
  1824. 84% {
  1825. top:3em;
  1826. left:1.3125em;
  1827. width:1.0625em
  1828. }
  1829. 100% {
  1830. top:2.8125em;
  1831. left:.8125em;
  1832. width:1.5625em
  1833. }
  1834. }@-webkit-keyframes swal2-animate-success-line-long {
  1835. 0% {
  1836. top:3.375em;
  1837. right:2.875em;
  1838. width:0
  1839. }
  1840. 65% {
  1841. top:3.375em;
  1842. right:2.875em;
  1843. width:0
  1844. }
  1845. 84% {
  1846. top:2.1875em;
  1847. right:0;
  1848. width:3.4375em
  1849. }
  1850. 100% {
  1851. top:2.375em;
  1852. right:.5em;
  1853. width:2.9375em
  1854. }
  1855. }@keyframes swal2-animate-success-line-long {
  1856. 0% {
  1857. top:3.375em;
  1858. right:2.875em;
  1859. width:0
  1860. }
  1861. 65% {
  1862. top:3.375em;
  1863. right:2.875em;
  1864. width:0
  1865. }
  1866. 84% {
  1867. top:2.1875em;
  1868. right:0;
  1869. width:3.4375em
  1870. }
  1871. 100% {
  1872. top:2.375em;
  1873. right:.5em;
  1874. width:2.9375em
  1875. }
  1876. }@-webkit-keyframes swal2-rotate-success-circular-line {
  1877. 0% {
  1878. transform:rotate(-45deg)
  1879. }
  1880. 5% {
  1881. transform:rotate(-45deg)
  1882. }
  1883. 12% {
  1884. transform:rotate(-405deg)
  1885. }
  1886. 100% {
  1887. transform:rotate(-405deg)
  1888. }
  1889. }@keyframes swal2-rotate-success-circular-line {
  1890. 0% {
  1891. transform:rotate(-45deg)
  1892. }
  1893. 5% {
  1894. transform:rotate(-45deg)
  1895. }
  1896. 12% {
  1897. transform:rotate(-405deg)
  1898. }
  1899. 100% {
  1900. transform:rotate(-405deg)
  1901. }
  1902. }@-webkit-keyframes swal2-animate-error-x-mark {
  1903. 0% {
  1904. margin-top:1.625em;
  1905. transform:scale(.4);
  1906. opacity:0
  1907. }
  1908. 50% {
  1909. margin-top:1.625em;
  1910. transform:scale(.4);
  1911. opacity:0
  1912. }
  1913. 80% {
  1914. margin-top:-.375em;
  1915. transform:scale(1.15)
  1916. }
  1917. 100% {
  1918. margin-top:0;
  1919. transform:scale(1);
  1920. opacity:1
  1921. }
  1922. }@keyframes swal2-animate-error-x-mark {
  1923. 0% {
  1924. margin-top:1.625em;
  1925. transform:scale(.4);
  1926. opacity:0
  1927. }
  1928. 50% {
  1929. margin-top:1.625em;
  1930. transform:scale(.4);
  1931. opacity:0
  1932. }
  1933. 80% {
  1934. margin-top:-.375em;
  1935. transform:scale(1.15)
  1936. }
  1937. 100% {
  1938. margin-top:0;
  1939. transform:scale(1);
  1940. opacity:1
  1941. }
  1942. }@-webkit-keyframes swal2-animate-error-icon {
  1943. 0% {
  1944. transform:rotateX(100deg);
  1945. opacity:0
  1946. }
  1947. 100% {
  1948. transform:rotateX(0);
  1949. opacity:1
  1950. }
  1951. }@keyframes swal2-animate-error-icon {
  1952. 0% {
  1953. transform:rotateX(100deg);
  1954. opacity:0
  1955. }
  1956. 100% {
  1957. transform:rotateX(0);
  1958. opacity:1
  1959. }
  1960. }@-webkit-keyframes swal2-rotate-loading {
  1961. 0% {
  1962. transform:rotate(0)
  1963. }
  1964. 100% {
  1965. transform:rotate(360deg)
  1966. }
  1967. }@keyframes swal2-rotate-loading {
  1968. 0% {
  1969. transform:rotate(0)
  1970. }
  1971. 100% {
  1972. transform:rotate(360deg)
  1973. }
  1974. }@-webkit-keyframes swal2-animate-question-mark {
  1975. 0% {
  1976. transform:rotateY(-360deg)
  1977. }
  1978. 100% {
  1979. transform:rotateY(0)
  1980. }
  1981. }@keyframes swal2-animate-question-mark {
  1982. 0% {
  1983. transform:rotateY(-360deg)
  1984. }
  1985. 100% {
  1986. transform:rotateY(0)
  1987. }
  1988. }@-webkit-keyframes swal2-animate-i-mark {
  1989. 0% {
  1990. transform:rotateZ(45deg);
  1991. opacity:0
  1992. }
  1993. 25% {
  1994. transform:rotateZ(-25deg);
  1995. opacity:.4
  1996. }
  1997. 50% {
  1998. transform:rotateZ(15deg);
  1999. opacity:.8
  2000. }
  2001. 75% {
  2002. transform:rotateZ(-5deg);
  2003. opacity:1
  2004. }
  2005. 100% {
  2006. transform:rotateX(0);
  2007. opacity:1
  2008. }
  2009. }@keyframes swal2-animate-i-mark {
  2010. 0% {
  2011. transform:rotateZ(45deg);
  2012. opacity:0
  2013. }
  2014. 25% {
  2015. transform:rotateZ(-25deg);
  2016. opacity:.4
  2017. }
  2018. 50% {
  2019. transform:rotateZ(15deg);
  2020. opacity:.8
  2021. }
  2022. 75% {
  2023. transform:rotateZ(-5deg);
  2024. opacity:1
  2025. }
  2026. 100% {
  2027. transform:rotateX(0);
  2028. opacity:1
  2029. }
  2030. }body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown) {
  2031. overflow:hidden
  2032. }
  2033. body.swal2-height-auto {
  2034. height:auto!important
  2035. }
  2036. body.swal2-no-backdrop .swal2-container {
  2037. background-color:transparent!important;
  2038. pointer-events:none
  2039. }
  2040. body.swal2-no-backdrop .swal2-container .swal2-popup {
  2041. pointer-events:all
  2042. }
  2043. body.swal2-no-backdrop .swal2-container .swal2-modal {
  2044. box-shadow:0 0 10px rgba(0,0,0,.4)
  2045. }
  2046. @media print {
  2047. body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown) {
  2048. overflow-y:scroll!important
  2049. }
  2050. body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown)>[aria-hidden=true] {
  2051. display:none
  2052. }
  2053. body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown) .swal2-container {
  2054. position:static!important
  2055. }
  2056. }body.swal2-toast-shown .swal2-container {
  2057. box-sizing:border-box;
  2058. width:360px;
  2059. max-width:100%;
  2060. background-color:transparent;
  2061. pointer-events:none
  2062. }
  2063. body.swal2-toast-shown .swal2-container.swal2-top {
  2064. top:0;
  2065. right:auto;
  2066. bottom:auto;
  2067. left:50%;
  2068. transform:translateX(-50%)
  2069. }
  2070. body.swal2-toast-shown .swal2-container.swal2-top-end,body.swal2-toast-shown .swal2-container.swal2-top-right {
  2071. top:0;
  2072. right:0;
  2073. bottom:auto;
  2074. left:auto
  2075. }
  2076. body.swal2-toast-shown .swal2-container.swal2-top-left,body.swal2-toast-shown .swal2-container.swal2-top-start {
  2077. top:0;
  2078. right:auto;
  2079. bottom:auto;
  2080. left:0
  2081. }
  2082. body.swal2-toast-shown .swal2-container.swal2-center-left,body.swal2-toast-shown .swal2-container.swal2-center-start {
  2083. top:50%;
  2084. right:auto;
  2085. bottom:auto;
  2086. left:0;
  2087. transform:translateY(-50%)
  2088. }
  2089. body.swal2-toast-shown .swal2-container.swal2-center {
  2090. top:50%;
  2091. right:auto;
  2092. bottom:auto;
  2093. left:50%;
  2094. transform:translate(-50%,-50%)
  2095. }
  2096. body.swal2-toast-shown .swal2-container.swal2-center-end,body.swal2-toast-shown .swal2-container.swal2-center-right {
  2097. top:50%;
  2098. right:0;
  2099. bottom:auto;
  2100. left:auto;
  2101. transform:translateY(-50%)
  2102. }
  2103. body.swal2-toast-shown .swal2-container.swal2-bottom-left,body.swal2-toast-shown .swal2-container.swal2-bottom-start {
  2104. top:auto;
  2105. right:auto;
  2106. bottom:0;
  2107. left:0
  2108. }
  2109. body.swal2-toast-shown .swal2-container.swal2-bottom {
  2110. top:auto;
  2111. right:auto;
  2112. bottom:0;
  2113. left:50%;
  2114. transform:translateX(-50%)
  2115. }
  2116. body.swal2-toast-shown .swal2-container.swal2-bottom-end,body.swal2-toast-shown .swal2-container.swal2-bottom-right {
  2117. top:auto;
  2118. right:0;
  2119. bottom:0;
  2120. left:auto
  2121. }
  2122. `;
  2123. this.addStyle('swal-style', 'style', swalcss);
  2124. },
  2125.  
  2126. async initDialog() {
  2127. let result = await Swal.fire({
  2128. title: pan.init[0],
  2129. allowOutsideClick: false,
  2130. showCloseButton: true,
  2131. showCancelButton: true,
  2132. confirmButtonText: '确定',
  2133. html: `<div><img style="width: 250px;margin-bottom: 10px;" src="${pan.img}" alt="${pan.img}"><input class="swal2-input" id="init" style="width:373;font-size:19px;" type="text" placeholder="${pan.init[1]}"><br><span>你可以选择“注入”立即点亮按钮,或者输入暗号。<br>暗号:“${pan.num}”。<br>(也可以扫码支持一下原作者油小猴)</span></div>`,
  2134. cancelButtonText: '注入(点亮下载助手按钮)'
  2135. });
  2136. if (result.isDismissed && result.dismiss === 'close') {console.log("窗口关闭");return};
  2137. if (result.isDismissed && result.dismiss === 'cancel') {
  2138. console.log("注入暗号")
  2139. console.log("正在注入点亮按钮设置项目...");
  2140. message.warning("正在注入点亮按钮设置项目...");
  2141. setTimeout(() => {
  2142. base.setValue('setting_init_code', pan.num);
  2143. message.success("注入成功!");
  2144. setTimeout(() => {
  2145. message.success(pan.init[2]);
  2146. setTimeout(() => {
  2147. history.go(0);
  2148. }, 3000);
  2149. }, 3000);
  2150. }, 5000);
  2151. return;
  2152. };
  2153. if (pan.num === $('#init').val()) {
  2154. console.log("暗号正确")
  2155. message.success(pan.init[2]);
  2156. setTimeout(() => {
  2157. base.setValue('setting_init_code', pan.num);
  2158. history.go(0);
  2159. }, 3000)
  2160. return;
  2161. } else {
  2162. console.log("暗号错误")
  2163. await Swal.fire({
  2164. imageUrl: pan.img,
  2165. title: pan.init[3],
  2166. html: `<div><span>${pan.init[4]}<br>你可以在返回后选择“注入”立即点亮按钮,<br>或者在输入框键入以下暗号:“${pan.num}”。</span></div>`,
  2167. confirmButtonText: '重新输入(返回)',
  2168. });
  2169. await this.initDialog();
  2170. return;
  2171. };
  2172. /*---
  2173. homo彩蛋被删去力(悲),存下图片罢!
  2174. imageUrl: 'https://pic4.zhimg.com/80/v2-1b97a088e156c015108dec663bba8b04.jpg',
  2175. imageUrl: 'https://lh1.hetaousercontent.com/img/7d4c1c0b4adb0e95.jpg',
  2176. */
  2177. },
  2178. };
  2179.  
  2180. //百度网盘
  2181. let baidu = {
  2182.  
  2183. _getExtra() {
  2184. let seKey = decodeURIComponent(base.getCookie('BDCLND'));
  2185. return '{' + '"sekey":"' + seKey + '"' + "}";
  2186. },
  2187.  
  2188. _getSurl() {
  2189. let reg = /(?<=s\/|surl=)([a-zA-Z0-9_-]+)/g;
  2190. if (reg.test(location.href)) {
  2191. return location.href.match(reg)[0];
  2192. }
  2193. return '';
  2194. },
  2195.  
  2196. _getFidList() {
  2197. let fidlist = [];
  2198. selectList.forEach(v => {
  2199. if (+v.isdir === 1) return;
  2200. fidlist.push(v.fs_id);
  2201. });
  2202. return '[' + fidlist + ']';
  2203. },
  2204.  
  2205. _resetData() {
  2206. progress = {};
  2207. $.each(request, (key) => {
  2208. (request[key]).abort();
  2209. });
  2210. $.each(ins, (key) => {
  2211. clearInterval(ins[key]);
  2212. });
  2213. idm = {};
  2214. ins = {};
  2215. request = {};
  2216. },
  2217.  
  2218. setBDUSS() {
  2219. try {
  2220. GM_cookie && GM_cookie('list', {name: 'BDUSS'}, (cookies, error) => {
  2221. if (!error) {
  2222. base.setStorage("baiduyunPlugin_BDUSS", {BDUSS: cookies[0].value});
  2223. }
  2224. });
  2225. } catch (e) {
  2226. }
  2227. },
  2228.  
  2229. getBDUSS() {
  2230. let baiduyunPlugin_BDUSS = base.getStorage('baiduyunPlugin_BDUSS') ? base.getStorage('baiduyunPlugin_BDUSS') : '{"baiduyunPlugin_BDUSS":""}';
  2231. return baiduyunPlugin_BDUSS.BDUSS || '';
  2232. },
  2233.  
  2234. convertLinkToAria(link, filename, ua) {
  2235. let BDUSS = this.getBDUSS();
  2236. if (!!BDUSS) {
  2237. filename = base.fixFilename(filename);
  2238. return encodeURIComponent(`aria2c "${link}" --out "${filename}" --header "User-Agent: ${ua}" --header "Cookie: BDUSS=${BDUSS}"`);
  2239. }
  2240. return {
  2241. link: pan.assistant,
  2242. text: pan.init[5]
  2243. };
  2244. },
  2245.  
  2246. convertLinkToBC(link, filename, ua) {
  2247. let BDUSS = this.getBDUSS();
  2248. if (!!BDUSS) {
  2249. let cookie = `BDUSS=${BDUSS}`;
  2250. let bc = `AA/${encodeURIComponent(filename)}/?url=${encodeURIComponent(link)}&cookie=${encodeURIComponent(cookie)}&user_agent=${encodeURIComponent(ua)}ZZ`;
  2251. return encodeURIComponent(`bc://http/${base.e(bc)}`);
  2252. }
  2253. return {
  2254. link: pan.assistant,
  2255. text: pan.init[5]
  2256. };
  2257. },
  2258.  
  2259. convertLinkToCurl(link, filename, ua) {
  2260. let BDUSS = this.getBDUSS();
  2261. if (!!BDUSS) {
  2262. let terminal = base.getValue('setting_terminal_type');
  2263. filename = base.fixFilename(filename);
  2264. return encodeURIComponent(`${terminal !== 'wp' ? 'curl' : 'curl.exe'} -L -C - "${link}" -o "${filename}" -A "${ua}" -b "BDUSS=${BDUSS}"`);
  2265. }
  2266. return {
  2267. link: pan.assistant,
  2268. text: pan.init[5]
  2269. };
  2270. },
  2271.  
  2272. addPageListener() {
  2273. function _factory(e) {
  2274. let target = $(e.target);
  2275. let item = target.parents('.pl-item');
  2276. let link = item.find('.pl-item-link');
  2277. let progress = item.find('.pl-item-progress');
  2278. let tip = item.find('.pl-item-tip');
  2279. let copy = item.find('.pl-item-copy');
  2280. let howidm = item.find('.pl-progress-how');
  2281. let back = item.find('.pl-progress-back');
  2282. return {
  2283. item, link, progress, tip, copy, howidm, target,
  2284. };
  2285. }
  2286.  
  2287. function _reset(i) {
  2288. ins[i] && clearInterval(ins[i]);
  2289. request[i] && request[i].abort();
  2290. progress[i] = 0;
  2291. idm[i] = false;
  2292. }
  2293.  
  2294. doc.on('mouseenter mouseleave click', '.pl-button.g-dropdown-button', (e) => {
  2295. if (e.type === 'mouseleave') {
  2296. $(e.currentTarget).removeClass('button-open');
  2297. } else {
  2298. $(e.currentTarget).addClass('button-open');
  2299. $(e.currentTarget).find('.pl-dropdown-menu').show();
  2300. }
  2301. });
  2302. doc.on('mouseleave', '.pl-button.g-dropdown-button .pl-dropdown-menu', (e) => {
  2303. $(e.currentTarget).hide();
  2304. });
  2305.  
  2306. doc.on('click', '.pl-button-mode', (e) => {
  2307. mode = e.target.dataset.mode;
  2308. Swal.showLoading();
  2309. this.getPCSLink();
  2310. });
  2311. doc.on('click', '.listener-link-api', async (e) => {
  2312. e.preventDefault();
  2313. let o = _factory(e);
  2314. let $width = o.item.find('.pl-progress-inner');
  2315. let $text = o.item.find('.pl-progress-inner-text');
  2316. let filename = o.link[0].dataset.filename;
  2317. let index = o.link[0].dataset.index;
  2318. _reset(index);
  2319. base.get(o.link[0].dataset.link, {"User-Agent": pan.ua}, 'blob', {filename, index});
  2320. ins[index] = setInterval(() => {
  2321. let prog = +progress[index] || 0;
  2322. let isIDM = idm[index] || false;
  2323. if (isIDM) {
  2324. o.tip.hide();
  2325. o.progress.hide();
  2326. o.link.text('已成功唤起IDM,请查看IDM下载框!').animate({opacity: '0.5'}, "slow").show();
  2327. clearInterval(ins[index]);
  2328. setTimeout(
  2329. function (){
  2330. o.copy.show();
  2331. o.link.text('重新下载').animate({opacity: '1'}, "slow");
  2332. },2000
  2333. )
  2334. idm[index] = false;
  2335. } else {
  2336. o.link.hide();
  2337. o.tip.hide();
  2338. o.copy.hide();
  2339. o.progress.show();
  2340. $width.css('width', prog + '%');
  2341. $text.text(prog + '%');
  2342. if (prog === 100) {
  2343. clearInterval(ins[index]);
  2344. progress[index] = 0;
  2345. o.item.find('.pl-progress-stop').hide();
  2346. o.copy.show();
  2347. o.howidm.hide();
  2348. o.item.find('.pl-progress-tip').html('下载完成,正在弹出浏览器下载框!');
  2349. o.back.show()
  2350. setTimeout(
  2351. function (){
  2352. o.link.text('重新下载').animate({opacity: '1'}, "slow");
  2353. },3000
  2354. )
  2355. }
  2356. }
  2357. }, 500);
  2358. });
  2359. doc.on('click', '.listener-retry', async (e) => {
  2360. let o = _factory(e);
  2361. o.tip.hide();
  2362. o.link.show();
  2363. });
  2364. doc.on('click', '.listener-how', async (e) => {
  2365. let o = _factory(e);
  2366. let index = o.link[0].dataset.index;
  2367. if (request[index]) {
  2368. request[index].abort();
  2369. clearInterval(ins[index]);
  2370. o.progress.hide();
  2371. o.tip.show();
  2372. }
  2373.  
  2374. });
  2375. doc.on('click', '.listener-stop', async (e) => {
  2376. let o = _factory(e);
  2377. let index = o.link[0].dataset.index;
  2378. if (request[index]) {
  2379. request[index].abort();
  2380. clearInterval(ins[index]);
  2381. o.tip.hide();
  2382. o.progress.hide();
  2383. o.link.show(0);
  2384. o.copy.show();
  2385. }
  2386. });
  2387. doc.on('click', '.listener-back', async (e) => {
  2388. let o = _factory(e);
  2389. o.progress.hide();
  2390. o.tip.hide();
  2391. o.link.show();
  2392. });
  2393. doc.on('click', '.listener-link-aria, .listener-copy-all', (e) => {
  2394. e.preventDefault();
  2395. if (!e.target.dataset.link) {
  2396. $(e.target).removeClass('listener-copy-all').addClass('pl-btn-danger').html(`${pan.init[5]}👉<a href="${pan.assistant}" target="_blank" class="pl-a">点击此处安装</a>👈`);
  2397. } else {
  2398. base.setClipboard(decodeURIComponent(e.target.dataset.link));
  2399. $(e.target).text('复制成功!').animate({opacity: '0.5'}, "slow");
  2400. setTimeout(
  2401. function (){
  2402. $(e.target).text('重新复制').animate({opacity: '1'}, "slow");
  2403. },2000
  2404. )
  2405. }
  2406. });
  2407. doc.on('click', '.listener-link-rpc', async (e) => {
  2408. let target = $(e.currentTarget);
  2409. target.find('.icon').remove();
  2410. target.find('.pl-loading').remove();
  2411. target.prepend(base.createLoading());
  2412. let res = await this.sendLinkToRPC(e.currentTarget.dataset.filename, e.currentTarget.dataset.link);
  2413. if (res === 'success') {
  2414. $('.listener-rpc-task').show();
  2415. target.removeClass('pl-btn-danger').html('发送成功,快去看看吧!').animate({opacity: '0.5'}, "slow");
  2416. } else if (res === 'assistant') {
  2417. target.addClass('pl-btn-danger').html(`${pan.init[5]}👉<a href="${pan.assistant}" target="_blank" class="pl-a">点击此处安装</a>👈`);
  2418. } else {
  2419. target.addClass('pl-btn-danger').text('发送失败,请检查您的RPC配置信息!').animate({opacity: '0.5'}, "slow");
  2420. }
  2421. });
  2422. doc.on('click', '.listener-send-rpc', (e) => {
  2423. $('.listener-link-rpc').click();
  2424. $(e.target).text('发送完成,发送结果见上方按钮!').animate({opacity: '0.5'}, "slow");
  2425. });
  2426. doc.on('click', '.listener-open-setting', () => {
  2427. base.showSetting();
  2428. });
  2429. doc.on('click', '.listener-open-updatelog', () => {
  2430. base.showUpdateLog();
  2431. });
  2432. doc.on('click', '.listener-rpc-task', () => {
  2433. let rpc = JSON.stringify({
  2434. domain: base.getValue('setting_rpc_domain'),
  2435. port: base.getValue('setting_rpc_port'),
  2436. }), url = `${pan.d}/?rpc=${base.e(rpc)}#${base.getValue('setting_rpc_token')}`;
  2437. GM_openInTab(url, {active: true});
  2438. });
  2439. document.documentElement.addEventListener('mouseup', (e) => {
  2440. if (e.target.nodeName === 'A' && ~e.target.className.indexOf('pl-a')) {
  2441. e.stopPropagation();
  2442. }
  2443. }, true);
  2444. },
  2445.  
  2446. addButton() {
  2447. waitForKeyElements(".wp-s-header__vip-btn-tip", function () {
  2448. let vip1 = document.getElementsByClassName("wp-s-header__vip-btn-tip")[0];
  2449. vip1.remove();
  2450. });
  2451. waitForKeyElements(".app-user-vip-center-tip", function () {
  2452. let vip2 = document.getElementsByClassName("app-user-vip-center-tip")[0];
  2453. vip2.remove();
  2454. });
  2455. waitForKeyElements(".web-header-text-s-45", function () {
  2456. let vip3 = document.getElementById("web-header-text-s-45");
  2457. vip3.remove();
  2458. });
  2459. waitForKeyElements(".wp-s-header__vip-btn", function () {
  2460. let vip4 = document.getElementsByClassName("wp-s-header__vip-btn")[0];
  2461. vip4.innerText = "会员中心";
  2462. });
  2463. waitForKeyElements(".KQcHyA", function () {
  2464. let vip5 = document.getElementsByClassName("KQcHyA")[0];
  2465. vip5.innerText = "会员中心";
  2466. });
  2467. waitForKeyElements(".gOIbzPb", function () {
  2468. let vip6 = document.getElementsByClassName("gOIbzPb")[0];
  2469. vip6.remove();
  2470. });
  2471. waitForKeyElements(".app-user-vip-center-box", function () {
  2472. let vip7 = document.getElementsByClassName("app-user-vip-center-box vip-center-type-2")[0];
  2473. vip7.remove();
  2474. });
  2475. waitForKeyElements(".u-popover", function () {
  2476. setInterval(function(){
  2477. let vip8 = document.getElementsByClassName("wp-s-header-user__vip-center")[0];
  2478. let arrow = document.getElementsByClassName("popper__arrow")[0];
  2479. if(vip8){
  2480. vip8.remove();
  2481. }
  2482. if(arrow){
  2483. arrow.remove();
  2484. };
  2485. },10)
  2486. });
  2487. waitForKeyElements(".wp-s-header-user__create-team-title", function () {
  2488. let ad1 = document.getElementsByClassName("wp-s-header-user__create-team-title")[0];
  2489. ad1.remove();
  2490. });
  2491. waitForKeyElements(".wp-side-options g-clearfix", function () {
  2492. let ad2 = document.getElementsByClassName("wp-side-options g-clearfix")[0];
  2493. ad2.remove();
  2494. });
  2495. waitForKeyElements(".web-header-ad-item", function () {
  2496. let ad3 = document.getElementsByClassName("web-header-ad-item wp-s-header__right-item")[0];
  2497. ad3.remove();
  2498. });
  2499. waitForKeyElements(".newIcon", function () {
  2500. let newicon1 = document.getElementsByClassName("newIcon")[0];
  2501. newicon1.remove();
  2502. });
  2503. waitForKeyElements(".u-badge__content", function () {
  2504. let newicon2 = document.getElementsByClassName("u-badge__content is-dot")[0];
  2505. if(newicon2) {
  2506. newicon2.remove();
  2507. }
  2508. });
  2509. waitForKeyElements(".wp-side-options-btn", function () {
  2510. let qiye1 = document.getElementsByClassName("wp-side-options g-clearfix")[0];
  2511. qiye1.remove();
  2512. });
  2513. waitForKeyElements(".app-download", function () {
  2514. let app1 = document.getElementsByClassName("app-download")[0];
  2515. app1.remove();
  2516. });
  2517. if (!pt) return;
  2518. let $toolWrap;
  2519. let $button = $(`<div class="g-dropdown-button pointer pl-button"><div style="color:#fff;background: ${color};border-color:${color}" class="g-button g-button-blue"><span class="g-button-right"><em class="icon icon-download"></em><span class="text" style="width: 60px;">下载助手</span></span></div><div class="menu" style="width:auto;z-index:41;border-color:${color}"><div class="g-button-menu pl-button-mode" data-mode="api" style="color:${color};">API下载</div><div class="g-button-menu pl-button-mode" data-mode="aria" style="color:${color};">Aria下载</div><div class="g-button-menu pl-button-mode" data-mode="rpc" style="color:${color};">RPC下载</div><div class="g-button-menu pl-button-mode" data-mode="curl" style="color:${color};">cURL下载</div><div class="g-button-menu pl-button-mode" data-mode="bc" style="color:${color};">BC下载</div><div class="g-button-menu pl-button-mode listener-open-setting" style="color:${color};">助手设置</div><div class="g-button-menu pl-button-mode listener-open-updatelog" style="color:${color};">更新日志</div></div></div>`);
  2520. if (pt === 'home') $toolWrap = $(pan.btn.home);
  2521. if (pt === 'main') {
  2522. $toolWrap = $(pan.btn.main);
  2523. $button = $(`<div class="pl-button" style="position: relative; display: inline-block; margin-right: 8px;"><button class="u-button u-button--primary u-button--small is-round is-has-icon" style="background: ${color};border-color: ${color};font-size: 14px; padding: 8px 16px; border: none;"><i class="u-icon u-icon-download"></i><span>下载助手</span></button><ul class="dropdown-list nd-common-float-menu pl-dropdown-menu"><li class="pl-button-mode sub cursor-p" data-mode="api">API下载</li><li class="pl-button-mode sub cursor-p" data-mode="aria">Aria下载</li><li class="pl-button-mode sub cursor-p" data-mode="rpc">RPC下载</li><li class="pl-button-mode sub cursor-p" data-mode="curl">cURL下载</li><li class="pl-button-mode sub cursor-p" data-mode="bc">BC下载</li><li class="pl-button-mode sub cursor-p listener-open-setting"">助手设置</li><li class="pl-button-mode sub cursor-p listener-open-updatelog">更新日志</li></ul></div>`);
  2524. }
  2525. if (pt === 'share') $toolWrap = $(pan.btn.share);
  2526. $toolWrap.prepend($button);
  2527. this.setBDUSS();
  2528. this.addPageListener();
  2529. },
  2530.  
  2531. addInitButton() {
  2532. if (!pt) return;
  2533. let $toolWrap;
  2534. let $button = $(`<div class="g-dropdown-button pointer pl-button-init" style="opacity:.5"><div style="color:#fff;background: ${color};border-color:${color}" class="g-button g-button-blue"><span class="g-button-right"><em class="icon icon-download"></em><span class="text" style="width: 60px;">下载助手(未点亮)</span></span></div></div>`);
  2535. if (pt === 'home') $toolWrap = $(pan.btn.home);
  2536. if (pt === 'main') {
  2537. $toolWrap = $(pan.btn.main);
  2538. $button = $(`<div class="pl-button-init" style="opacity:.5; display: inline-block; margin-right: 8px;"><button class="u-button u-button--primary u-button--small is-round is-has-icon" style="background: ${color};border-color: ${color};font-size: 14px; padding: 8px 16px; border: none;"><i class="u-icon u-icon-download"></i><span>下载助手(未点亮)</span></button></div>`);
  2539. }
  2540. if (pt === 'share') $toolWrap = $(pan.btn.share);
  2541. $toolWrap.prepend($button);
  2542. $button.click(() => base.initDialog());
  2543. },
  2544.  
  2545. async getPCSLink() {
  2546. selectList = this.getSelectedList();
  2547. let fidList = this._getFidList(), url, res;
  2548.  
  2549. if (pt === 'home' || pt === 'main') {
  2550. if (selectList.length === 0) {
  2551. return message.error('提示:请先勾选要下载的文件!');
  2552. }
  2553. if (fidList.length === 2) {
  2554. return message.error('提示:请打开文件夹后勾选文件!');
  2555. }
  2556. fidList = encodeURIComponent(fidList);
  2557. url = `${pan.pcs[0]}&fsids=${fidList}`;
  2558. res = await base.get(url, {"User-Agent": pan.ua});
  2559. }
  2560. if (pt === 'share') {
  2561. this.getShareData();
  2562. if (selectList.length === 0) {
  2563. return message.error('提示:请先勾选要下载的文件!');
  2564. }
  2565. if (fidList.length === 2) {
  2566. return message.error('提示:请打开文件夹后勾选文件!');
  2567. }
  2568. if (!params.sign) {
  2569. let url = `${pan.pcs[2]}&surl=${params.surl}&logid=${params.logid}`;
  2570. let r = await base.get(url);
  2571. if (r.errno === 0) {
  2572. params.sign = r.data.sign;
  2573. params.timestamp = r.data.timestamp;
  2574. } else {
  2575. let dialog = await Swal.fire({
  2576. toast: true,
  2577. icon: 'info',
  2578. title: `提示:请将文件<span class="tag-danger">[保存到网盘]</span>👉前往<span class="tag-danger">[我的网盘]</span>中下载!`,
  2579. showConfirmButton: true,
  2580. confirmButtonText: '点击保存',
  2581. position: 'top',
  2582. });
  2583. if (dialog.isConfirmed) {
  2584. $('.tools-share-save-hb')[0].click();
  2585. }
  2586. return;
  2587. }
  2588. }
  2589. if (!params.bdstoken) {
  2590. return message.error('提示:请先登录(不可用)网盘!');
  2591. }
  2592. let formData = new FormData();
  2593. formData.append('encrypt', params.encrypt);
  2594. formData.append('product', params.product);
  2595. formData.append('uk', params.uk);
  2596. formData.append('primaryid', params.primaryid);
  2597. formData.append('fid_list', fidList);
  2598. formData.append('logid', params.logid);
  2599. params.shareType === 'secret' ? formData.append('extra', params.extra) : '';
  2600. url = `${pan.pcs[1]}&sign=${params.sign}&timestamp=${params.timestamp}`;
  2601. res = await base.post(url, formData, {"User-Agent": pan.ua});
  2602. }
  2603. if (res.errno === 0) {
  2604. let html = this.generateDom(res.list);
  2605. this.showMainDialog(pan[mode][0], html, pan[mode][1]);
  2606. } else if (res.errno === 112) {
  2607. return message.error('提示:页面过期,请刷新重试!');
  2608. } else {
  2609. message.error('提示:获取下载链接失败!请刷新网页后重试!(或者试试重新登录(不可用)网盘?)');
  2610. }
  2611. },
  2612.  
  2613. generateDom(list) {
  2614. let content = '<div class="pl-main">';
  2615. let alinkAllText = '';
  2616. base.sortByName(list);
  2617. list.forEach((v, i) => {
  2618. if (v.isdir === 1) return;
  2619. let filename = v.server_filename || v.filename;
  2620. let ext = base.getExtension(filename);
  2621. let size = base.sizeFormat(v.size);
  2622. let dlink = v.dlink;
  2623. if (mode === 'api') {
  2624. alinkAllText += dlink + '\r\n';
  2625. content += `<div class="pl-item">
  2626. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  2627. <a class="pl-item-link pl-a listener-link-api" href="${dlink}" data-filename="${filename}" data-link="${dlink}" data-index="${i}">${dlink}<br>使用blob技术(支持断点续传) 下载 ${filename}</a>
  2628. <!--<a class="pl-item-copy" target="_blank" href="${dlink}" title="点击使用浏览器下载" data-filename="${filename}" data-link="${dlink}">传统下载</a>-->
  2629. <button class="pl-item-copy pl-btn-primary listener-copy-all" href="${dlink}" title="点击复制链接" data-filename="${filename}" data-link="${dlink}">复制链接</button>
  2630. <div class="pl-item-tip" style="display: none"><span>若没有弹出IDM下载框,找到IDM <b>选项</b> -> <b>文件类型</b> -> <b>第一个框</b> 中添加后缀 <span class="pl-ext">${ext}</span>,<a href="${pan.idm}" target="_blank" class="pl-a">详见此处</a></span> <span class="pl-back listener-back">返回</span></div>
  2631. <div class="pl-item-progress" style="display: none">
  2632. <div class="pl-progress">
  2633. <div class="pl-progress-outer"></div>
  2634. <div class="pl-progress-inner" style="width:5%">
  2635. <div class="pl-progress-inner-text">正在加载进度...0%</div>
  2636. </div>
  2637. </div>
  2638. <span class="pl-progress-stop listener-stop">取消下载</span>
  2639. `;
  2640. if (base.getValue('setting_hide_idm') === 'no') {
  2641. content+=`<span class="pl-progress-tip" >未发现IDM,使用自带浏览器下载</span>
  2642. <span class="pl-progress-back pl-back listener-back" style="display: none">返回</span>
  2643. <span class="pl-progress-how listener-how">如何唤起IDM?</span>
  2644. `
  2645. } else {
  2646. content+=`<span class="pl-progress-tip" style="display: none" >未发现IDM,使用自带浏览器下载</span>
  2647. <span class="pl-progress-back pl-back listener-back" style="display: none">返回</span>
  2648. <span class="pl-progress-how listener-how" style="display: none">如何唤起IDM?</span>
  2649. `
  2650. };
  2651. content +=`</div></div>`
  2652. }
  2653. if (mode === 'aria') {
  2654. let alink = this.convertLinkToAria(dlink, filename, pan.ua);
  2655. if (typeof (alink) === 'object') {
  2656. content += `<div class="pl-item">
  2657. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  2658. <a class="pl-item-link pl-a" target="_blank" href="${alink.link}" title="点击复制aria2c链接" data-filename="${filename}" data-link="${alink.link}">${decodeURIComponent(alink.text)}<br>复制 ${filename} 下载命令行</a> </div>`;
  2659. } else {
  2660. alinkAllText += alink + '\r\n';
  2661. content += `<div class="pl-item">
  2662. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  2663. <a class="pl-item-link pl-a listener-link-aria" href="${alink}" title="点击复制aria2c链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}<br>复制 ${filename} 下载命令行</a> </div>`;
  2664. }
  2665. }
  2666. if (mode === 'rpc') {
  2667. content += `<div class="pl-item">
  2668. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  2669. <button class="pl-item-link listener-link-rpc pl-btn-primary pl-btn-info" data-filename="${filename}" data-link="${dlink}"><em class="icon icon-device"></em><span style="margin-left: 5px;">将 ${filename} 推送到 RPC 下载器</span></button></div>`;
  2670. }
  2671. if (mode === 'curl') {
  2672. let alink = this.convertLinkToCurl(dlink, filename, pan.ua);
  2673. if (typeof (alink) === 'object') {
  2674. content += `<div class="pl-item">
  2675. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  2676. <a class="pl-item-link pl-a" target="_blank" href="${alink.link}" title="点击复制curl链接" data-filename="${filename}" data-link="${alink.link}">${decodeURIComponent(alink.text)}<br>复制 ${filename} 下载命令行</a> </div>`;
  2677. } else {
  2678. alinkAllText += alink + '\r\n';
  2679. content += `<div class="pl-item">
  2680. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  2681. <a class="pl-item-link pl-a listener-link-aria" href="${alink}" title="点击复制curl链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}<br>复制 ${filename} 下载命令行</a> </div>`;
  2682. }
  2683. }
  2684. if (mode === 'bc') {
  2685. let alink = this.convertLinkToBC(dlink, filename, pan.ua);
  2686. console.log(alink);
  2687. if (typeof (alink) === 'object') {
  2688. content += `<div class="pl-item">
  2689. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  2690. <a class="pl-item-link pl-a" href="${decodeURIComponent(alink.link)}" title="点击用比特彗星下载" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink.text)}<br>下载 ${filename}</a> </div>`;
  2691. } else {
  2692. alinkAllText += alink + '\r\n';
  2693. content += `<div class="pl-item">
  2694. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  2695. <a class="pl-item-link pl-a" href="${decodeURIComponent(alink)}" title="点击用比特彗星下载" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}<br>下载 ${filename}</a> </div>`;
  2696. }
  2697. }
  2698. });
  2699.  
  2700. if (mode === 'api'){
  2701. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button></div>`;}
  2702. if (mode === 'aria'){
  2703. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button></div>`;}
  2704. if (mode === 'rpc') {
  2705. let rpc = base.getValue('setting_rpc_domain') + ':' + base.getValue('setting_rpc_port') + base.getValue('setting_rpc_path');
  2706. content += `<div class="pl-extra"><button class="pl-btn-primary listener-send-rpc">发送全部链接</button><button title="${rpc}" class="pl-btn-primary pl-btn-warning listener-open-setting" style="margin-left: 10px">设置 RPC 参数(当前为:${rpc})</button><button class="pl-btn-primary pl-btn-success listener-rpc-task" style="margin-left: 10px;display: none">查看下载任务</button></div>`;
  2707. }
  2708. if (mode === 'curl'){
  2709. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button><button class="pl-btn-primary pl-btn-warning listener-open-setting" style="margin-left: 10px;">设置终端类型(当前为:${terminalType[base.getValue('setting_terminal_type')]})</button></div>`;}
  2710. if (mode === 'bc'){
  2711. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button></div>`;}
  2712. content += '</div>';
  2713. return content;
  2714. },
  2715.  
  2716. async sendLinkToRPC(filename, link) {
  2717. let rpc = {
  2718. domain: base.getValue('setting_rpc_domain'),
  2719. port: base.getValue('setting_rpc_port'),
  2720. path: base.getValue('setting_rpc_path'),
  2721. token: base.getValue('setting_rpc_token'),
  2722. dir: base.getValue('setting_rpc_dir'),
  2723. };
  2724. let BDUSS = this.getBDUSS();
  2725. if (!BDUSS) return 'assistant';
  2726.  
  2727. let url = `${rpc.domain}:${rpc.port}${rpc.path}`;
  2728. let rpcData = {
  2729. id: new Date().getTime(),
  2730. jsonrpc: '2.0',
  2731. method: 'aria2.addUri',
  2732. params: [`token:${rpc.token}`, [link], {
  2733. dir: rpc.dir,
  2734. out: filename,
  2735. header: [`User-Agent: ${pan.ua}`, `Cookie: BDUSS=${BDUSS}`]
  2736. }]
  2737. };
  2738. try {
  2739. let res = await base.post(url, rpcData, {"User-Agent": pan.ua}, '');
  2740. if (res.result) return 'success';
  2741. return 'fail';
  2742. } catch (e) {
  2743. return 'fail';
  2744. }
  2745. },
  2746.  
  2747. getSelectedList() {
  2748. try {
  2749. return require('system-core:context/context.js').instanceForSystem.list.getSelected();
  2750. } catch (e) {
  2751. return document.querySelector('.wp-s-core-pan').__vue__.selectedList;
  2752. }
  2753. },
  2754.  
  2755. getLogid() {
  2756. let ut = require("system-core:context/context.js").instanceForSystem.tools.baseService;
  2757. return ut.base64Encode(base.getCookie("BAIDUID"));
  2758. },
  2759.  
  2760. getShareData() {
  2761. let res = locals.dump();
  2762. params.shareType = 'secret';
  2763. params.sign = '';
  2764. params.timestamp = '';
  2765. params.bdstoken = res.bdstoken.value;
  2766. params.channel = 'chunlei';
  2767. params.clienttype = 0;
  2768. params.web = 1;
  2769. params.app_id = 250528;
  2770. params.encrypt = 0;
  2771. params.product = 'share';
  2772. params.logid = this.getLogid();
  2773. params.primaryid = res.shareid.value;
  2774. params.uk = res.share_uk.value;
  2775. params.shareType === 'secret' && (params.extra = this._getExtra());
  2776. params.surl = this._getSurl();
  2777. },
  2778.  
  2779. detectPage() {
  2780. let path = location.pathname;
  2781. if (/^\/disk\/home/.test(path)) return 'home';
  2782. if (/^\/disk\/main/.test(path)) return 'main';
  2783. if (/^\/(s|share)\//.test(path)) return 'share';
  2784. return '';
  2785. return '';
  2786. },
  2787.  
  2788. showMainDialog(title, html, footer) { //下载窗口
  2789. Swal.fire({
  2790. title,
  2791. html,
  2792. footer,
  2793. allowOutsideClick: false,
  2794. showCloseButton: true,
  2795. confirmButtonText: '关闭',
  2796. position: 'top',
  2797. width: '1000px',
  2798. padding: '15px 20px 5px',
  2799. customClass,
  2800. }).then(() => {
  2801. this._resetData();
  2802. });
  2803. },
  2804.  
  2805. async initPanLinker() {
  2806. base.initDefaultConfig();
  2807. base.addPanLinkerStyle();
  2808. pt = this.detectPage();
  2809. if (base.getValue('setting_getuser_info') === 'yes') {
  2810. let res = await base.post
  2811. (`https://api.youxiaohou.com/config?ver=${version}&a=${author}`, {}, {}, 'text');
  2812. pan = JSON.parse(base.d(res));
  2813. };
  2814. Object.freeze && Object.freeze(pan);
  2815. pan.num === base.getValue('setting_init_code') ? this.addButton() : this.addInitButton();
  2816. base.createTip();
  2817. base.registerMenuCommand();
  2818. }
  2819. };
  2820.  
  2821. //阿里云盘
  2822. let ali = {
  2823.  
  2824. convertLinkToAria(link, filename, ua) {
  2825. filename = base.fixFilename(filename);
  2826. return encodeURIComponent(`aria2c "${link}" --out "${filename}" --header "Referer: https://www.aliyundrive.com/"`);
  2827. },
  2828.  
  2829. convertLinkToBC(link, filename, ua) {
  2830. let bc = `AA/${encodeURIComponent(filename)}/?url=${encodeURIComponent(link)}&refer=${encodeURIComponent('https://www.aliyundrive.com/')}ZZ`;
  2831. return encodeURIComponent(`bc://http/${base.e(bc)}`);
  2832. },
  2833.  
  2834. convertLinkToCurl(link, filename, ua) {
  2835. let terminal = base.getValue('setting_terminal_type');
  2836. filename = base.fixFilename(filename);
  2837. return encodeURIComponent(`${terminal !== 'wp' ? 'curl' : 'curl.exe'} -L -C - "${link}" -o "${filename}" -e "https://www.aliyundrive.com/"`);
  2838. },
  2839.  
  2840. addPageListener() {
  2841. doc.on('click', '.pl-button-mode', (e) => {
  2842. mode = e.target.dataset.mode;
  2843. Swal.showLoading();
  2844. this.getPCSLink();
  2845. });
  2846. doc.on('click', '.listener-link-api', async (e) => {
  2847. e.preventDefault();
  2848. let dataset = e.currentTarget.dataset;
  2849. let href = dataset.link;
  2850. let url = await this.getRealLink(dataset.did, dataset.fid);
  2851. if (url) href = url;
  2852. let d = document.createElement("a");
  2853. d.download = e.currentTarget.dataset.filename;
  2854. d.rel = "noopener";
  2855. d.href = href;
  2856. d.dispatchEvent(new MouseEvent("click"));
  2857. });
  2858. doc.on('click', '.listener-link-aria, .listener-copy-all', (e) => {
  2859. e.preventDefault();
  2860. base.setClipboard(decodeURIComponent(e.target.dataset.link));
  2861. $(e.target).text('复制成功,快去粘贴吧!').animate({opacity: '0.5'}, "slow");
  2862. });
  2863. doc.on('click', '.listener-link-rpc', async (e) => {
  2864. let target = $(e.currentTarget);
  2865. target.find('.icon').remove();
  2866. target.find('.pl-loading').remove();
  2867. target.prepend(base.createLoading());
  2868. let res = await this.sendLinkToRPC(e.currentTarget.dataset.filename, e.currentTarget.dataset.link);
  2869. if (res === 'success') {
  2870. $('.listener-rpc-task').show();
  2871. target.removeClass('pl-btn-danger').html('发送成功,快去看看吧!').animate({opacity: '0.5'}, "slow");
  2872. } else {
  2873. target.addClass('pl-btn-danger').text('发送失败,请检查您的RPC配置信息!').animate({opacity: '0.5'}, "slow");
  2874. }
  2875. });
  2876. doc.on('click', '.listener-send-rpc', (e) => {
  2877. $('.listener-link-rpc').click();
  2878. $(e.target).text('发送完成,发送结果见上方按钮!').animate({opacity: '0.5'}, "slow");
  2879. });
  2880. doc.on('click', '.listener-open-setting', () => {
  2881. base.showSetting();
  2882. });
  2883. doc.on('click', '.listener-open-updatelog', () => {
  2884. base.showUpdateLog();
  2885. });
  2886. doc.on('click', '.listener-rpc-task', () => {
  2887. let rpc = JSON.stringify({
  2888. domain: base.getValue('setting_rpc_domain'),
  2889. port: base.getValue('setting_rpc_port'),
  2890. }), url = `${pan.d}/?rpc=${base.e(rpc)}#${base.getValue('setting_rpc_token')}`;
  2891. GM_openInTab(url, {active: true});
  2892. });
  2893. },
  2894.  
  2895. async getRealLink(d, f) {
  2896. let authorization = `${base.getStorage('token').token_type} ${base.getStorage('token').access_token}`;
  2897. let res = await base.post(pan.pcs[1], {
  2898. drive_id: d,
  2899. file_id: f
  2900. }, {
  2901. authorization,
  2902. "content-type": "application/json;charset=utf-8",
  2903. });
  2904. if (res.url) {
  2905. return res.url;
  2906. }
  2907. return '';
  2908. },
  2909.  
  2910. addButton() {
  2911. waitForKeyElements(".share-list-banner--1E8Jr", function () {
  2912. let tip1 = document.getElementsByClassName("share-list-banner--1E8Jr")[0];
  2913. tip1.style.zIndex = 0;
  2914. });
  2915. waitForKeyElements(".to-app--DrlQQ", function () {
  2916. let tip2 = document.getElementsByClassName("to-app--DrlQQ")[0];
  2917. tip2.remove();
  2918. });
  2919. waitForKeyElements(".btn-mobile-save--2nXdf", function () {
  2920. let tip3 = document.getElementsByClassName("btn-mobile-save--2nXdf")[0];
  2921. tip3.remove();
  2922. });
  2923. if (!pt) return;
  2924. let $toolWrap;
  2925. let $button = $(`<div class="ali-button-big">下载助手<div class="button--3S7z9 ali-button pl-button"><span data-role="icon" data-render-as="svg" class="icon"><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M853.333 938.667H170.667a85.333 85.333 0 0 1-85.334-85.334v-384A85.333 85.333 0 0 1 170.667 384H288a32 32 0 0 1 0 64H170.667a21.333 21.333 0 0 0-21.334 21.333v384a21.333 21.333 0 0 0 21.334 21.334h682.666a21.333 21.333 0 0 0 21.334-21.334v-384A21.333 21.333 0 0 0 853.333 448H736a32 32 0 0 1 0-64h117.333a85.333 85.333 0 0 1 85.334 85.333v384a85.333 85.333 0 0 1-85.334 85.334z" fill="#FFFFFF"></path><path d="M715.03 543.552a32.81 32.81 0 0 0-46.251 0L554.005 657.813v-540.48a32 32 0 0 0-64 0v539.734L375.893 543.488a32.79 32.79 0 0 0-46.229 0 32.427 32.427 0 0 0 0 46.037l169.557 168.811a32.81 32.81 0 0 0 46.251 0l169.557-168.81a32.47 32.47 0 0 0 0-45.974z" fill="#FFFFFF"></path></svg></span><ul class="pl-dropdown-menu"><li class="pl-dropdown-menu-item pl-button-mode" data-mode="api">API下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="aria" >Aria下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="rpc">RPC下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="curl">cURL下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="bc" >BC下载</li><li class="pl-dropdown-menu-item pl-button-mode listener-open-setting">助手设置</li><li class="pl-dropdown-menu-item pl-button-mode listener-open-updatelog">更新日志</li></ul></div></div>`);
  2926. if (pt === 'home') {
  2927. let ins = setInterval(() => {
  2928. $toolWrap = $(pan.btn.home);
  2929. if ($toolWrap.length > 0) {
  2930. $toolWrap.append($button);
  2931. clearInterval(ins);
  2932. }
  2933. }, 50);
  2934. }
  2935. if (pt === 'share') {
  2936. $button.css({'margin-right': '10px'});
  2937. let ins = setInterval(() => {
  2938. $toolWrap = $(pan.btn.share);
  2939. if ($toolWrap.length > 0) {
  2940. $toolWrap.prepend($button);
  2941. clearInterval(ins);
  2942. }
  2943. }, 50);
  2944. }
  2945. base.createDownloadIframe();
  2946. this.addPageListener();
  2947. },
  2948.  
  2949. addInitButton() {
  2950. if (!pt) return;
  2951. let $toolWrap;
  2952. let $button = $(`<div class="ali-button-big">下载助手(未点亮)<div class="button--3S7z9 ali-button pl-button-init"><span data-role="icon" data-render-as="svg" class="icon"><svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M853.333 938.667H170.667a85.333 85.333 0 0 1-85.334-85.334v-384A85.333 85.333 0 0 1 170.667 384H288a32 32 0 0 1 0 64H170.667a21.333 21.333 0 0 0-21.334 21.333v384a21.333 21.333 0 0 0 21.334 21.334h682.666a21.333 21.333 0 0 0 21.334-21.334v-384A21.333 21.333 0 0 0 853.333 448H736a32 32 0 0 1 0-64h117.333a85.333 85.333 0 0 1 85.334 85.333v384a85.333 85.333 0 0 1-85.334 85.334z" fill="#FFFFFF"></path><path d="M715.03 543.552a32.81 32.81 0 0 0-46.251 0L554.005 657.813v-540.48a32 32 0 0 0-64 0v539.734L375.893 543.488a32.79 32.79 0 0 0-46.229 0 32.427 32.427 0 0 0 0 46.037l169.557 168.811a32.81 32.81 0 0 0 46.251 0l169.557-168.81a32.47 32.47 0 0 0 0-45.974z" fill="#FFFFFF"></path></svg></span></div>`);
  2953. if (pt === 'home') {
  2954. let ins = setInterval(() => {
  2955. $toolWrap = $(pan.btn.home);
  2956. if ($toolWrap.length > 0) {
  2957. $toolWrap.append($button);
  2958. clearInterval(ins);
  2959. }
  2960. }, 50);
  2961. }
  2962. if (pt === 'share') {
  2963. $button.css({'margin-right': '10px'});
  2964. let ins = setInterval(() => {
  2965. $toolWrap = $(pan.btn.share);
  2966. if ($toolWrap.length > 0) {
  2967. $toolWrap.prepend($button);
  2968. clearInterval(ins);
  2969. }
  2970. }, 50);
  2971. }
  2972. $button.click(() => base.initDialog());
  2973. },
  2974.  
  2975. async getPCSLink() {
  2976. let reactDomGrid = document.getElementsByClassName(pan.dom.grid)[0];
  2977. if (reactDomGrid) {
  2978. let res = await Swal.fire({
  2979. title: '提示',
  2980. html: '<div style="display: flex;align-items: center;justify-content: center;">请先切换到&nbsp;&nbsp;<b>列表视图</b>&nbsp;“<svg class="icon" viewBox="0 0 1024 1024" width="20" height="20"><use xlink:href="#PDSDrag"></use></svg>”&nbsp;&nbsp;后获取下载链接!</div>',
  2981. icon: 'info',
  2982. confirmButtonText: '点击切换'
  2983. });
  2984. if (res) {
  2985. $('.switch-wrapper--1yEfx').trigger('click');
  2986. return message.success('切换成功,请重新获取下载链接!');
  2987. }
  2988. return false;
  2989. }
  2990. selectList = this.getSelectedList();
  2991. if (selectList.length === 0) {
  2992. return message.error('提示:请先勾选要下载的文件!');
  2993. }
  2994. if (this.isOnlyFolder()) {
  2995. return message.error('提示:请打开文件夹后勾选文件!');
  2996. }
  2997. if (pt === 'share') {
  2998. if (selectList.length > 20) {
  2999. return message.error('提示:单次最多可勾选 20 个文件!');
  3000. }
  3001. try {
  3002. let authorization = `${base.getStorage('token').token_type} ${base.getStorage('token').access_token}`;
  3003. let xShareToken = base.getStorage('shareToken').share_token;
  3004.  
  3005. for (let i = 0; i < selectList.length; i++) {
  3006. let res = await base.post(pan.pcs[0], {
  3007. expire_sec: 600,
  3008. file_id: selectList[i].fileId,
  3009. share_id: selectList[i].shareId
  3010. }, {
  3011. authorization,
  3012. "content-type": "application/json;charset=utf-8",
  3013. "x-share-token": xShareToken
  3014. });
  3015. if (res.download_url) {
  3016. selectList[i].downloadUrl = res.download_url;
  3017. }
  3018. }
  3019. } catch (e) {
  3020. return message.error('提示:请先登录(不可用)网盘!');
  3021. }
  3022. }
  3023. let html = this.generateDom(selectList);
  3024. this.showMainDialog(pan[mode][0], html, pan[mode][1]);
  3025. },
  3026.  
  3027. generateDom(list) {
  3028. let content = '<div class="pl-main">';
  3029. let alinkAllText = '';
  3030. list.forEach((v, i) => {
  3031. if (v.type === 'folder') return;
  3032. let filename = v.name;
  3033. let fid = v.fileId;
  3034. let did = v.driveId;
  3035. let size = base.sizeFormat(v.size);
  3036. let dlink = v.downloadUrl || v.url;
  3037. if (mode === 'api') {
  3038. content += `<div class="pl-item">
  3039. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  3040. <a class="pl-item-link listener-link-api" data-did="${did}" data-fid="${fid}" data-filename="${filename}" data-link="${dlink}" data-index="${i}">${dlink}</a>
  3041. </div>`;
  3042. }
  3043. if (mode === 'aria') {
  3044. let alink = this.convertLinkToAria(dlink, filename, navigator.userAgent);
  3045. alinkAllText += alink + '\r\n';
  3046. content += `<div class="pl-item">
  3047. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  3048. <a class="pl-item-link listener-link-aria" href="${alink}" title="点击复制aria2c链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  3049. }
  3050. if (mode === 'rpc') {
  3051. content += `<div class="pl-item">
  3052. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  3053. <button class="pl-item-link listener-link-rpc pl-btn-primary pl-btn-info" data-filename="${filename}" data-link="${dlink}"><em class="icon icon-device"></em><span style="margin-left: 5px;">推送到 RPC 下载器</span></button></div>`;
  3054. }
  3055. if (mode === 'curl') {
  3056. let alink = this.convertLinkToCurl(dlink, filename, navigator.userAgent);
  3057. alinkAllText += alink + '\r\n';
  3058. content += `<div class="pl-item">
  3059. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  3060. <a class="pl-item-link listener-link-aria" href="${alink}" title="点击复制curl链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  3061. }
  3062. if (mode === 'bc') {
  3063. let alink = this.convertLinkToBC(dlink, filename, navigator.userAgent);
  3064. content += `<div class="pl-item">
  3065. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  3066. <a class="pl-item-link" href="${decodeURIComponent(alink)}" title="点击用比特彗星下载" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  3067. }
  3068. });
  3069. content += '</div>';
  3070. if (mode === 'aria')
  3071. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button></div>`;
  3072. if (mode === 'rpc') {
  3073. let rpc = base.getValue('setting_rpc_domain') + ':' + base.getValue('setting_rpc_port') + base.getValue('setting_rpc_path');
  3074. content += `<div class="pl-extra"><button class="pl-btn-primary listener-send-rpc">发送全部链接</button><button title="${rpc}" class="pl-btn-primary pl-btn-warning listener-open-setting" style="margin-left: 10px">设置 RPC 参数(当前为:${rpc})</button><button class="pl-btn-primary pl-btn-success listener-rpc-task" style="margin-left: 10px;display: none">查看下载任务</button></div>`;
  3075. }
  3076. if (mode === 'curl')
  3077. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button><button class="pl-btn-primary pl-btn-warning listener-open-setting" style="margin-left: 10px;">前往助手设置修改当前终端类型(${terminalType[base.getValue('setting_terminal_type')]})</button></div>`;
  3078. return content;
  3079. },
  3080.  
  3081. async sendLinkToRPC(filename, link) {
  3082. let rpc = {
  3083. domain: base.getValue('setting_rpc_domain'),
  3084. port: base.getValue('setting_rpc_port'),
  3085. path: base.getValue('setting_rpc_path'),
  3086. token: base.getValue('setting_rpc_token'),
  3087. dir: base.getValue('setting_rpc_dir'),
  3088. };
  3089.  
  3090. let url = `${rpc.domain}:${rpc.port}${rpc.path}`;
  3091. let rpcData = {
  3092. id: new Date().getTime(),
  3093. jsonrpc: '2.0',
  3094. method: 'aria2.addUri',
  3095. params: [`token:${rpc.token}`, [link], {
  3096. dir: rpc.dir,
  3097. out: filename,
  3098. header: [`Referer: https://www.aliyundrive.com/`]
  3099. }]
  3100. };
  3101. try {
  3102. let res = await base.post(url, rpcData, {"Referer": "https://www.aliyundrive.com/"}, '');
  3103. if (res.result) return 'success';
  3104. return 'fail';
  3105. } catch (e) {
  3106. return 'fail';
  3107. }
  3108. },
  3109.  
  3110. getSelectedList() {
  3111. try {
  3112. let selectedList = [];
  3113. let reactDom = document.getElementsByClassName(pan.dom.list)[0];
  3114. let reactObj = base.findReact(reactDom, 1);
  3115. let props = reactObj.pendingProps;
  3116. if (props) {
  3117. let fileList = props.dataSource || [];
  3118. let selectedKeys = props.selectedKeys.split(',');
  3119. fileList.forEach((val) => {
  3120. if (selectedKeys.includes(val.fileId)) {
  3121. selectedList.push(val);
  3122. }
  3123. });
  3124. }
  3125. return selectedList;
  3126. } catch (e) {
  3127. return [];
  3128. }
  3129. },
  3130.  
  3131. detectPage() {
  3132. let path = location.pathname;
  3133. if (/^\/(drive)/.test(path)) return 'home';
  3134. if (/^\/(s|share)\//.test(path)) return 'share';
  3135. return '';
  3136. },
  3137.  
  3138. isOnlyFolder() {
  3139. for (let i = 0; i < selectList.length; i++) {
  3140. if (selectList[i].type === 'file') return false;
  3141. }
  3142. return true;
  3143. },
  3144.  
  3145. showMainDialog(title, html, footer) {
  3146. Swal.fire({
  3147. title,
  3148. html,
  3149. footer,
  3150. allowOutsideClick: false,
  3151. showCloseButton: true,
  3152. showConfirmButton: false,
  3153. position: 'top',
  3154. width,
  3155. padding: '15px 20px 5px',
  3156. customClass,
  3157. });
  3158. },
  3159.  
  3160. async initPanLinker() {
  3161. base.initDefaultConfig();
  3162. base.addPanLinkerStyle();
  3163. pt = this.detectPage();
  3164. if (base.getValue('setting_getuser_info') === 'yes') {
  3165. let res = await base.post
  3166. (`https://api.youxiaohou.com/config/ali?ver=${version}&a=${author}`, {}, {}, 'text');
  3167. pan = JSON.parse(base.d(res));
  3168. };
  3169. Object.freeze && Object.freeze(pan);
  3170. pan.num === base.getValue('setting_init_code') ? this.addButton() : this.addInitButton();
  3171. base.createTip();
  3172. base.registerMenuCommand();
  3173. }
  3174. };
  3175.  
  3176. //天翼云
  3177. let tianyi = {
  3178.  
  3179. convertLinkToAria(link, filename, ua) {
  3180. filename = base.fixFilename(filename);
  3181. return encodeURIComponent(`aria2c "${link}" --out "${filename}"`);
  3182. },
  3183.  
  3184. convertLinkToBC(link, filename, ua) {
  3185. let bc = `AA/${encodeURIComponent(filename)}/?url=${encodeURIComponent(link)}ZZ`;
  3186. return encodeURIComponent(`bc://http/${base.e(bc)}`);
  3187. },
  3188.  
  3189. convertLinkToCurl(link, filename, ua) {
  3190. let terminal = base.getValue('setting_terminal_type');
  3191. filename = base.fixFilename(filename);
  3192. return encodeURIComponent(`${terminal !== 'wp' ? 'curl' : 'curl.exe'} -L -C - "${link}" -o "${filename}"`);
  3193. },
  3194.  
  3195. addPageListener() {
  3196. doc.on('click', '.pl-button-mode', (e) => {
  3197. mode = e.target.dataset.mode;
  3198. Swal.showLoading();
  3199. this.getPCSLink();
  3200. });
  3201. doc.on('click', '.listener-link-api', async (e) => {
  3202. e.preventDefault();
  3203. $('#downloadIframe').attr('src', e.currentTarget.dataset.link);
  3204. });
  3205. doc.on('click', '.listener-link-aria, .listener-copy-all', (e) => {
  3206. e.preventDefault();
  3207. base.setClipboard(decodeURIComponent(e.target.dataset.link));
  3208. $(e.target).text('复制成功,快去粘贴吧!').animate({opacity: '0.5'}, "slow");
  3209. });
  3210. doc.on('click', '.listener-link-rpc', async (e) => {
  3211. let target = $(e.currentTarget);
  3212. target.find('.icon').remove();
  3213. target.find('.pl-loading').remove();
  3214. target.prepend(base.createLoading());
  3215. let res = await this.sendLinkToRPC(e.currentTarget.dataset.filename, e.currentTarget.dataset.link);
  3216. if (res === 'success') {
  3217. $('.listener-rpc-task').show();
  3218. target.removeClass('pl-btn-danger').html('发送成功,快去看看吧!').animate({opacity: '0.5'}, "slow");
  3219. } else {
  3220. target.addClass('pl-btn-danger').text('发送失败,请检查您的RPC配置信息!').animate({opacity: '0.5'}, "slow");
  3221. }
  3222. });
  3223. doc.on('click', '.listener-send-rpc', (e) => {
  3224. $('.listener-link-rpc').click();
  3225. $(e.target).text('发送完成,发送结果见上方按钮!').animate({opacity: '0.5'}, "slow");
  3226. });
  3227. doc.on('click', '.listener-open-setting', () => {
  3228. base.showSetting();
  3229. });
  3230. doc.on('click', '.listener-open-updatelog', () => {
  3231. base.showUpdateLog();
  3232. });
  3233. doc.on('click', '.listener-rpc-task', () => {
  3234. let rpc = JSON.stringify({
  3235. domain: base.getValue('setting_rpc_domain'),
  3236. port: base.getValue('setting_rpc_port'),
  3237. }), url = `${pan.d}/?rpc=${base.e(rpc)}#${base.getValue('setting_rpc_token')}`;
  3238. GM_openInTab(url, {active: true});
  3239. });
  3240. },
  3241.  
  3242. addButton() {
  3243. if (!pt) return;
  3244. let $toolWrap;
  3245. let $button = $(`<div class="tianyi-button pl-button">下载助手<ul class="pl-dropdown-menu" style="top: 26px;"><li class="pl-dropdown-menu-item pl-button-mode" data-mode="api">API下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="aria" >Aria下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="rpc">RPC下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="curl">cURL下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="bc" >BC下载</li><li class="pl-dropdown-menu-item pl-button-mode listener-open-setting">助手设置</li><li class="pl-dropdown-menu-item pl-button-mode listener-open-updatelog">更新日志</li></ul></div>`);
  3246. if (pt === 'home') {
  3247. let ins = setInterval(() => {
  3248. $toolWrap = $(pan.btn.home);
  3249. if ($toolWrap.length > 0) {
  3250. $toolWrap.prepend($button);
  3251. clearInterval(ins);
  3252. }
  3253. }, 50);
  3254. }
  3255. if (pt === 'share') {
  3256. let ins = setInterval(() => {
  3257. $toolWrap = $(pan.btn.share);
  3258. if ($toolWrap.length > 0) {
  3259. $toolWrap.prepend($button);
  3260. clearInterval(ins);
  3261. }
  3262. }, 50);
  3263. }
  3264. base.createDownloadIframe();
  3265. this.addPageListener();
  3266. },
  3267.  
  3268. addInitButton() {
  3269. if (!pt) return;
  3270. let $toolWrap;
  3271. let $button = $(`<div class="tianyi-button pl-button-init">下载助手(未点亮)</div>`);
  3272. if (pt === 'home') {
  3273. let ins = setInterval(() => {
  3274. $toolWrap = $(pan.btn.home);
  3275. if ($toolWrap.length > 0) {
  3276. $toolWrap.append($button);
  3277. clearInterval(ins);
  3278. }
  3279. }, 50);
  3280. }
  3281. if (pt === 'share') {
  3282. $button.css({'margin-right': '10px'});
  3283. let ins = setInterval(() => {
  3284. $toolWrap = $(pan.btn.share);
  3285. if ($toolWrap.length > 0) {
  3286. $toolWrap.prepend($button);
  3287. clearInterval(ins);
  3288. }
  3289. }, 50);
  3290. }
  3291. $button.click(() => base.initDialog());
  3292. },
  3293.  
  3294. async getToken() {
  3295. let res = await base.getFinalUrl(pan.pcs[1], {});
  3296. let accessToken = res.match(/accessToken=(\w+)/)?.[1];
  3297. accessToken && base.setStorage('accessToken', accessToken);
  3298. return accessToken;
  3299. },
  3300.  
  3301. async getFileUrlByOnce(item, index, token) {
  3302. try {
  3303. if (item.downloadUrl) return {
  3304. index,
  3305. downloadUrl: item.downloadUrl
  3306. };
  3307. let time = Date.now(),
  3308. fileId = item.fileId,
  3309. o = "AccessToken=" + token + "&Timestamp=" + time + "&fileId=" + fileId,
  3310. url = pan.pcs[2] + '?fileId=' + fileId;
  3311. if (item.shareId) {
  3312. o = "AccessToken=" + token + "&Timestamp=" + time + "&dt=1&fileId=" + fileId + "&shareId=" + item.shareId;
  3313. url += '&dt=1&shareId=' + item.shareId;
  3314. }
  3315. let sign = md5(o).toString();
  3316. let res = await base.get(url, {
  3317. "accept": "application/json;charset=UTF-8",
  3318. "sign-type": 1,
  3319. "accesstoken": token,
  3320. "timestamp": time,
  3321. "signature": sign
  3322. });
  3323. if (res.res_code === 0) {
  3324. return {
  3325. index,
  3326. downloadUrl: res.fileDownloadUrl
  3327. };
  3328. } else if (res.errorCode === 'InvalidSessionKey') {
  3329. return {
  3330. index,
  3331. downloadUrl: '提示:请先登录(不可用)网盘!'
  3332. };
  3333. } else if (res.res_code === 'ShareNotFoundFlatDir') {
  3334. return {
  3335. index,
  3336. downloadUrl: '提示:请先[转存]文件,👉前往[我的网盘]中下载!'
  3337. };
  3338. } else {
  3339. return {
  3340. index,
  3341. downloadUrl: '获取下载地址失败,请刷新重试!'
  3342. };
  3343. }
  3344. } catch (e) {
  3345. return {
  3346. index,
  3347. downloadUrl: '获取下载地址失败,请刷新重试!'
  3348. };
  3349. }
  3350. },
  3351.  
  3352. async getPCSLink() {
  3353. selectList = this.getSelectedList();
  3354. if (selectList.length === 0) {
  3355. return message.error('提示:请先勾选要下载的文件!');
  3356. }
  3357. if (this.isOnlyFolder()) {
  3358. return message.error('提示:请打开文件夹后勾选文件!');
  3359. }
  3360. let token = base.getStorage('accessToken') || await this.getToken();
  3361. if (!token) {
  3362. return message.error('提示:请先登录(不可用)网盘!');
  3363. }
  3364. let queue = [];
  3365. selectList.forEach((item, index) => {
  3366. queue.push(this.getFileUrlByOnce(item, index, token));
  3367. });
  3368.  
  3369. const res = await Promise.all(queue);
  3370. res.forEach(val => {
  3371. selectList[val.index].downloadUrl = val.downloadUrl;
  3372. });
  3373.  
  3374. let html = this.generateDom(selectList);
  3375. this.showMainDialog(pan[mode][0], html, pan[mode][1]);
  3376. },
  3377.  
  3378. generateDom(list) {
  3379. let content = '<div class="pl-main">';
  3380. let alinkAllText = '';
  3381. list.forEach((v, i) => {
  3382. if (v.isFolder) return;
  3383. let filename = v.fileName;
  3384. let size = base.sizeFormat(v.size);
  3385. let dlink = v.downloadUrl;
  3386. if (mode === 'api') {
  3387. content += `<div class="pl-item">
  3388. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  3389. <a class="pl-item-link listener-link-api" data-filename="${filename}" data-link="${dlink}" data-index="${i}">${dlink}</a>
  3390. </div>`;
  3391. }
  3392. if (mode === 'aria') {
  3393. let alink = this.convertLinkToAria(dlink, filename, navigator.userAgent);
  3394. alinkAllText += alink + '\r\n';
  3395. content += `<div class="pl-item">
  3396. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  3397. <a class="pl-item-link listener-link-aria" href="${alink}" title="点击复制aria2c链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  3398. }
  3399. if (mode === 'rpc') {
  3400. content += `<div class="pl-item">
  3401. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  3402. <button class="pl-item-link listener-link-rpc pl-btn-primary pl-btn-info" data-filename="${filename}" data-link="${dlink}"><em class="icon icon-device"></em><span style="margin-left: 5px;">推送到 RPC 下载器</span></button></div>`;
  3403. }
  3404. if (mode === 'curl') {
  3405. let alink = this.convertLinkToCurl(dlink, filename, navigator.userAgent);
  3406. alinkAllText += alink + '\r\n';
  3407. content += `<div class="pl-item">
  3408. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  3409. <a class="pl-item-link listener-link-aria" href="${alink}" title="点击复制curl链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  3410. }
  3411. if (mode === 'bc') {
  3412. let alink = this.convertLinkToBC(dlink, filename, navigator.userAgent);
  3413. content += `<div class="pl-item">
  3414. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  3415. <a class="pl-item-link" href="${decodeURIComponent(alink)}" title="点击用比特彗星下载" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  3416. }
  3417. });
  3418. content += '</div>';
  3419. if (mode === 'aria')
  3420. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button></div>`;
  3421. if (mode === 'rpc') {
  3422. let rpc = base.getValue('setting_rpc_domain') + ':' + base.getValue('setting_rpc_port') + base.getValue('setting_rpc_path');
  3423. content += `<div class="pl-extra"><button class="pl-btn-primary listener-send-rpc">发送全部链接</button><button title="${rpc}" class="pl-btn-primary pl-btn-warning listener-open-setting" style="margin-left: 10px">设置 RPC 参数(当前为:${rpc})</button><button class="pl-btn-primary pl-btn-success listener-rpc-task" style="margin-left: 10px;display: none">查看下载任务</button></div>`;
  3424. }
  3425. if (mode === 'curl')
  3426. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button><button class="pl-btn-primary pl-btn-warning listener-open-setting" style="margin-left: 10px;">设置终端类型(当前为:${terminalType[base.getValue('setting_terminal_type')]})</button></div>`;
  3427. return content;
  3428. },
  3429.  
  3430. async sendLinkToRPC(filename, link) {
  3431. let rpc = {
  3432. domain: base.getValue('setting_rpc_domain'),
  3433. port: base.getValue('setting_rpc_port'),
  3434. path: base.getValue('setting_rpc_path'),
  3435. token: base.getValue('setting_rpc_token'),
  3436. dir: base.getValue('setting_rpc_dir'),
  3437. };
  3438.  
  3439. let url = `${rpc.domain}:${rpc.port}${rpc.path}`;
  3440. let rpcData = {
  3441. id: new Date().getTime(),
  3442. jsonrpc: '2.0',
  3443. method: 'aria2.addUri',
  3444. params: [`token:${rpc.token}`, [link], {
  3445. dir: rpc.dir,
  3446. out: filename,
  3447. header: []
  3448. }]
  3449. };
  3450. try {
  3451. let res = await base.post(url, rpcData, {}, '');
  3452. if (res.result) return 'success';
  3453. return 'fail';
  3454. } catch (e) {
  3455. return 'fail';
  3456. }
  3457. },
  3458.  
  3459. getSelectedList() {
  3460. try {
  3461. return document.querySelector(".c-file-list").__vue__.selectedList;
  3462. } catch (e) {
  3463. return [document.querySelector(".info-detail").__vue__.fileDetail];
  3464. }
  3465. },
  3466.  
  3467. detectPage() {
  3468. let path = location.pathname;
  3469. if (/^\/web\/main/.test(path)) return 'home';
  3470. if (/^\/web\/share/.test(path)) return 'share';
  3471. return '';
  3472. },
  3473.  
  3474. isOnlyFolder() {
  3475. for (let i = 0; i < selectList.length; i++) {
  3476. if (!selectList[i].isFolder) return false;
  3477. }
  3478. return true;
  3479. },
  3480.  
  3481. showMainDialog(title, html, footer) {
  3482. Swal.fire({
  3483. title,
  3484. html,
  3485. footer,
  3486. allowOutsideClick: false,
  3487. showCloseButton: true,
  3488. showConfirmButton: false,
  3489. position: 'top',
  3490. width,
  3491. padding: '15px 20px 5px',
  3492. customClass,
  3493. });
  3494. },
  3495.  
  3496. async initPanLinker() {
  3497. base.initDefaultConfig();
  3498. base.addPanLinkerStyle();
  3499. pt = this.detectPage();
  3500. if (base.getValue('setting_getuser_info') === 'yes') {
  3501. let res = await base.post
  3502. (`https://api.youxiaohou.com/config/tianyi?ver=${version}&a=${author}`, {}, {}, 'text');
  3503. pan = JSON.parse(base.d(res));
  3504. };
  3505. Object.freeze && Object.freeze(pan);
  3506. pan.num === base.getValue('setting_init_code') ? this.addButton() : this.addInitButton();
  3507. this.getToken();
  3508. base.createTip();
  3509. base.registerMenuCommand();
  3510. }
  3511. };
  3512.  
  3513. //迅雷云盘
  3514. let xunlei = {
  3515.  
  3516. convertLinkToAria(link, filename, ua) {
  3517. filename = base.fixFilename(filename);
  3518. return encodeURIComponent(`aria2c "${link}" --out "${filename}"`);
  3519. },
  3520.  
  3521. convertLinkToBC(link, filename, ua) {
  3522. let bc = `AA/${encodeURIComponent(filename)}/?url=${encodeURIComponent(link)}ZZ`;
  3523. return encodeURIComponent(`bc://http/${base.e(bc)}`);
  3524. },
  3525.  
  3526. convertLinkToCurl(link, filename, ua) {
  3527. let terminal = base.getValue('setting_terminal_type');
  3528. filename = base.fixFilename(filename);
  3529. return encodeURIComponent(`${terminal !== 'wp' ? 'curl' : 'curl.exe'} -L -C - "${link}" -o "${filename}"`);
  3530. },
  3531.  
  3532. addPageListener() {
  3533. doc.on('click', '.pl-button-mode', (e) => {
  3534. mode = e.target.dataset.mode;
  3535. Swal.showLoading();
  3536. this.getPCSLink();
  3537. });
  3538. doc.on('click', '.listener-link-api', async (e) => {
  3539. e.preventDefault();
  3540. $('#downloadIframe').attr('src', e.currentTarget.dataset.link);
  3541. });
  3542. doc.on('click', '.listener-link-api-btn', async (e) => {
  3543. base.setClipboard(e.target.dataset.filename);
  3544. $(e.target).text('复制成功').animate({opacity: '0.5'}, "slow");
  3545. });
  3546. doc.on('click', '.listener-link-bc-btn', async (e) => {
  3547. let mirror = base.getMirrorList(e.target.dataset.dlink, pan.mirror);
  3548. base.setClipboard(mirror);
  3549. $(e.target).text('复制成功').animate({opacity: '0.5'}, "slow");
  3550. });
  3551. doc.on('click', '.listener-link-aria, .listener-copy-all', (e) => {
  3552. e.preventDefault();
  3553. base.setClipboard(decodeURIComponent(e.target.dataset.link));
  3554. $(e.target).text('复制成功,快去粘贴吧!').animate({opacity: '0.5'}, "slow");
  3555. });
  3556. doc.on('click', '.listener-link-rpc', async (e) => {
  3557. let target = $(e.currentTarget);
  3558. target.find('.icon').remove();
  3559. target.find('.pl-loading').remove();
  3560. target.prepend(base.createLoading());
  3561. let res = await this.sendLinkToRPC(e.currentTarget.dataset.filename, e.currentTarget.dataset.link);
  3562. if (res === 'success') {
  3563. $('.listener-rpc-task').show();
  3564. target.removeClass('pl-btn-danger').html('发送成功,快去看看吧!').animate({opacity: '0.5'}, "slow");
  3565. } else {
  3566. target.addClass('pl-btn-danger').text('发送失败,请检查您的RPC配置信息!').animate({opacity: '0.5'}, "slow");
  3567. }
  3568. });
  3569. doc.on('click', '.listener-send-rpc', (e) => {
  3570. $('.listener-link-rpc').click();
  3571. $(e.target).text('发送完成,发送结果见上方按钮!').animate({opacity: '0.5'}, "slow");
  3572. });
  3573. doc.on('click', '.listener-open-setting', () => {
  3574. base.showSetting();
  3575. });
  3576. doc.on('click', '.listener-open-updatelog', () => {
  3577. base.showUpdateLog();
  3578. });
  3579. doc.on('click', '.listener-rpc-task', () => {
  3580. let rpc = JSON.stringify({
  3581. domain: base.getValue('setting_rpc_domain'),
  3582. port: base.getValue('setting_rpc_port'),
  3583. }), url = `${pan.d}/?rpc=${base.e(rpc)}#${base.getValue('setting_rpc_token')}`;
  3584. GM_openInTab(url, {active: true});
  3585. });
  3586. },
  3587.  
  3588. addButton() {
  3589. if (!pt) return;
  3590. let $toolWrap;
  3591. let $button = $(`<div class="xunlei-button pl-button"><i class="xlpfont xlp-download"></i><span style="font-size: 13px;margin-left: 6px;">下载助手</span><ul class="pl-dropdown-menu" style="top: 34px;"><li class="pl-dropdown-menu-item pl-button-mode" data-mode="api">API下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="aria" >Aria下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="rpc">RPC下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="curl">cURL下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="bc" >BC下载</li><li class="pl-dropdown-menu-item pl-button-mode listener-open-setting">助手设置</li><li class="pl-dropdown-menu-item pl-button-mode listener-open-updatelog">更新日志</li></ul></div>`);
  3592. if (pt === 'home') {
  3593. let ins = setInterval(() => {
  3594. $toolWrap = $(pan.btn.home);
  3595. if ($toolWrap.length > 0) {
  3596. $toolWrap.prepend($button);
  3597. clearInterval(ins);
  3598. }
  3599. }, 50);
  3600. }
  3601. if (pt === 'share') {
  3602. $button.css({'margin-right': '10px'});
  3603. let ins = setInterval(() => {
  3604. $toolWrap = $(pan.btn.share);
  3605. if ($toolWrap.length > 0) {
  3606. $toolWrap.prepend($button);
  3607. clearInterval(ins);
  3608. }
  3609. }, 50);
  3610. }
  3611. base.createDownloadIframe();
  3612. this.addPageListener();
  3613. },
  3614.  
  3615. addInitButton() {
  3616. if (!pt) return;
  3617. let $toolWrap;
  3618. let $button = $(`<div class="xunlei-button pl-button-init"><i class="xlpfont xlp-download"></i><span style="font-size: 13px;margin-left: 6px;">下载助手(未点亮)</span></div>`);
  3619. if (pt === 'home') {
  3620. let ins = setInterval(() => {
  3621. $toolWrap = $(pan.btn.home);
  3622. if ($toolWrap.length > 0) {
  3623. $toolWrap.append($button);
  3624. clearInterval(ins);
  3625. }
  3626. }, 50);
  3627. }
  3628. if (pt === 'share') {
  3629. $button.css({'margin-right': '10px'});
  3630. let ins = setInterval(() => {
  3631. $toolWrap = $(pan.btn.share);
  3632. if ($toolWrap.length > 0) {
  3633. $toolWrap.prepend($button);
  3634. clearInterval(ins);
  3635. }
  3636. }, 50);
  3637. }
  3638. $button.click(() => base.initDialog());
  3639. },
  3640.  
  3641. getToken() {
  3642. let credentials = {}, captcha = {};
  3643. for (let i = 0; i < localStorage.length; i++) {
  3644. if (/^credentials_/.test(localStorage.key(i))) {
  3645. credentials = base.getStorage(localStorage.key(i));
  3646. base.setStorage('');
  3647. }
  3648. if (/^captcha_[\w]{16}/.test(localStorage.key(i))) {
  3649. captcha = base.getStorage(localStorage.key(i));
  3650. }
  3651. }
  3652. let deviceid = /(\w{32})/.exec(base.getStorage('deviceid').split(','))[0];
  3653. let token = {
  3654. credentials,
  3655. captcha,
  3656. deviceid
  3657. };
  3658. return token;
  3659. },
  3660.  
  3661. async getFileUrlByOnce(item, index, token) {
  3662. try {
  3663. if (item.downloadUrl) return {
  3664. index,
  3665. downloadUrl: item.downloadUrl
  3666. };
  3667. let res = await base.get(pan.pcs[0] + item.id, {
  3668. 'Authorization': `${token.credentials.token_type} ${token.credentials.access_token}`,
  3669. 'content-type': "application/json",
  3670. 'x-captcha-token': token.captcha.token,
  3671. 'x-device-id': token.deviceid,
  3672. });
  3673. if (res.web_content_link) {
  3674. return {
  3675. index,
  3676. downloadUrl: res.web_content_link
  3677. };
  3678. } else {
  3679. return {
  3680. index,
  3681. downloadUrl: '获取下载地址失败,请刷新重试!'
  3682. };
  3683. }
  3684. } catch (e) {
  3685. return message.error('提示:请先登录(不可用)网盘后刷新页面!');
  3686. }
  3687. },
  3688.  
  3689. async getPCSLink() {
  3690. selectList = this.getSelectedList();
  3691. if (selectList.length === 0) {
  3692. return message.error('提示:请先勾选要下载的文件!');
  3693. }
  3694. if (this.isOnlyFolder()) {
  3695. return message.error('提示:请打开文件夹后勾选文件!');
  3696. }
  3697. if (pt === 'home') {
  3698. let queue = [];
  3699. let token = this.getToken();
  3700. selectList.forEach((item, index) => {
  3701. queue.push(this.getFileUrlByOnce(item, index, token));
  3702. });
  3703. const res = await Promise.all(queue);
  3704. res.forEach(val => {
  3705. selectList[val.index].downloadUrl = val.downloadUrl;
  3706. });
  3707. } else {
  3708. return message.error('提示:请保存到自己网盘后去网盘主页下载!');
  3709. }
  3710. let html = this.generateDom(selectList);
  3711. this.showMainDialog(pan[mode][0], html, pan[mode][1]);
  3712.  
  3713. },
  3714.  
  3715. generateDom(list) {
  3716. let content = '<div class="pl-main">';
  3717. let alinkAllText = '';
  3718. list.forEach((v, i) => {
  3719. if (v.kind === 'drive#folder') return;
  3720. let filename = v.name;
  3721. let size = base.sizeFormat(+v.size);
  3722. let dlink = v.downloadUrl;
  3723. if (mode === 'api') {
  3724. content += `<div class="pl-item">
  3725. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  3726. <a class="pl-item-link listener-link-api" data-filename="${filename}" data-link="${dlink}" data-index="${i}">${dlink}</a>
  3727. <div class="pl-item-btn listener-link-api-btn" data-filename="${filename}">复制文件名</div>
  3728. </div>`;
  3729. }
  3730. if (mode === 'aria') {
  3731. let alink = this.convertLinkToAria(dlink, filename, navigator.userAgent);
  3732. alinkAllText += alink + '\r\n';
  3733. content += `<div class="pl-item">
  3734. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  3735. <a class="pl-item-link listener-link-aria" href="${alink}" title="点击复制aria2c链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  3736. }
  3737. if (mode === 'rpc') {
  3738. content += `<div class="pl-item">
  3739. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  3740. <button class="pl-item-link listener-link-rpc pl-btn-primary pl-btn-info" data-filename="${filename}" data-link="${dlink}"><em class="icon icon-device"></em><span style="margin-left: 5px;">推送到 RPC 下载器</span></button></div>`;
  3741. }
  3742. if (mode === 'curl') {
  3743. let alink = this.convertLinkToCurl(dlink, filename, navigator.userAgent);
  3744. alinkAllText += alink + '\r\n';
  3745. content += `<div class="pl-item">
  3746. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  3747. <a class="pl-item-link listener-link-aria" href="${alink}" title="点击复制curl链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  3748. }
  3749. if (mode === 'bc') {
  3750. let alink = this.convertLinkToBC(dlink, filename, navigator.userAgent);
  3751. content += `<div class="pl-item">
  3752. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  3753. <a class="pl-item-link" href="${decodeURIComponent(alink)}" title="点击用比特彗星下载" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a>
  3754. <div class="pl-item-btn listener-link-bc-btn" data-dlink="${dlink}">复制镜像地址</div>
  3755. </div>`;
  3756. }
  3757. });
  3758. content += '</div>';
  3759. if (mode === 'aria')
  3760. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button></div>`;
  3761. if (mode === 'rpc') {
  3762. let rpc = base.getValue('setting_rpc_domain') + ':' + base.getValue('setting_rpc_port') + base.getValue('setting_rpc_path');
  3763. content += `<div class="pl-extra"><button class="pl-btn-primary listener-send-rpc">发送全部链接</button><button title="${rpc}" class="pl-btn-primary pl-btn-warning listener-open-setting" style="margin-left: 10px">设置 RPC 参数(当前为:${rpc})</button><button class="pl-btn-primary pl-btn-success listener-rpc-task" style="margin-left: 10px;display: none">查看下载任务</button></div>`;
  3764. }
  3765. if (mode === 'curl')
  3766. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button><button class="pl-btn-primary pl-btn-warning listener-open-setting" style="margin-left: 10px;">设置终端类型(当前为:${terminalType[base.getValue('setting_terminal_type')]})</button></div>`;
  3767. return content;
  3768. },
  3769.  
  3770. async sendLinkToRPC(filename, link) {
  3771. let rpc = {
  3772. domain: base.getValue('setting_rpc_domain'),
  3773. port: base.getValue('setting_rpc_port'),
  3774. path: base.getValue('setting_rpc_path'),
  3775. token: base.getValue('setting_rpc_token'),
  3776. dir: base.getValue('setting_rpc_dir'),
  3777. };
  3778.  
  3779. let url = `${rpc.domain}:${rpc.port}${rpc.path}`;
  3780. let rpcData = {
  3781. id: new Date().getTime(),
  3782. jsonrpc: '2.0',
  3783. method: 'aria2.addUri',
  3784. params: [`token:${rpc.token}`, [link], {
  3785. dir: rpc.dir,
  3786. out: filename,
  3787. header: []
  3788. }]
  3789. };
  3790. try {
  3791. let res = await base.post(url, rpcData, {}, '');
  3792. if (res.result) return 'success';
  3793. return 'fail';
  3794. } catch (e) {
  3795. return 'fail';
  3796. }
  3797. },
  3798.  
  3799. getSelectedList() {
  3800. try {
  3801. let doms = document.querySelectorAll('.pan-list-item');
  3802. let selectedList = [];
  3803. for (let dom of doms) {
  3804. let domVue = dom.__vue__;
  3805. if (domVue.selected.includes(domVue.info.id)) {
  3806. selectedList.push(domVue.info);
  3807. }
  3808. }
  3809. return selectedList;
  3810. } catch (e) {
  3811. return [];
  3812. }
  3813. },
  3814.  
  3815. detectPage() {
  3816. let path = location.pathname;
  3817. if (/^\/$/.test(path)) return 'home';
  3818. if (/^\/(s|share)\//.test(path)) return 'share';
  3819. return '';
  3820. },
  3821.  
  3822. isOnlyFolder() {
  3823. for (let i = 0; i < selectList.length; i++) {
  3824. if (selectList[i].kind === 'drive#file') return false;
  3825. }
  3826. return true;
  3827. },
  3828.  
  3829. showMainDialog(title, html, footer) {
  3830. Swal.fire({
  3831. title,
  3832. html,
  3833. footer,
  3834. allowOutsideClick: false,
  3835. showCloseButton: true,
  3836. showConfirmButton: false,
  3837. position: 'top',
  3838. width,
  3839. padding: '15px 20px 5px',
  3840. customClass,
  3841. });
  3842. },
  3843.  
  3844. async initPanLinker() {
  3845. base.initDefaultConfig();
  3846. base.addPanLinkerStyle();
  3847. pt = this.detectPage();
  3848. if (base.getValue('setting_getuser_info') === 'yes') {
  3849. let res = await base.post
  3850. (`https://api.youxiaohou.com/config/xunlei?ver=${version}&a=${author}`, {}, {}, 'text');
  3851. pan = JSON.parse(base.d(res));
  3852. };
  3853. Object.freeze && Object.freeze(pan);
  3854. pan.num === base.getValue('setting_init_code') ? this.addButton() : this.addInitButton();
  3855. base.createTip();
  3856. base.registerMenuCommand();
  3857. }
  3858. };
  3859.  
  3860. //夸克网盘
  3861. let quark = {
  3862.  
  3863. convertLinkToAria(link, filename, ua) {
  3864. filename = base.fixFilename(filename);
  3865. return encodeURIComponent(`aria2c "${link}" --out "${filename}" --header "Cookie: ${document.cookie}"`);
  3866. },
  3867.  
  3868. convertLinkToBC(link, filename, ua) {
  3869. let bc = `AA/${encodeURIComponent(filename)}/?url=${encodeURIComponent(link)}&cookie=${encodeURIComponent(document.cookie)}ZZ`;
  3870. return encodeURIComponent(`bc://http/${base.e(bc)}`);
  3871. },
  3872.  
  3873. convertLinkToCurl(link, filename, ua) {
  3874. let terminal = base.getValue('setting_terminal_type');
  3875. filename = base.fixFilename(filename);
  3876. return encodeURIComponent(`${terminal !== 'wp' ? 'curl' : 'curl.exe'} -L -C - "${link}" -o "${filename}" -b "${document.cookie}"`);
  3877. },
  3878.  
  3879. addPageListener() {
  3880. window.addEventListener('hashchange', async (e) => {
  3881. let home = 'https://pan.quark.cn/list#/', all = 'https://pan.quark.cn/list#/list/all';
  3882. if (e.oldURL === home && e.newURL === all) return;
  3883. await base.sleep(150);
  3884. if ($('.quark-button').length > 0) return;
  3885. pan.num === base.getValue('setting_init_code') ? this.addButton() : this.addInitButton();
  3886. });
  3887. doc.on('click', '.pl-button-mode', (e) => {
  3888. mode = e.target.dataset.mode;
  3889. Swal.showLoading();
  3890. this.getPCSLink();
  3891. });
  3892. doc.on('click', '.listener-link-api', async (e) => {
  3893. e.preventDefault();
  3894. $('#downloadIframe').attr('src', e.currentTarget.dataset.link);
  3895. });
  3896. doc.on('click', '.listener-link-aria, .listener-copy-all', (e) => {
  3897. e.preventDefault();
  3898. base.setClipboard(decodeURIComponent(e.target.dataset.link));
  3899. $(e.target).text('复制成功,快去粘贴吧!').animate({opacity: '0.5'}, "slow");
  3900. });
  3901. doc.on('click', '.listener-link-rpc', async (e) => {
  3902. let target = $(e.currentTarget);
  3903. target.find('.icon').remove();
  3904. target.find('.pl-loading').remove();
  3905. target.prepend(base.createLoading());
  3906. let res = await this.sendLinkToRPC(e.currentTarget.dataset.filename, e.currentTarget.dataset.link);
  3907. if (res === 'success') {
  3908. $('.listener-rpc-task').show();
  3909. target.removeClass('pl-btn-danger').html('发送成功,快去看看吧!').animate({opacity: '0.5'}, "slow");
  3910. } else {
  3911. target.addClass('pl-btn-danger').text('发送失败,请检查您的RPC配置信息!').animate({opacity: '0.5'}, "slow");
  3912. }
  3913. });
  3914. doc.on('click', '.listener-send-rpc', (e) => {
  3915. $('.listener-link-rpc').click();
  3916. $(e.target).text('发送完成,发送结果见上方按钮!').animate({opacity: '0.5'}, "slow");
  3917. });
  3918. doc.on('click', '.listener-open-setting', () => {
  3919. base.showSetting();
  3920. });
  3921. doc.on('click', '.listener-open-updatelog', () => {
  3922. base.showUpdateLog();
  3923. });
  3924. doc.on('click', '.listener-rpc-task', () => {
  3925. let rpc = JSON.stringify({
  3926. domain: base.getValue('setting_rpc_domain'),
  3927. port: base.getValue('setting_rpc_port'),
  3928. }), url = `${pan.d}/?rpc=${base.e(rpc)}#${base.getValue('setting_rpc_token')}`;
  3929. GM_openInTab(url, {active: true});
  3930. });
  3931. },
  3932.  
  3933. addButton() {
  3934. if ($("#quark-button")){
  3935. $("#quark-button").remove();
  3936. };
  3937. if (!pt) return;
  3938. let $toolWrap;
  3939. let $button = $(`<div id="quark-button" class="file-info_r quark-button pl-button"><svg width="22" height="22" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd" stroke="#FFFFFF" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12l2 2 2-2z"/><path d="M14 8h1.553c.85 0 1.16.093 1.47.267.311.174.556.43.722.756.166.326.255.65.255 1.54v4.873c0 .892-.089 1.215-.255 1.54-.166.327-.41.583-.722.757-.31.174-.62.267-1.47.267H6.447c-.85 0-1.16-.093-1.47-.267a1.778 1.778 0 01-.722-.756c-.166-.326-.255-.65-.255-1.54v-4.873c0-.892.089-1.215.255-1.54.166-.327.41-.583.722-.757.31-.174.62-.267 1.47-.267H11"/><path stroke-linecap="round" stroke-linejoin="round" d="M11 3v10"/></g></svg>下载助手<ul class="pl-dropdown-menu"><li class="pl-dropdown-menu-item pl-button-mode" data-mode="api">API下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="aria" >Aria下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="rpc">RPC下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="curl">cURL下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="bc" >BC下载</li><li class="pl-dropdown-menu-item pl-button-mode listener-open-setting">助手设置</li><li class="pl-dropdown-menu-item pl-button-mode listener-open-updatelog">更新日志</li></ul></div>`);
  3940. $button.css({"margin-right":"10px","background-color":color});
  3941. if (pt === 'home') {
  3942. let ins = setInterval(() => {
  3943. $toolWrap = $(pan.btn.home);
  3944. if ($toolWrap.length > 0) {
  3945. $toolWrap.prepend($button);
  3946. clearInterval(ins);
  3947. }
  3948. }, 50);
  3949. }
  3950. if (pt === 'share') {
  3951. $button.css({"margin-right":"10px","background-color":color});
  3952. let ins = setInterval(() => {
  3953. $toolWrap = $(pan.btn.share);
  3954. if ($toolWrap.length > 0) {
  3955. $toolWrap.prepend($button);
  3956. clearInterval(ins);
  3957. }
  3958. }, 50);
  3959. }
  3960. },
  3961.  
  3962. addInitButton() {
  3963. $("#pl-button-init").remove();
  3964. if (!pt) return;
  3965. let $toolWrap;
  3966. let $button = $(`<div id="quark-button" class="file-info_r quark-button pl-button-init"><svg width="22" height="22" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd" stroke="#FFFFFF" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12l2 2 2-2z"/><path d="M14 8h1.553c.85 0 1.16.093 1.47.267.311.174.556.43.722.756.166.326.255.65.255 1.54v4.873c0 .892-.089 1.215-.255 1.54-.166.327-.41.583-.722.757-.31.174-.62.267-1.47.267H6.447c-.85 0-1.16-.093-1.47-.267a1.778 1.778 0 01-.722-.756c-.166-.326-.255-.65-.255-1.54v-4.873c0-.892.089-1.215.255-1.54.166-.327.41-.583.722-.757.31-.174.62-.267 1.47-.267H11"/><path stroke-linecap="round" stroke-linejoin="round" d="M11 3v10"/></g></svg>下载助手(未点亮)</div>`);
  3967. $button.css({"margin-right":"10px","background-color":color});
  3968. if (pt === 'home') {
  3969. let ins = setInterval(() => {
  3970. $toolWrap = $(pan.btn.home);
  3971. if ($toolWrap.length > 0) {
  3972. $toolWrap.prepend($button);
  3973. clearInterval(ins);
  3974. }
  3975. }, 50);
  3976. }
  3977. if (pt === 'share') {
  3978. $button.css({'margin-right': '10px','width': '160px',"background-color":color});
  3979. let ins = setInterval(() => {
  3980. $toolWrap = $(pan.btn.share);
  3981. if ($toolWrap.length > 0) {
  3982. $toolWrap.prepend($button);
  3983. clearInterval(ins);
  3984. }
  3985. }, 50);
  3986. }
  3987. $button.click(() => base.initDialog());
  3988. },
  3989.  
  3990. async getPCSLink() {
  3991. selectList = this.getSelectedList();
  3992. if (selectList.length === 0) {
  3993. return message.error('提示:请先勾选要下载的文件!');
  3994. }
  3995. if (this.isOnlyFolder()) {
  3996. return message.error('提示:请打开文件夹后勾选文件!');
  3997. }
  3998. let fids = [];
  3999. selectList.forEach(val => {
  4000. fids.push(val.fid);
  4001. });
  4002. if (pt === 'home') {
  4003. let res = await base.post(pan.pcs[0], {
  4004. "fids": fids
  4005. }, {"content-type": "application/json;charset=utf-8", "user-agent": pan.ua});
  4006. if (res.code === 31001) {
  4007. return message.error('提示:请先登录(不可用)网盘!');
  4008. }
  4009. if (res.code !== 0) {
  4010. return message.error('提示:获取链接失败!');
  4011. }
  4012. let html = this.generateDom(res.data);
  4013. this.showMainDialog(pan[mode][0], html, pan[mode][1]);
  4014. } else {
  4015. message.error('提示:请保存到自己网盘后去网盘主页下载!');
  4016. await base.sleep(1000);
  4017. document.querySelector('.file-info_r').click();
  4018. return;
  4019. }
  4020. },
  4021.  
  4022. generateDom(list) {
  4023. let content = '<div class="pl-main">';
  4024. let alinkAllText = '';
  4025. list.forEach((v, i) => {
  4026. if (v.file === false) return;
  4027. let filename = v.file_name;
  4028. let fid = v.fid;
  4029. let size = base.sizeFormat(v.size);
  4030. let dlink = v.download_url;
  4031. if (mode === 'api') {
  4032. content += `<div class="pl-item">
  4033. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  4034. <a class="pl-item-link listener-link-api" data-fid="${fid}" data-filename="${filename}" data-link="${dlink}" data-index="${i}">${dlink}</a>
  4035. </div>`;
  4036. }
  4037. if (mode === 'aria') {
  4038. let alink = this.convertLinkToAria(dlink, filename, navigator.userAgent);
  4039. alinkAllText += alink + '\r\n';
  4040. content += `<div class="pl-item">
  4041. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  4042. <a class="pl-item-link listener-link-aria" href="${alink}" title="点击复制aria2c链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  4043. }
  4044. if (mode === 'rpc') {
  4045. content += `<div class="pl-item">
  4046. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  4047. <button class="pl-item-link listener-link-rpc pl-btn-primary pl-btn-info" data-filename="${filename}" data-link="${dlink}"><em class="icon icon-device"></em><span style="margin-left: 5px;">推送到 RPC 下载器</span></button></div>`;
  4048. }
  4049. if (mode === 'curl') {
  4050. let alink = this.convertLinkToCurl(dlink, filename, navigator.userAgent);
  4051. alinkAllText += alink + '\r\n';
  4052. content += `<div class="pl-item">
  4053. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  4054. <a class="pl-item-link listener-link-aria" href="${alink}" title="点击复制curl链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  4055. }
  4056. if (mode === 'bc') {
  4057. let alink = this.convertLinkToBC(dlink, filename, navigator.userAgent);
  4058. content += `<div class="pl-item">
  4059. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  4060. <a class="pl-item-link" href="${decodeURIComponent(alink)}" title="点击用比特彗星下载" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  4061. }
  4062. });
  4063. content += '</div>';
  4064. if (mode === 'aria')
  4065. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button></div>`;
  4066. if (mode === 'rpc') {
  4067. let rpc = base.getValue('setting_rpc_domain') + ':' + base.getValue('setting_rpc_port') + base.getValue('setting_rpc_path');
  4068. content += `<div class="pl-extra"><button class="pl-btn-primary listener-send-rpc">发送全部链接</button><button title="${rpc}" class="pl-btn-primary pl-btn-warning listener-open-setting" style="margin-left: 10px">设置 RPC 参数(当前为:${rpc})</button><button class="pl-btn-primary pl-btn-success listener-rpc-task" style="margin-left: 10px;display: none">查看下载任务</button></div>`;
  4069. }
  4070. if (mode === 'curl')
  4071. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button><button class="pl-btn-primary pl-btn-warning listener-open-setting" style="margin-left: 10px;">设置终端类型(当前为:${terminalType[base.getValue('setting_terminal_type')]})</button></div>`;
  4072. return content;
  4073. },
  4074.  
  4075. async sendLinkToRPC(filename, link) {
  4076. let rpc = {
  4077. domain: base.getValue('setting_rpc_domain'),
  4078. port: base.getValue('setting_rpc_port'),
  4079. path: base.getValue('setting_rpc_path'),
  4080. token: base.getValue('setting_rpc_token'),
  4081. dir: base.getValue('setting_rpc_dir'),
  4082. };
  4083.  
  4084. let url = `${rpc.domain}:${rpc.port}${rpc.path}`;
  4085. let rpcData = {
  4086. id: new Date().getTime(),
  4087. jsonrpc: '2.0',
  4088. method: 'aria2.addUri',
  4089. params: [`token:${rpc.token}`, [link], {
  4090. dir: rpc.dir,
  4091. out: filename,
  4092. header: [`Cookie: ${document.cookie}`]
  4093. }]
  4094. };
  4095. try {
  4096. let res = await base.post(url, rpcData, {"Cookie": document.cookie}, '');
  4097. if (res.result) return 'success';
  4098. return 'fail';
  4099. } catch (e) {
  4100. return 'fail';
  4101. }
  4102. },
  4103.  
  4104. getSelectedList() {
  4105. try {
  4106. let selectedList = [];
  4107. let reactDom = document.getElementsByClassName('file-list')[0];
  4108. let reactObj = base.findReact(reactDom);
  4109. let props = reactObj.props;
  4110. if (props) {
  4111. let fileList = props.list || [];
  4112. let selectedKeys = props.selectedRowKeys || [];
  4113. fileList.forEach((val) => {
  4114. if (selectedKeys.includes(val.fid)) {
  4115. selectedList.push(val);
  4116. }
  4117. });
  4118. }
  4119. return selectedList;
  4120. } catch (e) {
  4121. return [];
  4122. }
  4123. },
  4124.  
  4125. detectPage() {
  4126. let path = location.pathname;
  4127. if (/^\/(list)/.test(path)) return 'home';
  4128. if (/^\/(s|share)\//.test(path)) return 'share';
  4129. return '';
  4130. },
  4131.  
  4132. isOnlyFolder() {
  4133. for (let i = 0; i < selectList.length; i++) {
  4134. if (selectList[i].file) return false;
  4135. }
  4136. return true;
  4137. },
  4138.  
  4139. showMainDialog(title, html, footer) {
  4140. Swal.fire({
  4141. title,
  4142. html,
  4143. footer,
  4144. allowOutsideClick: false,
  4145. showCloseButton: true,
  4146. showConfirmButton: false,
  4147. position: 'top',
  4148. width,
  4149. padding: '15px 20px 5px',
  4150. customClass,
  4151. });
  4152. },
  4153.  
  4154. async initPanLinker() {
  4155. base.initDefaultConfig();
  4156. base.addPanLinkerStyle();
  4157. pt = this.detectPage();
  4158. if (base.getValue('setting_getuser_info') === 'yes') {
  4159. let res = await base.post
  4160. (`https://api.youxiaohou.com/config/quark?ver=${version}&a=${author}`, {}, {}, 'text');
  4161. pan = JSON.parse(base.d(res));
  4162. };
  4163. Object.freeze && Object.freeze(pan);
  4164. pan.num === base.getValue('setting_init_code') ? this.addButton() : this.addInitButton();
  4165. this.addPageListener();
  4166. base.createTip();
  4167. base.createDownloadIframe();
  4168. base.registerMenuCommand();
  4169. }
  4170. };
  4171.  
  4172. //中国移动云盘/和彩云
  4173. let yidong = {
  4174.  
  4175. convertLinkToAria(link, filename, ua) {
  4176. filename = base.fixFilename(filename);
  4177. return encodeURIComponent(`aria2c "${link}" --out "${filename}"`);
  4178. },
  4179.  
  4180. convertLinkToBC(link, filename, ua) {
  4181. let bc = `AA/${encodeURIComponent(filename)}/?url=${encodeURIComponent(link)}ZZ`;
  4182. return encodeURIComponent(`bc://http/${base.e(bc)}`);
  4183. },
  4184.  
  4185. convertLinkToCurl(link, filename, ua) {
  4186. let terminal = base.getValue('setting_terminal_type');
  4187. filename = base.fixFilename(filename);
  4188. return encodeURIComponent(`${terminal !== 'wp' ? 'curl' : 'curl.exe'} -L -C - "${link}" -o "${filename}"`);
  4189. },
  4190.  
  4191. addPageListener() {
  4192. doc.on('click', '.pl-button-mode', (e) => {
  4193. mode = e.target.dataset.mode;
  4194. Swal.showLoading();
  4195. this.getPCSLink();
  4196. });
  4197. doc.on('click', '.listener-link-api', async (e) => {
  4198. e.preventDefault();
  4199. $('#downloadIframe').attr('src', e.currentTarget.dataset.link);
  4200. });
  4201. doc.on('click', '.listener-link-aria, .listener-copy-all', (e) => {
  4202. e.preventDefault();
  4203. base.setClipboard(decodeURIComponent(e.target.dataset.link));
  4204. $(e.target).text('复制成功,快去粘贴吧!').animate({opacity: '0.5'}, "slow");
  4205. });
  4206. doc.on('click', '.listener-link-rpc', async (e) => {
  4207. let target = $(e.currentTarget);
  4208. target.find('.icon').remove();
  4209. target.find('.pl-loading').remove();
  4210. target.prepend(base.createLoading());
  4211. let res = await this.sendLinkToRPC(e.currentTarget.dataset.filename, e.currentTarget.dataset.link);
  4212. if (res === 'success') {
  4213. $('.listener-rpc-task').show();
  4214. target.removeClass('pl-btn-danger').html('发送成功,快去看看吧!').animate({opacity: '0.5'}, "slow");
  4215. } else {
  4216. target.addClass('pl-btn-danger').text('发送失败,请检查您的RPC配置信息!').animate({opacity: '0.5'}, "slow");
  4217. }
  4218. });
  4219. doc.on('click', '.listener-send-rpc', (e) => {
  4220. $('.listener-link-rpc').click();
  4221. $(e.target).text('发送完成,发送结果见上方按钮!').animate({opacity: '0.5'}, "slow");
  4222. });
  4223. doc.on('click', '.listener-open-setting', () => {
  4224. base.showSetting();
  4225. });
  4226. doc.on('click', '.listener-open-updatelog', () => {
  4227. base.showUpdateLog();
  4228. });
  4229. doc.on('click', '.listener-rpc-task', () => {
  4230. let rpc = JSON.stringify({
  4231. domain: base.getValue('setting_rpc_domain'),
  4232. port: base.getValue('setting_rpc_port'),
  4233. }), url = `${pan.d}/?rpc=${base.e(rpc)}#${base.getValue('setting_rpc_token')}`;
  4234. GM_openInTab(url, {active: true});
  4235. });
  4236. },
  4237.  
  4238. addButton() {
  4239. if (!pt) return;
  4240. let $toolWrap;
  4241. let $button = $(`<div class="yidong-button pl-button">下载助手<ul class="pl-dropdown-menu" style="top: 36px;"><li class="pl-dropdown-menu-item pl-button-mode" data-mode="api">API下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="aria" >Aria下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="rpc">RPC下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="curl">cURL下载</li><li class="pl-dropdown-menu-item pl-button-mode" data-mode="bc" >BC下载</li><li class="pl-dropdown-menu-item pl-button-mode listener-open-setting">助手设置</li><li class="pl-dropdown-menu-item pl-button-mode listener-open-updatelog">更新日志</li>${pan.code == 200 && version < pan.version ? pan.new : ''}</ul></div>`);
  4242. if (pt === 'home') {
  4243. let ins = setInterval(() => {
  4244. $toolWrap = $(pan.btn.home);
  4245. if ($toolWrap.length > 0) {
  4246. $toolWrap.prepend($button);
  4247. clearInterval(ins);
  4248. }
  4249. }, 50);
  4250. }
  4251. if (pt === 'share') {
  4252. $button.removeClass('yidong-button').addClass('yidong-share-button');
  4253. let ins = setInterval(() => {
  4254. $toolWrap = $(pan.btn.share);
  4255. if ($toolWrap.length > 0) {
  4256. $toolWrap.prepend($button);
  4257. clearInterval(ins);
  4258. }
  4259. }, 50);
  4260. }
  4261. base.createDownloadIframe();
  4262. this.addPageListener();
  4263. },
  4264.  
  4265. addInitButton() {
  4266. if (!pt) return;
  4267. let $toolWrap;
  4268. let $button = $(`<div class="yidong-button pl-button-init">下载助手(未点亮)</div>`);
  4269. if (pt === 'home') {
  4270. let ins = setInterval(() => {
  4271. $toolWrap = $(pan.btn.home);
  4272. if ($toolWrap.length > 0) {
  4273. $toolWrap.prepend($button);
  4274. clearInterval(ins);
  4275. }
  4276. }, 50);
  4277. }
  4278. if (pt === 'share') {
  4279. $button.removeClass('yidong-button').addClass('yidong-share-button');
  4280. let ins = setInterval(() => {
  4281. $toolWrap = $(pan.btn.share);
  4282. if ($toolWrap.length > 0) {
  4283. $toolWrap.prepend($button);
  4284. clearInterval(ins);
  4285. }
  4286. }, 50);
  4287. }
  4288. $button.click(() => base.initDialog());
  4289. },
  4290.  
  4291. getRandomString(len) {
  4292. len = len || 16;
  4293. let $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
  4294. let maxPos = $chars.length;
  4295. let pwd = '';
  4296. for (let i = 0; i < len; i++) {
  4297. pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
  4298. }
  4299. return pwd;
  4300. },
  4301.  
  4302. utob(str) {
  4303. const u = String.fromCharCode;
  4304. return str.replace(/[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g, (t) => {
  4305. if (t.length < 2) {
  4306. let e = t.charCodeAt(0);
  4307. return e < 128 ? t : e < 2048 ? u(192 | e >>> 6) + u(128 | 63 & e) : u(224 | e >>> 12 & 15) + u(128 | e >>> 6 & 63) + u(128 | 63 & e);
  4308. }
  4309. e = 65536 + 1024 * (t.charCodeAt(0) - 55296) + (t.charCodeAt(1) - 56320);
  4310. return u(240 | e >>> 18 & 7) + u(128 | e >>> 12 & 63) + u(128 | e >>> 6 & 63) + u(128 | 63 & e);
  4311. });
  4312. },
  4313.  
  4314. getSign(e, t, a, n) {
  4315. let r = "",
  4316. i = "";
  4317. if (t) {
  4318. let s = Object.assign({}, t);
  4319. i = JSON.stringify(s),
  4320. i = i.replace(/\s*/g, ""),
  4321. i = encodeURIComponent(i);
  4322. let c = i.split(""),
  4323. u = c.sort();
  4324. i = u.join("");
  4325. }
  4326. let A = md5(base.e(this.utob(i)));
  4327. let l = md5(a + ":" + n);
  4328. return md5(A + l).toUpperCase();
  4329. },
  4330.  
  4331. async getFileUrlByOnce(item, index) {
  4332. try {
  4333. if (item.downloadUrl) return {
  4334. index,
  4335. downloadUrl: item.downloadUrl
  4336. };
  4337.  
  4338. if (this.detectPage() === 'home') {
  4339. let body = {
  4340. "appName": "",
  4341. "contentID": item.contentID,
  4342. "commonAccountInfo": {"account": item.owner, "accountType": 1}
  4343. };
  4344. let time = new Date(+new Date() + 8 * 3600 * 1000).toJSON().substr(0, 19).replace('T', ' ');
  4345. let key = this.getRandomString(16);
  4346. let sign = this.getSign(undefined, body, time, key);
  4347.  
  4348. let res = await base.post(pan.pcs[0], body, {
  4349. 'x-huawei-channelSrc': '10000034',
  4350. 'x-inner-ntwk': '2',
  4351. 'mcloud-channel': '1000101',
  4352. 'mcloud-client': '10701',
  4353. 'mcloud-sign': time + "," + key + "," + sign,
  4354. 'content-type': "application/json;charset=UTF-8",
  4355. 'caller': 'web',
  4356. 'CMS-DEVICE': 'default',
  4357. 'x-DeviceInfo': '||9|85.0.4183.83|chrome|85.0.4183.83|||windows 10||zh-CN|||',
  4358. 'x-SvcType': '1',
  4359. });
  4360. if (res.success) {
  4361. return {
  4362. index,
  4363. downloadUrl: res.data.downloadURL
  4364. };
  4365. } else {
  4366. return {
  4367. index,
  4368. downloadUrl: '获取下载地址失败,请刷新重试!'
  4369. };
  4370. }
  4371. }
  4372. if (this.detectPage() === 'share') {
  4373. let vueDom = document.querySelector(".home-page").__vue__;
  4374.  
  4375. let res = await base.post(pan.pcs[1], `linkId=${vueDom.linkID}&contentIds=${encodeURIComponent(vueDom.currentPath.id + '/' + item.coID)}&catalogIds=`, {
  4376. 'Content-Type': 'application/x-www-form-urlencoded',
  4377. });
  4378. if (res.code === 0) {
  4379. return {
  4380. index,
  4381. downloadUrl: res.data.redrUrl
  4382. };
  4383. } else {
  4384. return {
  4385. index,
  4386. downloadUrl: '获取下载地址失败,请刷新重试!'
  4387. };
  4388. }
  4389. }
  4390. } catch (e) {
  4391. return {
  4392. index,
  4393. downloadUrl: '获取下载地址失败,请刷新重试!'
  4394. };
  4395. }
  4396. },
  4397.  
  4398. async getPCSLink() {
  4399. selectList = this.getSelectedList();
  4400. if (selectList.length === 0) {
  4401. return message.error('提示:请先勾选要下载的文件!');
  4402. }
  4403. if (this.isOnlyFolder()) {
  4404. return message.error('提示:请打开文件夹后勾选文件!');
  4405. }
  4406.  
  4407. let queue = [];
  4408. selectList.forEach((item, index) => {
  4409. queue.push(this.getFileUrlByOnce(item, index));
  4410. });
  4411.  
  4412. const res = await Promise.all(queue);
  4413. res.forEach(val => {
  4414. selectList[val.index].downloadUrl = val.downloadUrl;
  4415. });
  4416.  
  4417. let html = this.generateDom(selectList);
  4418. this.showMainDialog(pan[mode][0], html, pan[mode][1]);
  4419. },
  4420.  
  4421. generateDom(list) {
  4422. let content = '<div class="pl-main">';
  4423. let alinkAllText = '';
  4424. list.forEach((v, i) => {
  4425. if (v.dirEtag || v.caName) return;
  4426. let filename = v.contentName || v.coName;
  4427. let size = base.sizeFormat(v.contentSize || v.coSize);
  4428. let dlink = v.downloadUrl;
  4429. if (mode === 'api') {
  4430. content += `<div class="pl-item">
  4431. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  4432. <a class="pl-item-link listener-link-api" data-filename="${filename}" data-link="${dlink}" data-index="${i}">${dlink}</a>
  4433. </div>`;
  4434. }
  4435. if (mode === 'aria') {
  4436. let alink = this.convertLinkToAria(dlink, filename, navigator.userAgent);
  4437. alinkAllText += alink + '\r\n';
  4438. content += `<div class="pl-item">
  4439. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  4440. <a class="pl-item-link listener-link-aria" href="${alink}" title="点击复制aria2c链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  4441. }
  4442. if (mode === 'rpc') {
  4443. content += `<div class="pl-item">
  4444. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  4445. <button class="pl-item-link listener-link-rpc pl-btn-primary pl-btn-info" data-filename="${filename}" data-link="${dlink}"><em class="icon icon-device"></em><span style="margin-left: 5px;">推送到 RPC 下载器</span></button></div>`;
  4446. }
  4447. if (mode === 'curl') {
  4448. let alink = this.convertLinkToCurl(dlink, filename, navigator.userAgent);
  4449. alinkAllText += alink + '\r\n';
  4450. content += `<div class="pl-item">
  4451. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  4452. <a class="pl-item-link listener-link-aria" href="${alink}" title="点击复制curl链接" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  4453. }
  4454. if (mode === 'bc') {
  4455. let alink = this.convertLinkToBC(dlink, filename, navigator.userAgent);
  4456. content += `<div class="pl-item">
  4457. <div class="pl-item-name listener-tip" data-size="${size}">${filename}</div>
  4458. <a class="pl-item-link" href="${decodeURIComponent(alink)}" title="点击用比特彗星下载" data-filename="${filename}" data-link="${alink}">${decodeURIComponent(alink)}</a> </div>`;
  4459. }
  4460. });
  4461. content += '</div>';
  4462. if (mode === 'aria')
  4463. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button></div>`;
  4464. if (mode === 'rpc') {
  4465. let rpc = base.getValue('setting_rpc_domain') + ':' + base.getValue('setting_rpc_port') + base.getValue('setting_rpc_path');
  4466. content += `<div class="pl-extra"><button class="pl-btn-primary listener-send-rpc">发送全部链接</button><button title="${rpc}" class="pl-btn-primary pl-btn-warning listener-open-setting" style="margin-left: 10px">设置 RPC 参数(当前为:${rpc})</button><button class="pl-btn-primary pl-btn-success listener-rpc-task" style="margin-left: 10px;display: none">查看下载任务</button></div>`;
  4467. }
  4468. if (mode === 'curl')
  4469. content += `<div class="pl-extra"><button class="pl-btn-primary listener-copy-all" data-link="${alinkAllText}">复制全部链接</button><button class="pl-btn-primary pl-btn-warning listener-open-setting" style="margin-left: 10px;">设置终端类型(当前为:${terminalType[base.getValue('setting_terminal_type')]})</button></div>`;
  4470. return content;
  4471. },
  4472.  
  4473. async sendLinkToRPC(filename, link) {
  4474. let rpc = {
  4475. domain: base.getValue('setting_rpc_domain'),
  4476. port: base.getValue('setting_rpc_port'),
  4477. path: base.getValue('setting_rpc_path'),
  4478. token: base.getValue('setting_rpc_token'),
  4479. dir: base.getValue('setting_rpc_dir'),
  4480. };
  4481.  
  4482. let url = `${rpc.domain}:${rpc.port}${rpc.path}`;
  4483. let rpcData = {
  4484. id: new Date().getTime(),
  4485. jsonrpc: '2.0',
  4486. method: 'aria2.addUri',
  4487. params: [`token:${rpc.token}`, [link], {
  4488. dir: rpc.dir,
  4489. out: filename,
  4490. header: []
  4491. }]
  4492. };
  4493. try {
  4494. let res = await base.post(url, rpcData, {}, '');
  4495. if (res.result) return 'success';
  4496. return 'fail';
  4497. } catch (e) {
  4498. return 'fail';
  4499. }
  4500. },
  4501.  
  4502. getSelectedList() {
  4503. try {
  4504. return document.querySelector(".main_file_list").__vue__.selectList.map(val => val.item);
  4505. } catch (e) {
  4506. let vueDom = document.querySelector(".home-page").__vue__;
  4507. let fileList = vueDom._computedWatchers.fileList.value;
  4508. let dirList = vueDom._computedWatchers.dirList.value;
  4509. let selectedFileIndex = vueDom.selectedFile;
  4510. let selectedDirIndex = vueDom.selectedDir;
  4511. let selectFileList = fileList.filter((v, i) => {
  4512. return selectedFileIndex.includes(i);
  4513. });
  4514. let selectDirList = dirList.filter((v, i) => {
  4515. return selectedDirIndex.includes(i);
  4516. });
  4517. return [...selectFileList, ...selectDirList];
  4518. }
  4519. },
  4520.  
  4521. detectPage() {
  4522. let hostname = location.hostname;
  4523. if (/^yun/.test(hostname)) return 'home';
  4524. if (/^caiyun/.test(hostname)) return 'share';
  4525. return '';
  4526. },
  4527.  
  4528. isOnlyFolder() {
  4529. for (let i = 0; i < selectList.length; i++) {
  4530. if (selectList[i].fileEtag || selectList[i].coName) return false;
  4531. }
  4532. return true;
  4533. },
  4534.  
  4535. showMainDialog(title, html, footer) {
  4536. Swal.fire({
  4537. title,
  4538. html,
  4539. footer,
  4540. allowOutsideClick: false,
  4541. showCloseButton: true,
  4542. showConfirmButton: false,
  4543. position: 'top',
  4544. width,
  4545. padding: '15px 20px 5px',
  4546. customClass,
  4547. });
  4548. },
  4549.  
  4550. async initPanLinker() {
  4551. base.initDefaultConfig();
  4552. base.addPanLinkerStyle();
  4553. pt = this.detectPage();
  4554. let res = await base.post
  4555. (`https://api.youxiaohou.com/config/yidong?ver=${version}&a=${author}`, {}, {}, 'text');
  4556. pan = JSON.parse(base.d(res));
  4557. Object.freeze && Object.freeze(pan);
  4558. pan.num === base.getValue('setting_init_code') ? this.addButton() : this.addInitButton();
  4559. base.createTip();
  4560. base.registerMenuCommand();
  4561. }
  4562. };
  4563.  
  4564. let youxiaohou ={
  4565. async initPanLinker() {
  4566. base.initDefaultConfig();
  4567. base.addPanLinkerStyle();
  4568. let res = await base.post
  4569. (`https://api.youxiaohou.com/config/?ver=${version}&a=${author}`, {}, {}, 'text');
  4570. pan = JSON.parse(base.d(res));
  4571. base.createTip();
  4572. base.registerPanMenuCommand();
  4573.  
  4574. let $button1 = `<div class="nav-item" style="text-align: center;"><a class="listener-open-updatelog">(改)下载助手<br>更新日志</a></div>`
  4575. doc.on('click', '.listener-open-updatelog', () => {
  4576. base.showUpdateLog();
  4577. });
  4578. document.getElementsByClassName("nav-links can-hide")[0].innerHTML += $button1
  4579.  
  4580. let $button2 = `<div class="nav-item" style="text-align: center;"><a class="listener-open-info">(改)下载助手<br>暗号查看</a></div>`
  4581. doc.on('click', '.listener-open-info', () => {
  4582. base.showPanInfo();
  4583. });
  4584. document.getElementsByClassName("nav-links can-hide")[0].innerHTML += $button2
  4585. }
  4586. }
  4587.  
  4588. let main = {
  4589. init() {
  4590. if (/(pan|yun).baidu.com/.test(location.host)) {
  4591. baidu.initPanLinker();
  4592. }
  4593. if (/www.aliyundrive.com/.test(location.host)) {
  4594. ali.initPanLinker();
  4595. }
  4596. if (/cloud.189.cn/.test(location.host)) {
  4597. tianyi.initPanLinker();
  4598. }
  4599. if (/pan.xunlei.com/.test(location.host)) {
  4600. xunlei.initPanLinker();
  4601. }
  4602. if (/pan.quark.cn/.test(location.host)) {
  4603. quark.initPanLinker();
  4604. }
  4605. if (/(yun|caiyun).139.com/.test(location.host)) {
  4606. yidong.initPanLinker();
  4607. }
  4608. if (/www.youxiaohou.com/.test(location.host)) {
  4609. youxiaohou.initPanLinker();
  4610. }
  4611. }
  4612. };
  4613. main.init();
  4614. })();

QingJ © 2025

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