🏠 返回首頁 

Greasy Fork is available in English.

Redirecteur de confidentialité

Rediriger les plateformes de médias sociaux vers leurs pages d'accueil respectueuses de la vie privée

  1. // ==UserScript==
  2. // @name Privacy Redirector
  3. // @name:bg Пренасочване на поверителността
  4. // @name:br Rediretor de privacidade
  5. // @name:cs Přesměrování soukromí
  6. // @name:de Datenschutz Umleiter
  7. // @name:da Omdirigeringsenhed for privatlivets fred
  8. // @name:et Privaatsuse ümbersuunaja
  9. // @name:es Redirección de privacidad
  10. // @name:fi Yksityisyydensuojan uudelleenohjaus
  11. // @name:fr Redirecteur de confidentialité
  12. // @name:el Επανακατευθυντής απορρήτου
  13. // @name:hu Adatvédelmi átirányító
  14. // @name:id Pengarah Privasi
  15. // @name:it Reindirizzatore di privacy
  16. // @name:ja プライバシーリダイレクト
  17. // @name:lt Privatumo nukreipiklis
  18. // @name:lv Konfidencialitātes pāradresētājs
  19. // @name:nl Privacy-omleiding
  20. // @name:pl Przekierownik prywatności
  21. // @name:pt Redirector de Privacidade
  22. // @name:ro Redirector de confidențialitate
  23. // @name:ru Перенаправление конфиденциальности
  24. // @name:sv Omdirigering av sekretess
  25. // @name:sl Preusmerjevalnik zasebnosti
  26. // @name:sk Presmerovanie súkromia
  27. // @name:tr Gizlilik Yönlendiricisi
  28. // @name:uk Редиректор конфіденційності
  29. // @name:zh 隐私重定向器
  30. // @name:zh-CN 隐私重定向器
  31. // @description Redirect social media platforms to their privacy respecting frontends
  32. // @description:bg Пренасочване на платформите за социални медии към заглавните им страници, съобразени с поверителността
  33. // @description:br Redirecionando as plataformas de mídia social para suas primeiras páginas de privacidade
  34. // @description:cs Přesměrování platforem sociálních médií na jejich titulní stránky šetrné k soukromí
  35. // @description:de Leitet von Social-Media-Plattformen auf deren jeweilige datenschutzfreundlicheren Frontends
  36. // @description:da Omdirigering af sociale medieplatforme til deres privatlivsvenlige forsider
  37. // @description:et Sotsiaalmeediaplatvormide ümbersuunamine nende privaatsussõbralikele esilehtedele
  38. // @description:es Redirigir las plataformas de medios sociales a sus portadas respetuosas con la privacidad
  39. // @description:fi Sosiaalisen median alustojen ohjaaminen yksityisyyden suojaa edistäville etusivuille.
  40. // @description:fr Rediriger les plateformes de médias sociaux vers leurs pages d'accueil respectueuses de la vie privée
  41. // @description:el Αναπροσανατολισμός των πλατφορμών κοινωνικής δικτύωσης στις μπροστινές σελίδες τους που είναι φιλικές προς το απόρρητο
  42. // @description:hu A közösségi médiaplatformok átirányítása az adatvédelem-barát kezdőlapokra
  43. // @description:id Mengarahkan platform media sosial ke halaman depan yang ramah privasi
  44. // @description:it Reindirizzare le piattaforme di social media verso le loro pagine frontali che rispettano la privacy
  45. // @description:ja ソーシャルメディアプラットフォームをプライバシーに配慮したフロントページにリダイレクトする
  46. // @description:lt Socialinės žiniasklaidos platformų nukreipimas į privatumą užtikrinančius pirmuosius puslapius
  47. // @description:lv Sociālo plašsaziņas līdzekļu platformu pāradresēšana uz to privātumam draudzīgajām pirmajām lapām.
  48. // @description:nl Sociale-mediaplatforms omleiden naar hun privacyvriendelijke voorpagina's
  49. // @description:pl Przekierowanie platform mediów społecznościowych na ich przyjazne dla prywatności strony tytułowe
  50. // @description:pt Redireccionar as plataformas de redes sociais para as suas primeiras páginas amigas da privacidade
  51. // @description:ro Redirecționarea platformelor de socializare către paginile lor de început care respectă viața privată
  52. // @description:ru Перенаправление платформ социальных сетей на их главные страницы, дружественные к конфиденциальности
  53. // @description:sv Omdirigera sociala medieplattformar till deras integritetsvänliga förstasidor.
  54. // @description:sl preusmeritev platform družabnih medijev na njihove naslovne strani, ki so prijazne do zasebnosti.
  55. // @description:sk Presmerovanie platforiem sociálnych médií na ich úvodné stránky, ktoré chránia súkromie
  56. // @description:tr Sosyal medya platformlarını, gizliliğe saygı duyan önyüzlerine yönlendirir
  57. // @description:uk Перенаправлення соціальних медіа-платформ на їхні головні сторінки, дружні до приватності
  58. // @description:zh 将社交媒体##重定向到其隐私友好的首页
  59. // @description:zh-CN 将社交媒体##重定向到其隐私友好的首页
  60. // @namespace https://github.com/dybdeskarphet/privacy-redirector
  61. // @author Ahmet Arda Kavakcı
  62. // @license GPLv3
  63. // @version 1.6.2
  64. // @downloadURL
  65. // https://raw.githubusercontent.com/dybdeskarphet/privacy-redirector/main/privacy-redirector.user.js
  66. // @supportURL https://github.com/dybdeskarphet/privacy-redirector
  67. // @updateURL
  68. // https://raw.githubusercontent.com/dybdeskarphet/privacy-redirector/main/privacy-redirector.user.js
  69. // @run-at document-start
  70. // @match *://*.bandcamp.com/*
  71. // @match *://*.fandom.com/*
  72. // @match *://*.genius.com/*
  73. // @match *://*.google.com/*
  74. // @match *://*.imdb.com/*
  75. // @match *://*.imgur.com/*
  76. // @match *://*.imgur.io/*
  77. // @match *://*.instagram.com/*
  78. // @match *://*.medium.com/*
  79. // @match *://*.pinterest.com/*
  80. // @match *://*.quora.com/*
  81. // @match *://*.reddit.com/*
  82. // @match *://*.reuters.com/*
  83. // @match *://*.soundcloud.com/*
  84. // @match *://*.tiktok.com/*
  85. // @match *://*.twitch.tv/*
  86. // @match *://*.deepl.com/*
  87. // @match *://*.deviantart.com/*
  88. // @match *://twitch.tv/*
  89. // @match *://*.twitter.com/*
  90. // @match *://*.x.com/*
  91. // @match *://*.tumblr.com/*
  92. // @match *://x.com/*
  93. // @match *://*.wikipedia.org/*
  94. // @match *://*.youtube-nocookie.com/*
  95. // @match *://*.youtube.com/*
  96. // @match *://f4.bcbits.com/*
  97. // @match *://genius.com/*
  98. // @match *://i.pinimg.com/*
  99. // @match *://imgur.com/*
  100. // @match *://instagram.com/*
  101. // @match *://medium.com/*
  102. // @match *://news.ycombinator.com/*
  103. // @match *://reddit.com/*
  104. // @match *://stackoverflow.com/*
  105. // @match *://t4.bcbits.com/*
  106. // @match *://translate.google.com/*
  107. // @match *://twitter.com/*
  108. // @match *://www.goodreads.com/*
  109. // @match *://www.pixiv.net/*
  110. // @match *://youtube.com/*
  111. // @exclude *://*.youtube.com/redirect*
  112. // @exclude *://youtube.com/redirect*
  113. // ==/UserScript==
  114. /*
  115. ___ _ _ ___ _____ _____
  116. / _ \| \ | | / _ \| ___| ___|
  117. | | | | \| |_____| | | | |_ | |_
  118. | |_| | |\ |_____| |_| | _| | _|
  119. \___/|_| \_| \___/|_| |_|
  120. CHANGE THE RELEVANT VALUE TO "false" TO
  121. DISABLE THE REDIRECTION/FARSIDE FOR THAT
  122. PARTICULAR PLATFORM */
  123. // REDIRECTON / FARSIDE
  124. let bandcamp = [true, true];
  125. let deepl = [false, true]; // Mozhi Deepl engine doesn't work
  126. let deviantart = [true, false];
  127. let fandom = [true, true];
  128. let genius = [true, true];
  129. let goodreads = [true, false];
  130. let google = [true, true];
  131. let gtranslate = [true, true];
  132. let hackernews = [true, true];
  133. let imdb = [true, true];
  134. let imgur = [true, false];
  135. let instagram = [true, true];
  136. let medium = [true, true];
  137. let pinterest = [true, true];
  138. let pixiv = [true, true];
  139. let quora = [true, false];
  140. let reddit = [true, false];
  141. let reuters = [true, true];
  142. let soundcloud = [true, true];
  143. let stackoverflow = [true, true];
  144. let tiktok = [true, false];
  145. let tumblr = [true, false];
  146. let twitch = [true, true];
  147. let twitter = [true, true];
  148. let wikipedia = [true, false];
  149. let youtube = [true, false];
  150. // PREFERRED FRONTEND
  151. let youtubeFrontend = "freetube"; // accepts "invidious", "piped", "tubo", "freetube"
  152. let youtubeMusicFrontend = "hyperpipe"; // accepts "hyperpipe", "invidious", "piped"
  153. let redditFrontend = "libreddit"; // accepts "libreddit", "teddit"
  154. let googleFrontend = "librey"; // accepts "librey", "searx", "searxng"
  155. let googleTranslateFrontend = "mozhi"; // accepts "lingva" (farside available), "mozhi" (no farside)
  156. let geniusFrontend = "intellectual"; // accepts dumb, intellectual
  157. let mediumFrontend = "scribe"; // accepts libmedium, scribe, mediumrip
  158. let hackernewsFrontend = "better"; // accepts better, worker
  159. // OTHER SETTINGS
  160. let keepHistory = false; // keeps farside.link in the browser history
  161. // // // // // // // // // // // // //
  162. /*
  163. ___ _
  164. |_ _|_ __ ___| |_ __ _ _ __ ___ ___ ___
  165. | || '_ \/ __| __/ _` | '_ \ / __/ _ \/ __|
  166. | || | | \__ \ || (_| | | | | (_| __/\__ \
  167. |___|_| |_|___/\__\__,_|_| |_|\___\___||___/
  168. LIST OF INSTANCES TO USE IF FARSIDE IS NOT ENABLED
  169. */
  170. const Instances = {
  171. anonymousoverflow: [
  172. "code.whatever.social",
  173. "ao.vern.cc",
  174. "overflow.smnz.de",
  175. "overflow.lunar.icu",
  176. "overflow.adminforge.de",
  177. "overflow.projectsegfau.lt",
  178. "ao.bloat.cat",
  179. "overflow.ducks.party",
  180. "ao.owo.si",
  181. "overflow.freedit.eu",
  182. "ao.rootdo.org",
  183. "a.opnxng.com",
  184. "overflow.einfachzocken.eu",
  185. "exchange.seitan-ayoub.lol",
  186. "overflow.r4fo.com",
  187. ],
  188. hyperpipe: [
  189. "hyperpipe.surge.sh",
  190. "hyperpipe.onrender.com",
  191. "music.adminforge.de",
  192. "music.pfcd.me",
  193. "hyperpipe.projectsegfau.lt",
  194. "hp.ggtyler.dev",
  195. "hyperpipe.lunar.icu",
  196. "music.seitan-ayoub.lol",
  197. ],
  198. proxigram: [
  199. "proxigram.protokolla.fi",
  200. "proxigram.kyun.li",
  201. "proxigram.lunar.icu",
  202. "ig.opnxng.com",
  203. ],
  204. biblioreads: [
  205. "biblioreads.eu.org",
  206. "biblioreads.vercel.app",
  207. "biblioreads.mooo.com",
  208. "bl.vern.cc",
  209. "biblioreads.lunar.icu",
  210. "read.seitan-ayoub.lol",
  211. ],
  212. binternet: [
  213. "binternet.ahwx.org",
  214. "bn.bloat.cat",
  215. "bn.opnxng.com",
  216. "bn.vern.cc",
  217. ],
  218. breezewiki: [
  219. "breezewiki.com",
  220. "antifandom.com",
  221. "breezewiki.pussthecat.org",
  222. "bw.hamstro.dev",
  223. "bw.projectsegfau.lt",
  224. "breeze.hostux.net",
  225. "bw.artemislena.eu",
  226. "breezewiki.woodland.cafe",
  227. "breeze.nohost.network",
  228. "z.opnxng.com",
  229. "breezewiki.catsarch.com",
  230. "breeze.mint.lgbt",
  231. "breezewiki.lunar.icu",
  232. "fandom.adminforge.de",
  233. ],
  234. dumb: [
  235. "dumb.privacydev.net",
  236. "db.vern.cc",
  237. "sing.whatever.social",
  238. "dumb.lunar.icu",
  239. ],
  240. intellectual: [
  241. "intellectual.insprill.net",
  242. "in.bloat.cat",
  243. "in2.bloat.cat",
  244. "intellectual.lumaeris.com",
  245. ],
  246. invidious: [
  247. "yewtu.be",
  248. "vid.puffyan.us",
  249. "yt.artemislena.eu",
  250. "invidious.flokinet.to",
  251. "invidious.projectsegfau.lt",
  252. "invidious.privacydev.net",
  253. "iv.ggtyler.dev",
  254. "invidious.lunar.icu",
  255. "inv.tux.pizza",
  256. "invidious.protokolla.fi",
  257. "proxied.invidious.fi",
  258. "onion.tube",
  259. "invidious.no-logs.com",
  260. "invidious.io.lol",
  261. "iv.nboeck.de",
  262. "invidious.private.coffee",
  263. "invidious.asir.dev",
  264. "iv.datura.network",
  265. "invidious.perennialte.ch",
  266. "yt.cdaut.de",
  267. "invidious.einfachzocken.eu",
  268. "yt.drgnz.club",
  269. ],
  270. piped: [
  271. "piped.video",
  272. "cf.piped.video",
  273. "fl.piped.video",
  274. "do.piped.video",
  275. "az.piped.video",
  276. "piped.mha.fi",
  277. "watch.leptons.xyz",
  278. "piped.lunar.icu",
  279. "piped.r4fo.com",
  280. "piped.privacydev.net",
  281. "piped.smnz.de",
  282. "piped.adminforge.de",
  283. "piped.astartes.nl",
  284. "piped.osphost.fi",
  285. "pi.ggtyler.dev",
  286. "piped.seitan-ayoub.lol",
  287. "yt.owo.si",
  288. "piped.minionflo.net",
  289. ],
  290. libmedium: [
  291. "libmedium.batsense.net",
  292. "md.vern.cc",
  293. "medium.hostux.net",
  294. "libmedium.ducks.party",
  295. ],
  296. libreddit: [
  297. "redditor.fly.dev",
  298. "libreddit.kavin.rocks",
  299. "libreddit.northboot.xyz",
  300. "libreddit.kylrth.com",
  301. "libreddit.tiekoetter.com",
  302. "l.opnxng.com",
  303. "libreddit.projectsegfau.lt",
  304. "libreddit.privacydev.net",
  305. "libreddit.freedit.eu",
  306. "libreddit.mha.fi",
  307. "lr.artemislena.eu",
  308. "libreddit.nohost.network",
  309. "libreddit.lunar.icu",
  310. "snoo.habedieeh.re",
  311. "libreddit.tux.pizza",
  312. "libreddit.perennialte.ch",
  313. "libreddit.private.coffee",
  314. "lr.seitan-ayoub.lol",
  315. "l.bloat.cat",
  316. ],
  317. libremdb: [
  318. "libremdb.iket.me",
  319. "libremdb.pussthecat.org",
  320. "ld.vern.cc",
  321. "binge.whatever.social",
  322. "libremdb.lunar.icu",
  323. "libremdb.jeikobu.net",
  324. "libremdb.nerdyfam.tech",
  325. "libremdb.tux.pizza",
  326. "d.opnxng.com",
  327. "libremdb.catsarch.com",
  328. ],
  329. librey: [
  330. "search.ahwx.org",
  331. "ly.owo.si",
  332. "librey.danyaal.xyz",
  333. "librey.org",
  334. "search.davidovski.xyz",
  335. "search.funami.tech",
  336. "librex.nohost.network",
  337. "search.pabloferreiro.es",
  338. "librey.baczek.me",
  339. "search.seitan-ayoub.lol",
  340. ],
  341. lingva: [
  342. "lingva.ml",
  343. "lingva.thedaviddelta.com",
  344. "lingva.retiolus.net",
  345. "translate.plausibility.cloud",
  346. "lingva.lunar.icu",
  347. "lingva.garudalinux.org",
  348. "lingva.seitan-ayoub.lol",
  349. ],
  350. mediumrip: ["medium.rip"],
  351. neuters: ["neuters.de", "nu.vern.cc"],
  352. nitter: [
  353. "nitter.net",
  354. "nitter.unixfox.eu",
  355. "nitter.poast.org",
  356. "nitter.privacydev.net",
  357. "nitter.projectsegfau.lt",
  358. "nitter.soopy.moe",
  359. "nitter.rawbit.ninja",
  360. "nitter.freedit.eu",
  361. "nitter.nohost.network",
  362. "nitter.io.lol",
  363. "nitter.woodland.cafe",
  364. "nitter.perennialte.ch",
  365. "nitter.salastil.com",
  366. "n.opnxng.com",
  367. "nitter.ktachibana.party",
  368. ],
  369. pixivfe: [
  370. "pixivfe.drgns.space",
  371. "pixivfe.ducks.party",
  372. "pixiv.perennialte.ch",
  373. ],
  374. proxitok: [
  375. "proxitok.pabloferreiro.es",
  376. "proxitok.pussthecat.org",
  377. "tok.habedieeh.re",
  378. "proxitok.privacydev.net",
  379. "tok.artemislena.eu",
  380. "tok.adminforge.de",
  381. "cringe.whatever.social",
  382. "proxitok.lunar.icu",
  383. "proxitok.privacy.com.de",
  384. "cringe.seitan-ayoub.lol",
  385. "tt.opnxng.com",
  386. "tiktok.wpme.pl",
  387. ],
  388. quetre: [
  389. "quetre.iket.me",
  390. "qr.vern.cc",
  391. "quetre.pussthecat.org",
  392. "quetre.privacydev.net",
  393. "ask.habedieeh.re",
  394. "quetre.blackdrgn.nl",
  395. "quetre.lunar.icu",
  396. "q.opnxng.com",
  397. "quetre.rootdo.org",
  398. "quora.seitan-ayoub.lol",
  399. "ask.sudovanilla.org",
  400. "quetre.smnz.de",
  401. ],
  402. rimgo: [
  403. "rimgo.totaldarkness.net",
  404. "imgur.artemislena.eu",
  405. "rimgo.lunar.icu",
  406. "imgur.010032.xyz",
  407. "rimgo.kling.gg",
  408. "rimgo.projectsegfau.lt",
  409. "rimgo.nohost.network",
  410. "rimgo.catsarch.com",
  411. "rimgo.quantenzitrone.eu",
  412. ],
  413. scribe: [
  414. "scribe.rip",
  415. "scribe.citizen4.eu",
  416. "scribe.nixnet.services",
  417. "scribe.privacyredirect.com",
  418. "scribe.projectsegfau.lt",
  419. "scribe.rawbit.ninja",
  420. "m.opnxng.com",
  421. ],
  422. teddit: [
  423. "i.opnxng.com",
  424. "teddit.net",
  425. "teddit.rawbit.ninja",
  426. "teddit.pussthecat.org",
  427. "teddit.zaggy.nl",
  428. "t.sneed.network",
  429. "td.vern.cc",
  430. ],
  431. tent: ["tent.sny.sh", "tent.bloat.cat", "tn.vern.cc"],
  432. tubo: ["tubo.media", "tubo.reallyaweso.me", "tubo.ducks.party"],
  433. wikiless: [
  434. "wikiless.tiekoetter.com",
  435. "wikiless.funami.tech",
  436. "wl.vern.cc",
  437. "wiki.froth.zone",
  438. "wikiless.northboot.xyz",
  439. "wikiless.rawbit.ninja",
  440. "wiki.adminforge.de",
  441. "wikiless.rootdo.org",
  442. "w.sneed.network",
  443. "wikiless.r4fo.com",
  444. "wiki.seitan-ayoub.lol",
  445. "wikiless.ditatompel.com",
  446. ],
  447. safetwitch: [
  448. "safetwitch.drgns.space",
  449. "safetwitch.projectsegfau.lt",
  450. "safetwitch.datura.network",
  451. "ttv.vern.cc",
  452. "twitch.seitan-ayoub.lol",
  453. "st.ggtyler.dev",
  454. "safetwitch.lunar.icu",
  455. "safetwitch.r4fo.com",
  456. "safetwitch.ducks.party",
  457. "safetwitch.nogafam.fr",
  458. "safetwitch.privacyredirect.com",
  459. ],
  460. searx: [
  461. "searx.gnu.style",
  462. "searx.nixnet.services",
  463. "search.projectsegfau.lt",
  464. "searx.roflcopter.fr",
  465. "northboot.xyz",
  466. "opnxng.com",
  467. ],
  468. searxng: [
  469. "search.sapti.me",
  470. "priv.au",
  471. "search.demoniak.ch",
  472. "www.gruble.de",
  473. "searx.divided-by-zero.eu",
  474. "xo.wtf",
  475. "freesearch.club",
  476. "baresearch.org",
  477. "searx.perennialte.ch",
  478. "searx.techsaviours.org",
  479. "search.mdosch.de",
  480. "searx.si",
  481. "searx.namejeff.xyz",
  482. "search.ononoki.org",
  483. "etsi.me",
  484. "searx.work",
  485. "search.smnz.de",
  486. "searx.prvcy.eu",
  487. "searx.headpat.exchange",
  488. ],
  489. hackernews: {
  490. better: "better-hackernews.vercel.app",
  491. worker: "news.workers.tools",
  492. },
  493. mozhi: [
  494. "mozhi.aryak.me",
  495. "nyc1.mz.ggtyler.dev",
  496. "translate.projectsegfau.lt",
  497. "translate.nerd###.de",
  498. "mozhi.ducks.party",
  499. "mozhi.pussthecat.org",
  500. "mozhi.adminforge.de",
  501. "translate.privacyredirect.com",
  502. "mozhi.canine.tools",
  503. "mozhi.gitro.xyz",
  504. ],
  505. skunkyart: [
  506. "art.bloat.cat",
  507. "skunky.bloat.cat",
  508. "lost-skunk.cc/skunkyart",
  509. "skunkyart.lumaeris.com",
  510. ],
  511. priviblur: [
  512. "pb.bloat.cat",
  513. "tb.opnxng.com",
  514. "priviblur.pussthecat.org",
  515. "priviblur.thebunny.zone",
  516. "priviblur.gitro.xyz",
  517. "priviblur.canine.tools",
  518. ],
  519. };
  520. let farsideInstance = keepHistory ? "farside.link/_" : "farside.link";
  521. // // // // // // // // // // // // //
  522. const hash = window.location.hash,
  523. scheme = `${window.location.protocol}//`;
  524. let debug_mode = false;
  525. if (debug_mode) {
  526. alert(
  527. "\n== DEBUG MODE IS ON ==" +
  528. "\nIf you're seeing this" +
  529. "\nset the debug_mode value to" +
  530. "\nfalse for Privacy Redirector." +
  531. "\n======================" +
  532. "\n\nHostname: " +
  533. window.location.hostname +
  534. "\nPath: " +
  535. window.location.pathname +
  536. "\nQuery: " +
  537. window.location.search +
  538. "\nHash: " +
  539. hash,
  540. );
  541. }
  542. let selectedInstance = "",
  543. newURL = "";
  544. const getrandom = async (instances) =>
  545. instances[Math.floor(Math.random() * instances.length)];
  546. async function redirectInstagram() {
  547. if (instagram[0]) {
  548. window.stop();
  549. let pathname = window.location.pathname;
  550. let search = window.location.search;
  551. let params = new URLSearchParams(search);
  552. selectedInstance = await getrandom(Instances.proxigram);
  553. switch (true) {
  554. case pathname.startsWith("/accounts/login/"):
  555. case pathname.startsWith("/accounts/signup/"):
  556. pathname = pathname.replace(/^\/accounts\/(login|signup)\/[a-z]*/, "");
  557. params.delete("next");
  558. search = params.size ? `?${params}` : "";
  559. break;
  560. case pathname.startsWith("/reel/"):
  561. case pathname.startsWith("/tv/"):
  562. pathname = pathname.replace(/^\/(reel|tv)\//, "/p/");
  563. break;
  564. case pathname.endsWith("/reels/"):
  565. pathname = pathname.replace("/reels", "");
  566. break;
  567. }
  568. newURL = `${scheme}${selectedInstance}${pathname}${search}${hash}`;
  569. window.location.replace(newURL);
  570. }
  571. }
  572. async function redirectTwitter() {
  573. if (twitter[0]) {
  574. window.stop();
  575. const pathname = window.location.pathname;
  576. let searchpath = `${pathname}${window.location.search}`;
  577. selectedInstance = twitter[1]
  578. ? `${farsideInstance}/nitter`
  579. : await getrandom(Instances.nitter);
  580. if (pathname === "/i/flow/login")
  581. searchpath = searchpath.replace(
  582. "/i/flow/login?redirect_after_login=",
  583. "",
  584. );
  585. if (searchpath.includes("%")) searchpath = decodeURIComponent(searchpath);
  586. newURL = `${scheme}${selectedInstance}${searchpath}${hash}`;
  587. window.location.replace(newURL);
  588. }
  589. }
  590. async function redirectReddit() {
  591. if (reddit[0] && !window.location.pathname.startsWith("/domain")) {
  592. window.stop();
  593. let pathname = window.location.pathname;
  594. let search = window.location.search;
  595. selectedInstance = reddit[1]
  596. ? `${farsideInstance}/${redditFrontend}`
  597. : await getrandom(Instances[redditFrontend]);
  598. if (pathname === "/media" && search) {
  599. const params = new URLSearchParams(search);
  600. const mediaURL = new URL(params.get("url"));
  601. if (["i.redd.it", "preview.redd.it"].includes(mediaURL.hostname)) {
  602. pathname = `/img${mediaURL.pathname}`;
  603. search = mediaURL.search;
  604. }
  605. }
  606. newURL = `${scheme}${selectedInstance}${pathname}${search}${hash}`;
  607. window.location.replace(newURL);
  608. }
  609. }
  610. async function redirectYoutube(frontend) {
  611. if (youtube[0]) {
  612. window.stop();
  613. let searchpath = `${window.location.pathname}${window.location.search}`;
  614. if (window.location.pathname.startsWith("/embed")) {
  615. selectedInstance = youtube[1]
  616. ? `${farsideInstance}/invidious`
  617. : await getrandom(Instances["invidious"]);
  618. newURL = `${scheme}${selectedInstance}${window.location.pathname}${
  619. window.location.search
  620. }${hash}`;
  621. window.location.replace(newURL);
  622. } else {
  623. if (frontend === "tubo") {
  624. selectedInstance = await getrandom(Instances.tubo);
  625. searchpath = `/stream?url=${window.location.href}`;
  626. if (
  627. window.location.pathname.startsWith("/@") ||
  628. window.location.pathname.startsWith("/channel")
  629. )
  630. searchpath = `/channel?url=${window.location.href}`;
  631. } else if (frontend === "freetube") {
  632. let youtube_link = window.location.href;
  633. window.location.replace(`freetube://${youtube_link}`);
  634. return;
  635. } else {
  636. selectedInstance =
  637. youtube[1] && frontend !== "hyperpipe"
  638. ? `${farsideInstance}/${frontend}`
  639. : await getrandom(Instances[frontend]);
  640. }
  641. newURL = `${scheme}${selectedInstance}${searchpath}${hash}`;
  642. window.location.replace(newURL);
  643. }
  644. }
  645. }
  646. async function redirectTiktok() {
  647. if (tiktok[0]) {
  648. window.stop();
  649. let pathname = window.location.pathname;
  650. selectedInstance = tiktok[1]
  651. ? `${farsideInstance}/proxitok`
  652. : await getrandom(Instances.proxitok);
  653. await Promise.any(
  654. [
  655. ["/@/", "/@placeholder/"],
  656. ["/discover/", "/tag/"],
  657. ["/foryou", "/trending"],
  658. ].map(async ([key, value]) => {
  659. if (pathname.startsWith(key)) pathname = pathname.replace(key, value);
  660. }),
  661. );
  662. newURL = `${scheme}${selectedInstance}${pathname}${window.location.search}${
  663. hash
  664. }`;
  665. window.location.replace(newURL);
  666. }
  667. }
  668. async function redirectImgur() {
  669. if (imgur[0]) {
  670. window.stop();
  671. selectedInstance = imgur[1]
  672. ? `${farsideInstance}/rimgo`
  673. : await getrandom(Instances.rimgo);
  674. newURL = `${scheme}${selectedInstance}${window.location.pathname}${
  675. window.location.search
  676. }${hash}`;
  677. window.location.replace(newURL);
  678. }
  679. }
  680. async function redirectMedium(frontend) {
  681. if (medium[0]) {
  682. let pathname = window.location.pathname;
  683. const host_path = `${window.location.hostname}${pathname}`;
  684. if (
  685. (/^.+?\.medium\.com\/.+/.test(host_path) ||
  686. /^\/@?[^\/]+?\//.test(pathname) ||
  687. host_path === "medium.com/") &&
  688. !(
  689. /^\/(tag|m|hc)\//.test(pathname) ||
  690. /\/(about|followers|following)/.test(pathname)
  691. )
  692. ) {
  693. window.stop();
  694. selectedInstance =
  695. medium[1] && frontend === "scribe"
  696. ? `${farsideInstance}/scribe`
  697. : await getrandom(Instances[frontend]);
  698. const username = window.location.hostname.replace(/\.?medium\.com/, "");
  699. if (username) pathname = `/${username}${pathname}`;
  700. newURL = `${scheme}${selectedInstance}${pathname}${
  701. window.location.search
  702. }${hash}`;
  703. window.location.replace(newURL);
  704. }
  705. }
  706. }
  707. async function redirectHackerNews() {
  708. if (hackernews[0]) {
  709. let pathname = window.location.pathname;
  710. if (
  711. ["/newest", "/item", "/user", "/ask", "/show", "/jobs", "/"].includes(
  712. pathname,
  713. )
  714. ) {
  715. if (
  716. hackernewsFrontend === "better" &&
  717. window.location.pathname === "/newest"
  718. )
  719. pathname = "/new";
  720. selectedInstance = Instances.hackernews[hackernewsFrontend];
  721. } else if (
  722. ["/best", "/news", "/submitted", "/threads", "/classic"].includes(
  723. pathname,
  724. )
  725. ) {
  726. selectedInstance = Instances.hackernews.worker;
  727. }
  728. if (selectedInstance) {
  729. window.stop();
  730. newURL = `${scheme}${selectedInstance}${pathname}${window.location.search}`;
  731. window.location.replace(newURL);
  732. }
  733. }
  734. }
  735. async function redirectGTranslate() {
  736. if (gtranslate[0]) {
  737. window.stop();
  738. let pathname = window.location.pathname;
  739. switch (googleTranslateFrontend) {
  740. case "lingva":
  741. selectedInstance = gtranslate[1]
  742. ? `${farsideInstance}/lingva`
  743. : await getrandom(Instances.lingva);
  744. if (window.location.search) {
  745. const params = new URLSearchParams(window.location.search);
  746. pathname = `/${params.get("sl")}/${params.get("tl")}/${params.get(
  747. "text",
  748. )}`;
  749. } else if (/^\/\w+?\/\w+?\/.*/.test(pathname)) {
  750. pathname = pathname.replace(/\+/g, " ");
  751. }
  752. newURL = `${scheme}${selectedInstance}${pathname}`;
  753. break;
  754. case "mozhi":
  755. selectedInstance = await getrandom(Instances.mozhi);
  756. if (window.location.search) {
  757. const params = new URLSearchParams(window.location.search);
  758. pathname = `?text=${params.get(
  759. "text",
  760. )}&from=${params.get("sl")}&to=${params.get("tl")}&engine=google`;
  761. newURL = `${scheme}${selectedInstance}${pathname}`;
  762. } else {
  763. newURL = `${scheme}${selectedInstance}`;
  764. }
  765. break;
  766. default:
  767. break;
  768. }
  769. window.location.replace(newURL);
  770. }
  771. }
  772. async function redirectDeviantart() {
  773. window.stop();
  774. let pathname = window.location.pathname;
  775. let query = window.location.search;
  776. let parts = pathname.split("/").filter((n) => n);
  777. let pathnameMatch = "";
  778. selectedInstance = await getrandom(Instances.skunkyart);
  779. let patterns = {
  780. post: /\/art\/\S+/,
  781. tag: /\/tag\/\S+/,
  782. search: /(?<=\?q=)[^&]+/,
  783. gallery: /\/\w+\/gallery$/,
  784. gallery_folder: /\/\w+\/gallery\/\d+/,
  785. favorites: /\/(\w+)\/favourites/,
  786. profile: /^\/(\w+)$/,
  787. };
  788. if (deviantart[0]) {
  789. if (patterns.post.test(pathname)) {
  790. pathnameMatch = `/post/${parts[0].toLowerCase()}/${parts[2]}`;
  791. } else if (patterns.tag.test(pathname)) {
  792. pathnameMatch = `/search?q=${parts[1]}&type=tag`;
  793. } else if (pathname.startsWith("/search")) {
  794. query = query.match(patterns.search)[0];
  795. pathnameMatch = `/search?q=${query}&type=all`;
  796. } else if (patterns.gallery.test(pathname)) {
  797. pathnameMatch = `/group_user?type=gallery&q=${parts[0]}`;
  798. } else if (patterns.gallery_folder.test(pathname)) {
  799. pathnameMatch = `/group_user?folder=${parts[2]}&q=${parts[0]}&type=g`;
  800. } else if (patterns.favorites.test(pathname)) {
  801. pathnameMatch = `/group_user?q=${pathname.match(patterns.favorites)[1]}&type=favorites`;
  802. } else if (patterns.profile.test(pathname)) {
  803. pathnameMatch = `/group_user?type=about&q=${pathname.match(patterns.profile)[1]}`;
  804. }
  805. }
  806. newURL = `${scheme}${selectedInstance}${pathnameMatch}`;
  807. window.location.replace(newURL);
  808. }
  809. async function redirectDeepl() {
  810. if (deepl[0]) {
  811. window.stop();
  812. selectedInstance = await getrandom(Instances.mozhi);
  813. if (window.location.hash) {
  814. let hash_parts = window.location.hash.substring(1).split("/");
  815. let pathname = `?text=${hash_parts[2]}&from=${hash_parts[0]}&to=${
  816. hash_parts[1]
  817. }&engine=deepl`;
  818. newURL = `${scheme}${selectedInstance}${pathname}`;
  819. }
  820. window.location.replace(newURL);
  821. }
  822. }
  823. async function redirectTumblr() {
  824. if (tumblr[0]) {
  825. window.stop();
  826. selectedInstance = await getrandom(Instances.priviblur);
  827. newURL = `${scheme}${selectedInstance}${window.location.pathname}${
  828. window.location.search
  829. }${hash}`;
  830. window.location.replace(newURL);
  831. }
  832. }
  833. async function redirectReuters() {
  834. if (reuters[0]) {
  835. window.stop();
  836. selectedInstance = await getrandom(Instances.neuters);
  837. newURL = `${scheme}${selectedInstance}${window.location.pathname}${
  838. window.location.search
  839. }${hash}`;
  840. window.location.replace(newURL);
  841. }
  842. }
  843. async function redirectWikipedia() {
  844. if (wikipedia[0]) {
  845. window.stop();
  846. let langCode = /^([a-z\-]+)\./.exec(window.location.hostname)[1];
  847. selectedInstance = wikipedia[1]
  848. ? `${farsideInstance}/wikiless`
  849. : await getrandom(Instances.wikiless);
  850. if (langCode === "www") langCode = "en";
  851. newURL = `${scheme}${selectedInstance}${window.location.pathname}?lang=${
  852. langCode
  853. }${hash}`;
  854. window.location.replace(newURL);
  855. }
  856. }
  857. async function redirectImdb() {
  858. if (imdb[0]) {
  859. window.stop();
  860. selectedInstance = imdb[1]
  861. ? `${farsideInstance}/libremdb`
  862. : await getrandom(Instances.libremdb);
  863. newURL = `${scheme}${selectedInstance}${window.location.pathname}${
  864. window.location.search
  865. }${hash}`;
  866. window.location.replace(newURL);
  867. }
  868. }
  869. async function redirectQuora() {
  870. if (quora[0]) {
  871. window.stop();
  872. selectedInstance = quora[1]
  873. ? `${farsideInstance}/quetre`
  874. : await getrandom(Instances.quetre);
  875. newURL = `${scheme}${selectedInstance}${window.location.pathname}${
  876. window.location.search
  877. }${hash}`;
  878. window.location.replace(newURL);
  879. }
  880. }
  881. async function redirectFandom() {
  882. if (fandom[0]) {
  883. window.stop();
  884. const fandomName = window.location.hostname.replace(/\..+/, "");
  885. selectedInstance = await getrandom(Instances.breezewiki);
  886. let pathname = window.location.pathname;
  887. if (fandomName !== "www") pathname = `/${fandomName}${pathname}`;
  888. newURL = `${scheme}${selectedInstance}${pathname}${window.location.search}${
  889. hash
  890. }`;
  891. window.location.replace(newURL);
  892. }
  893. }
  894. async function redirectGoogle() {
  895. if (
  896. google[0] &&
  897. window.location.hostname.startsWith("www") &&
  898. window.location.pathname.startsWith("/search")
  899. ) {
  900. window.stop();
  901. selectedInstance = google[1]
  902. ? `${farsideInstance}/${googleFrontend}`
  903. : (selectedInstance = await getrandom(Instances[googleFrontend]));
  904. let pathname = window.location.pathname;
  905. if (googleFrontend === "librey" && pathname === "/search")
  906. pathname += ".php";
  907. const params = new URLSearchParams(window.location.search);
  908. const query = params.entries().q;
  909. const search = query ? `?q=${query}` : window.location.search;
  910. newURL = `${scheme}${selectedInstance}${pathname}${search}${hash}`;
  911. window.location.replace(newURL);
  912. }
  913. }
  914. async function redirectGoodreads() {
  915. if (goodreads[0]) {
  916. window.stop();
  917. selectedInstance = await getrandom(Instances.biblioreads);
  918. if (window.location.pathname.startsWith("/search")) {
  919. const params = new URLSearchParams(search);
  920. search = `/${params.get("q")}`;
  921. }
  922. newURL = `${scheme}${selectedInstance}${window.location.pathname}${search}${
  923. hash
  924. }`;
  925. window.location.replace(newURL);
  926. }
  927. }
  928. async function redirectStackoverflow() {
  929. if (
  930. stackoverflow[0] &&
  931. (window.location.pathname.startsWith("/questions/") ||
  932. window.location.pathname === "/")
  933. ) {
  934. window.stop();
  935. selectedInstance = stackoverflow[1]
  936. ? `${farsideInstance}/anonymousoverflow`
  937. : await getrandom(Instances.anonymousoverflow);
  938. newURL = `${scheme}${selectedInstance}${window.location.pathname}${
  939. window.location.search
  940. }${hash}`;
  941. window.location.replace(newURL);
  942. }
  943. }
  944. async function redirectBandcamp() {
  945. if (bandcamp[0]) {
  946. // thanks to libredirect
  947. selectedInstance = await getrandom(Instances.tent);
  948. const params = new URLSearchParams(window.location.search);
  949. const artist = window.location.hostname.replace(/\..+/, "");
  950. const regex = /^\/([^\/]+?)\/(.+)/.exec(window.location.pathname);
  951. const audio = /^\/stream\/([a-f0-9]+?)\/([^\/]+?)\/([0-9]+)/.exec(
  952. window.location.pathname,
  953. );
  954. const image = /^\/img\/(.+)/.exec(window.location.pathname);
  955. let searchpath = "";
  956. switch (true) {
  957. case window.location.pathname === "/search":
  958. searchpath = `/search.php?query=${params.get("q")}`;
  959. break;
  960. case window.location.hostname.search(/(daily)?\.bandcamp\.com/) > 0:
  961. if (window.location.pathname === "/") {
  962. searchpath = `/artist.php?name=${artist}`;
  963. } else if (regex.length > 2) {
  964. searchpath = `/release.php?artist=${artist}&type=${regex[1]}&name=${regex[2]}`;
  965. }
  966. break;
  967. case window.location.hostname === "f4.bcbits.com":
  968. if (image.length > 1) searchpath = `/image.php?file=${image[1]}`;
  969. break;
  970. case window.location.hostname === "t4.bcbits.com":
  971. if (audio.length > 3)
  972. searchpath = `/audio.php?directory=${audio[1]}&format=${
  973. audio[2]
  974. }&file=${audio[3]}&token=${params.get("token")}`;
  975. break;
  976. default:
  977. return;
  978. }
  979. window.stop();
  980. newURL = `${scheme}${selectedInstance}${searchpath}`;
  981. window.location.replace(newURL);
  982. }
  983. }
  984. async function redirectGenius() {
  985. if (genius[0]) {
  986. const pathname = window.location.pathname;
  987. selectedInstance = await getrandom(Instances[geniusFrontend]);
  988. await Promise.any(
  989. [
  990. ["lyrics", pathname.endsWith("-lyrics")],
  991. ["album", pathname.startsWith("/albums/")],
  992. ["artist", pathname.startsWith("/artists/")],
  993. [, ["/", "/search"].includes(pathname)],
  994. ].map(async ([key, value]) => {
  995. if (value) {
  996. const searchpath =
  997. geniusFrontend === "intellectual" && key
  998. ? `/${key}?path=${pathname.slice(1)}`
  999. : `${pathname}${window.location.search}`;
  1000. window.stop();
  1001. newURL = `${scheme}${selectedInstance}${searchpath}${hash}`;
  1002. window.location.replace(newURL);
  1003. }
  1004. }),
  1005. );
  1006. }
  1007. }
  1008. async function redirectPinterest() {
  1009. if (pinterest[0]) {
  1010. selectedInstance = await getrandom(Instances.binternet);
  1011. let searchpath = "";
  1012. if (window.location.hostname === "i.pinimg.com") {
  1013. searchpath = `/image_proxy.php?url=${window.location.href}`;
  1014. } else if (window.location.pathname.startsWith("/search")) {
  1015. searchpath = `${window.location.pathname
  1016. .replace("search", "search.php")
  1017. .replace("/pins/", "")}${window.location.search}`;
  1018. } else if (window.location.pathname !== "/") return;
  1019. window.stop();
  1020. newURL = `${scheme}${selectedInstance}${searchpath}`;
  1021. window.location.replace(newURL);
  1022. }
  1023. }
  1024. async function redirectSoundcloud() {
  1025. if (soundcloud[0]) {
  1026. window.stop();
  1027. selectedInstance = await getrandom(Instances.tubo);
  1028. let searchpath = "/kiosk?serviceId=1";
  1029. if (window.location.pathname !== "/")
  1030. searchpath = `/stream?url=${window.location.href}`;
  1031. newURL = `${scheme}${selectedInstance}${searchpath}`;
  1032. window.location.replace(newURL);
  1033. }
  1034. }
  1035. async function redirectPixiv() {
  1036. if (pixiv[0]) {
  1037. window.stop();
  1038. selectedInstance = await getrandom(Instances.pixivfe);
  1039. const pathname = window.location.pathname.replace(/^\/\w{2}\//, "/");
  1040. newURL = `${scheme}${selectedInstance}${pathname}${window.location.search}`;
  1041. window.location.replace(newURL);
  1042. }
  1043. }
  1044. async function redirectTwitch() {
  1045. if (twitch[0]) {
  1046. window.stop();
  1047. selectedInstance = await getrandom(Instances.safetwitch);
  1048. const pathname =
  1049. window.location.pathname == "/search"
  1050. ? window.location.pathname + "/"
  1051. : window.location.pathname;
  1052. let searchpath =
  1053. window.location.pathname == "/search"
  1054. ? window.location.search.replace("term", "query")
  1055. : window.location.search;
  1056. newURL = `${scheme}${selectedInstance}${pathname}${searchpath}`;
  1057. window.location.replace(newURL);
  1058. }
  1059. }
  1060. const urlHostname = window.location.hostname;
  1061. switch (urlHostname) {
  1062. case "www.instagram.com":
  1063. redirectInstagram();
  1064. break;
  1065. case "twitter.com":
  1066. case "mobile.twitter.com":
  1067. case "x.com":
  1068. case "mobile.x.com":
  1069. redirectTwitter();
  1070. break;
  1071. case "www.youtube.com":
  1072. case "m.youtube.com":
  1073. case "www.youtube-nocookie.com":
  1074. redirectYoutube(youtubeFrontend);
  1075. break;
  1076. case "www.tiktok.com":
  1077. redirectTiktok();
  1078. break;
  1079. case "music.youtube.com":
  1080. redirectYoutube(youtubeMusicFrontend);
  1081. break;
  1082. case "news.ycombinator.com":
  1083. redirectHackerNews();
  1084. break;
  1085. case "translate.google.com":
  1086. redirectGTranslate();
  1087. break;
  1088. case "www.reuters.com":
  1089. redirectReuters();
  1090. break;
  1091. case "www.imdb.com":
  1092. case "m.imdb.com":
  1093. redirectImdb();
  1094. break;
  1095. case "www.quora.com":
  1096. redirectQuora();
  1097. break;
  1098. case "www.google.com":
  1099. redirectGoogle();
  1100. break;
  1101. case "www.goodreads.com":
  1102. redirectGoodreads();
  1103. break;
  1104. case "genius.com":
  1105. redirectGenius();
  1106. break;
  1107. case "stackoverflow.com":
  1108. redirectStackoverflow();
  1109. break;
  1110. case "f4.bcbits.com":
  1111. case "t4.bcbits.com":
  1112. redirectBandcamp();
  1113. break;
  1114. case "www.deviantart.com":
  1115. redirectDeviantart();
  1116. break;
  1117. case "i.pinimg.com":
  1118. redirectPinterest();
  1119. break;
  1120. case "soundcloud.com":
  1121. case "m.soundcloud.com":
  1122. redirectSoundcloud();
  1123. break;
  1124. case "www.pixiv.net":
  1125. redirectPixiv();
  1126. break;
  1127. case "www.deepl.com":
  1128. redirectDeepl();
  1129. break;
  1130. case "twitch.tv":
  1131. case "www.twitch.tv":
  1132. redirectTwitch();
  1133. break;
  1134. case urlHostname.includes("reddit.com") ? urlHostname : 0:
  1135. redirectReddit();
  1136. break;
  1137. case urlHostname.includes("medium.com") ? urlHostname : 0:
  1138. redirectMedium(mediumFrontend);
  1139. break;
  1140. case urlHostname.includes("imgur.com") ? urlHostname : 0:
  1141. case urlHostname.includes("imgur.io") ? urlHostname : 0:
  1142. redirectImgur();
  1143. break;
  1144. case urlHostname.includes("wikipedia.org") ? urlHostname : 0:
  1145. redirectWikipedia();
  1146. break;
  1147. case urlHostname.includes("fandom.com") ? urlHostname : 0:
  1148. redirectFandom();
  1149. break;
  1150. case urlHostname.includes("bandcamp.com") ? urlHostname : 0:
  1151. redirectBandcamp();
  1152. break;
  1153. case urlHostname.includes("pinterest.com") ? urlHostname : 0:
  1154. redirectPinterest();
  1155. break;
  1156. case urlHostname.includes("tumblr.com") ? urlHostname : 0:
  1157. redirectTumblr();
  1158. break;
  1159. }
  1160. // export module for the test in github action
  1161. typeof module !== "undefined"
  1162. ? (module.exports = { Instances: Instances })
  1163. : true;