Khan Academy Problem Solver

Here is a Khan Academy Solver!

目前为 2021-11-27 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name Khan Academy Problem Solver
  3. // @version 2.1
  4. // @description Here is a Khan Academy Solver!
  5. // @author Logzilla6
  6. // @match https://www.khanacademy.org/*
  7. // @grant none
  8. // @namespace https://gf.qytechs.cn/users/783447
  9. // ==/UserScript==
  10.  
  11. (function () {
  12. let overlayHTML = ` <link rel="preconnect" href="https://fonts.googleapis.com">
  13. <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  14. <link href="https://fonts.googleapis.com/css2?family=Roboto&display=swap" rel="stylesheet">
  15. <div id="box">
  16. <button class="ou" id="accordian">Toggle</button>
  17. <div class="ou" id="box2">
  18. <p style="color:white;"> KhanHack </p>
  19. <section><label>Answer: [<label id="ans1">...</label>]</label></section>
  20. <section><label>&nbsp;</label></section>
  21. <section><label> </label></section>
  22. <section><label>Next And Last Answer: [<label id="ans2"></label>]</label></section>
  23. <section><label>&nbsp;</label></section>
  24. <section><label>M to hide "Toggle"</label></section>
  25.  
  26.  
  27. </div>
  28. </div>
  29. <style>
  30. #box {
  31. z-index: 1090;
  32. position: fixed;
  33. top: 0;
  34. right: 0;}
  35. #box2 {
  36. padding: 15px;
  37. margin-bottom: 5px;
  38. display: none};
  39. section {
  40. display: flex;
  41. justify-content: space-between;margin:5px;}
  42. .ou {
  43. background-color: #072357;
  44. letter-spacing: 2px;
  45.  
  46. font-weight: none;
  47. font-size: 11px;
  48. font-family: 'Roboto', sans-serif;
  49. color:white;}
  50. p { text-align: center;border-bottom:1px solid white;}
  51. #ytlink { border:0;}
  52. #ytlink a{ color:lime;}
  53. #accordian {
  54. width: 100%;
  55. border:0;
  56. cursor: pointer;}
  57. label { font-weight: bold;}
  58. input {
  59. margin-top: auto;
  60. margin-bottom: auto;
  61. transform: scale(1.3);}
  62. input:hover { cursor: pointer;}
  63. input:focus { box-shadow: 0 0 10px #9ecaed;}
  64. input[type=checkbox] { transform: scale(2.2);outline=none;}
  65. input[type=radio] { border-top: auto;}
  66. input[type=color] { width: 50px;}
  67. .checked {
  68. height: 20px;
  69. width: 20px;
  70. box-shadow: -1px -2px 5px gray;
  71. border: 3px solid gray;
  72. background-color: #17e34d;
  73. margin-top: auto;
  74. margin-bottom: auto;
  75. box-shadow: 2 2 2px #a0a0a0;
  76. width:20px;
  77. transform: scale(1.5);}
  78. .notchecked { background-color: red;}
  79.  
  80.  
  81.  
  82.  
  83.  
  84. ._eqjto6h {
  85. -webkit-box-pack: center !important;
  86. -ms-flex-pack: center !important;
  87. -webkit-box-align: center !important;
  88. -ms-flex-align: center !important;
  89. display: -webkit-box !important;
  90. display: -moz-box !important;
  91. display: -ms-flexbox !important;
  92. display: -webkit-flex !important;
  93. display: flex !important;
  94. -webkit-align-items: center !important;
  95. align-items: center !important;
  96. -webkit-justify-content: center !important;
  97. justify-content: center !important;
  98. position: absolute !important;
  99. max-width: 5% !important;
  100. width: 48
  101. px
  102. !important;
  103. top: 0
  104. px
  105. !important;
  106. height: 0% !important;
  107. color: white !important;
  108. -webkit-user-select: none !important;
  109. -moz-user-select: none !important;
  110. -ms-user-select: none !important;
  111. user-select: none !important;
  112. -webkit-tap-highlight-color: transparent !important;
  113. background: none !important;
  114. border: none !important;
  115. right: 0
  116. px
  117. !important;
  118. }
  119.  
  120.  
  121. </style>
  122. `
  123.  
  124.  
  125. function get(x) { return document.getElementById(x); }
  126.  
  127. let overlay = document.createElement("div");
  128. overlay.innerHTML = overlayHTML;
  129. document.body.appendChild(overlay);
  130.  
  131. let acc = get("accordian"),
  132. aimbot = get("aimbot");
  133.  
  134. acc.onclick = function() {
  135. let panel = get("box2");
  136. if (panel.style.display == "grid") panel.style.display = "none";
  137. else { panel.style.display = "grid"; }
  138. }
  139. document.addEventListener('keydown', (event) => {
  140. if (event.key === 'm') {
  141. let panel2 = get("box2")
  142. panel2.style.display = "none"
  143. let panel = get("accordian");
  144. if (panel.style.display == "none" && panel2.style.display == "none") panel.style.display = "grid";
  145. else { panel.style.display = "none"; }
  146. if (panel2.style.display == "grid" && panel.style.display == "grid") {
  147. panel2.style.display = "none"
  148. panel.style.display = "none"
  149. }
  150. return;
  151. }
  152. });
  153.  
  154.  
  155.  
  156. 'use strict';
  157. window.loaded = false;
  158. alert("Look at top right for 'Toggle'")
  159. class Answer {
  160. constructor(answer, type) {
  161. this.body = answer;
  162. this.type = type;
  163. }
  164.  
  165. get isMultiChoice() {
  166. return this.type == "multiple_choice";
  167. }
  168.  
  169. get isFreeResponse() {
  170. return this.type == "free_response";
  171. }
  172.  
  173. get isExpression() {
  174. return this.type == "expression";
  175. }
  176.  
  177. get isDropdown() {
  178. return this.type == "dropdown";
  179. }
  180.  
  181. log() {
  182. const answer = this.body;
  183. const style = "color: coral; -webkit-text-stroke: .5px black; font-size:24px; font-weight:bold;";
  184.  
  185. answer.map(ans => {
  186. if (typeof ans == "string") {
  187. if (ans.includes("web+graphie")) {
  188. this.body[this.body.indexOf(ans)] = "";
  189. this.printImage(ans);
  190. } else {
  191. answer[answer.indexOf(ans)] = ans.replaceAll("$", "");
  192. }
  193. }
  194. });
  195.  
  196. const text = answer.join("\n");
  197. if (text) {
  198. console.log(`${text.trim()}`, style);
  199. }
  200. }
  201.  
  202. printImage(ans) {
  203. const url = ans.replace("![](web+graphie", "https").replace(")", ".svg");
  204. const image = new Image();
  205.  
  206. image.src = url;
  207. image.onload = () => {
  208. const imageStyle = [
  209. 'font-size: 1px;',
  210. 'line-height: ', this.height % 2, 'px;',
  211. 'padding: ', this.height * .5, 'px ', this.width * .5, 'px;',
  212. 'background-size: ', this.width, 'px ', this.height, 'px;',
  213. 'background: url(', url, ');'
  214. ].join(' ');
  215. console.log('', imageStyle);
  216. };
  217. }
  218. }
  219.  
  220. const originalFetch = window.fetch;
  221. window.fetch = function () {
  222. return originalFetch.apply(this, arguments).then((res) => {
  223. if (res.url.includes("/getAssessmentItem")) {
  224. const clone = res.clone();
  225. clone.json().then(json => {
  226. let item, question;
  227.  
  228. try {
  229. item = json.data.assessmentItem.item.itemData;
  230. question = JSON.parse(item).question;
  231. } catch {
  232. let errorIteration = () => { return localStorage.getItem("error_iter") || 0; }
  233. localStorage.setItem("error_iter", errorIteration() + 1);
  234.  
  235. if (errorIteration() < 4) {
  236. return location.reload();
  237. } else {
  238. return alert("An error occurred");
  239. }
  240. }
  241.  
  242. if (!question) return;
  243.  
  244. Object.keys(question.widgets).map(widgetName => {
  245. switch (widgetName.split(" ")[0]) {
  246. case "numeric-input":
  247. return freeResponseAnswerFrom(question).log();
  248. case "radio":
  249. return multipleChoiceAnswerFrom(question).log();
  250. case "expression":
  251. return expressionAnswerFrom(question).log();
  252. case "dropdown":
  253. return dropdownAnswerFrom(question).log();
  254. }
  255. });
  256. });
  257. }
  258.  
  259. return res;
  260. })
  261. }
  262.  
  263. function freeResponseAnswerFrom(question) {
  264. const answer = Object.values(question.widgets).map((widget) => {
  265. if (widget.options?.answers) {
  266. return widget.options.answers.map(answer => {
  267. if (answer.status == "correct") {
  268. //alert('freeresponse')
  269. var ans1 = document.getElementById('ans1').innerHTML
  270. var ans2 = document.getElementById('ans2').innerHTML
  271. document.getElementById('ans2').innerHTML = (answer.value)
  272. if (ans2 == "") {
  273. document.getElementById('ans1').innerHTML = (answer.value)
  274. }
  275. else {
  276. document.getElementById('ans1').innerHTML = (ans2)
  277. }
  278. }
  279. });
  280. }
  281. }).flat().filter((val) => { return val !== undefined; });
  282.  
  283. return new Answer(answer, "free_response");
  284. }
  285.  
  286. function multipleChoiceAnswerFrom(question) {
  287. const answer = Object.values(question.widgets).map((widget) => {
  288. if (widget.options?.choices) {
  289. return widget.options.choices.map(choice => {
  290. if (choice.correct) {
  291. //alert('multichoice')
  292. var ans1 = document.getElementById('ans1').innerHTML
  293. var ans2 = document.getElementById('ans2').innerHTML
  294. document.getElementById('ans2').innerHTML = (choice.content)
  295. if (ans2 == "") {
  296. document.getElementById('ans1').innerHTML = (choice.content)
  297. }
  298. else {
  299. document.getElementById('ans1').innerHTML = (ans2)
  300. }
  301. }
  302. });
  303. }
  304. }).flat().filter((val) => { return val !== undefined; });
  305.  
  306.  
  307. return new Answer(answer, "multiple_choice");
  308. }
  309.  
  310. function expressionAnswerFrom(question) {
  311. const answer = Object.values(question.widgets).map((widget) => {
  312. if (widget.options?.answerForms) {
  313. return widget.options.answerForms.map(answer => {
  314. if (Object.values(answer).includes("correct")) {
  315. //alert('expression')
  316. var ans1 = document.getElementById('ans1').innerHTML
  317. var ans2 = document.getElementById('ans2').innerHTML
  318. document.getElementById('ans2').innerHTML = (answer.value)
  319. if (ans2 == "") {
  320. document.getElementById('ans1').innerHTML = (answer.value)
  321. }
  322. else {
  323. document.getElementById('ans1').innerHTML = (ans2)
  324. }
  325. }
  326. });
  327. }
  328. }).flat();
  329.  
  330. return new Answer(answer, "expression");
  331. }
  332.  
  333. function dropdownAnswerFrom(question) {
  334. const answer = Object.values(question.widgets).map((widget) => {
  335. if (widget.options?.choices) {
  336. return widget.options.choices.map(choice => {
  337. if (choice.correct) {
  338. //alert('dropdown')
  339. var ans1 = document.getElementById('ans1').innerHTML
  340. var ans2 = document.getElementById('ans2').innerHTML
  341. document.getElementById('ans2').innerHTML = (choice.content)
  342. if (ans2 == "") {
  343. document.getElementById('ans1').innerHTML = (choice.content)
  344. }
  345. else {
  346. document.getElementById('ans1').innerHTML = (ans2)
  347. }
  348. }
  349. });
  350. }
  351.  
  352. }).flat();
  353.  
  354. return new Answer(answer, "dropdown");
  355.  
  356. }
  357. })();

QingJ © 2025

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