Greasy Fork

Greasy Fork is available in English.

粉笔网刷题宝

粉笔网优化布局,清屏快速生成pdf

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         粉笔网刷题宝
// @namespace    http://tampermonkey.net/
// @version      0.0.52
// @author       binyellow
// @icon         https://nodestatic.fbstatic.cn/weblts_spa_online/page/assets/fenbi32.ico
// @defaulticon  粉笔网优化布局,清屏快速生成pdf
// @match        *.fenbi.com/*
// @require      https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.js
// @grant        GM_addStyle
// @grant        GM_getValue
// @grant        GM_setClipboard
// @grant        GM_setValue
// @grant        GM_xmlhttpRequest
// @grant        unsafeWindow
// @description 粉笔网优化布局,清屏快速生成pdf
// ==/UserScript==

(async function ($) {
  'use strict';

  const processCls = `__binyellow__processed__`;
  function processElements(selector, callback) {
    function checkForMatchingNode(nodes) {
      for (const node of nodes) {
        if (node.matches && node.matches(selector)) {
          callback(node);
          return true;
        }
        if (node.querySelectorAll) {
          const matchingDescendant = node.querySelector(selector);
          if (matchingDescendant) {
            callback($(matchingDescendant));
            return true;
          }
        }
      }
      return false;
    }
    const observer = new MutationObserver((mutations) => {
      for (const mutation of mutations) {
        if (mutation.type === "childList") {
          if (checkForMatchingNode(mutation.addedNodes)) {
            observer.disconnect();
            break;
          }
        }
      }
    });
    observer.observe(document.body, { childList: true, subtree: true });
  }
  const mokao = () => {
    processElements(".exam-post-nav", (node) => {
      $(node).css({ left: 0, top: 0 });
      const detailContent = $(".solution-detail.clear-float");
      $(detailContent).css({ width: "100%" });
      const optionsUl = $(detailContent).find(".options.ng-star-inserted");
      $(optionsUl).css({ display: "flex", "justify-content": "space-between", "flex-wrap": "wrap" });
      optionsUl.children().css("margin", "0");
      $(detailContent).find(".exam-main-content.ng-tns-c3-0.ng-star-inserted").css({ width: "calc(100% - 302px)" });
      $(".practice-header").hide();
      $(detailContent).find(".solu-detail.ng-star-inserted").css({ margin: 0, padding: 0 });
      $(detailContent).find(".nav-coll-divider.solu-divider").css({ margin: "6px 0" });
      $(detailContent).find(".question-content > p:nth-child(2) > img").each(function() {
        var img = $(this);
        var width = img.width() || 0;
        var height = img.height() || 0;
        var newWidth = width * 0.6;
        var newHeight = height * 0.6;
        img.width(newWidth);
        img.height(newHeight);
      });
    });
  };
  const caogao = () => {
    processElements(".draft-icon", () => {
      $(".draft-icon").on("click", function() {
        console.log("draft-icon 被点击");
        $(document).on("keydown", function(event) {
          if (event.key === "Escape" || event.keyCode === 27) {
            $(".tool-item.exit").trigger("click");
            $(document).off("keydown");
          }
        });
      });
    });
  };
  var _GM_addStyle = /* @__PURE__ */ (() => typeof GM_addStyle != "undefined" ? GM_addStyle : void 0)();
  var _GM_getValue = /* @__PURE__ */ (() => typeof GM_getValue != "undefined" ? GM_getValue : void 0)();
  var _GM_setClipboard = /* @__PURE__ */ (() => typeof GM_setClipboard != "undefined" ? GM_setClipboard : void 0)();
  var _GM_setValue = /* @__PURE__ */ (() => typeof GM_setValue != "undefined" ? GM_setValue : void 0)();
  var _GM_xmlhttpRequest = /* @__PURE__ */ (() => typeof GM_xmlhttpRequest != "undefined" ? GM_xmlhttpRequest : void 0)();
  var _unsafeWindow = /* @__PURE__ */ (() => typeof unsafeWindow != "undefined" ? unsafeWindow : void 0)();
  const customExamUrlsKey = "__custom-exam-urls-key__";
  const customExamQuestionTypesKey = "__custom-exam-question-types-key__";
  const customExamContentsKey = "__custom-exam-contents-key__";
  const customExamMatchContent = "__custom-exam-match-content__";
  const getLinks = async () => _GM_getValue(customExamUrlsKey, []);
  const setLinks = async (link) => {
    await _GM_setValue(customExamUrlsKey, link);
  };
  const getOptions = async () => await _GM_getValue(customExamQuestionTypesKey);
  const setOptions = async (options) => {
    await _GM_setValue(customExamQuestionTypesKey, options);
  };
  const setContents = async (content) => {
    try {
      const pre = await getContents();
      await _GM_setValue(customExamContentsKey, [...pre, content]);
    } catch (error) {
      console.log(`setContent Error===>`, error);
      clearCustom();
    }
  };
  const getContents = async () => await _GM_getValue(customExamContentsKey);
  const getMatchContent = async () => await _GM_getValue(customExamMatchContent, "");
  const setMatchContent = async (content) => {
    await _GM_setValue(customExamMatchContent, content);
  };
  const clearCustom = async () => {
    await setLinks([]);
    await setOptions([]);
    await _GM_setValue(customExamContentsKey, []);
    await setMatchContent("");
    await _GM_setValue(cacheExamNameFLag, false);
    await _GM_setValue(cacheExamName, void 0);
    await _GM_setValue(pdfExamNameArr, []);
  };
  const xhrInterceptor = (rules, cb, resCb) => {
    const originalXHR = _unsafeWindow.XMLHttpRequest;
    _unsafeWindow.XMLHttpRequest = function() {
      const xhr = new originalXHR();
      const originalOpen = xhr.open;
      xhr.open = function() {
        const method = arguments[0];
        const url = arguments[1];
        const matchedRule = rules.find((rule) => {
          if (typeof rule.url === "string") {
            return rule.url === url && (!rule.method || rule.method === method);
          } else if (rule.url instanceof RegExp) {
            return rule.url.test(url) && (!rule.method || rule.method === method);
          } else {
            return false;
          }
        });
        if (matchedRule) {
          console.log("XHR request: " + method + " " + url);
          this._url = url;
          this._method = method;
        }
        originalOpen.apply(this, arguments);
      };
      const originalSend = xhr.send;
      xhr.send = function() {
        const body = arguments[0];
        if (this._url) {
          console.log(`send===>`, arguments, this._headers);
          this._body = body;
          console.log("XHR request body: " + body, this._url, this._headers);
          cb({
            url: this._url,
            method: this._method,
            body: this._body,
            headers: this._headers
          });
        }
        originalSend.apply(this, arguments);
      };
      const originalSetRequestHeader = xhr.setRequestHeader;
      xhr.setRequestHeader = function(header, value) {
        if (this._url) {
          if (!this._headers) {
            this._headers = {};
          }
          this._headers[header] = value;
        }
        originalSetRequestHeader.apply(this, arguments);
      };
      const originalOnReadyStateChange = xhr.onreadystatechange;
      xhr.onreadystatechange = function() {
        if (this.readyState === 4 && this._url) {
          resCb == null ? void 0 : resCb({
            url: this._url,
            method: this._method,
            body: this._body,
            headers: this._headers,
            status: this.status,
            statusText: this.statusText,
            responseText: this.responseText,
            response: JSON.parse(this.response),
            responseHeaders: this.getAllResponseHeaders()
          });
        }
        originalOnReadyStateChange == null ? void 0 : originalOnReadyStateChange.apply(this, arguments);
      };
      return xhr;
    };
  };
  const kuaiSuShuaTiKey = "__kuaiSuShuaTiKey__";
  const cacheExamNameFLag = "__cache_exam_name_flag__";
  const cacheExamName = "__cache_exam_name__";
  const pdfExamNameArr = "__pdf_exam_name_arr__";
  const setPdfNameArr = async (name) => {
    const preNameArr = await _GM_getValue(pdfExamNameArr, []);
    await _GM_setValue(pdfExamNameArr, [...preNameArr, name]);
  };
  const getPdfNameArr = async () => {
    return await _GM_getValue(pdfExamNameArr, []);
  };
  const genPdfName = async () => {
    var _a, _b;
    const nameArr = await getPdfNameArr();
    let years = [];
    const gmOptions = await getOptions();
    for (let i = 0; i < nameArr.length; i++) {
      let year = (_b = (_a = nameArr == null ? void 0 : nameArr[i]) == null ? void 0 : _a.match(/\d+/)) == null ? void 0 : _b[0];
      years.push(year);
    }
    const optionAddon = gmOptions ? "-" + (gmOptions == null ? void 0 : gmOptions.join("-")) : "";
    let result = years.join("-") + "年" + optionAddon;
    return result;
  };
  const jiankong = async () => {
    jiankongKuaiSuLianXi();
    await jianKongCustomName();
  };
  const jiankongKuaiSuLianXi = () => {
    const rules = [
      {
        url: "https://tiku.fenbi.com/api/xingce/exercises?app=web&kav=100&av=100&hav=100&version=3.0.0.0",
        method: "POST"
      }
    ];
    const callback = (config) => {
      _GM_setValue(kuaiSuShuaTiKey, config);
    };
    xhrInterceptor(rules, callback);
  };
  const jianKongCustomName = async () => {
    const flag = await _GM_getValue(cacheExamNameFLag);
    if (flag) {
      const rules = [
        {
          url: new RegExp("https://tiku.fenbi.com/api/xingce/exercises/*"),
          method: "GET"
        }
      ];
      const callback = (config) => {
        var _a, _b, _c, _d;
        const name = (_b = (_a = config == null ? void 0 : config.response) == null ? void 0 : _a.sheet) == null ? void 0 : _b.name;
        _GM_setValue(cacheExamName, (_d = (_c = config == null ? void 0 : config.response) == null ? void 0 : _c.sheet) == null ? void 0 : _d.name);
        setPdfNameArr(name);
      };
      xhrInterceptor(rules, () => {
      }, callback);
    }
  };
  const request = (props) => {
    const { body, ...rest } = props;
    return new Promise((resolve) => {
      _GM_xmlhttpRequest({
        onload: (data) => {
          resolve(data);
        },
        method: "POST",
        data: typeof body === "object" && !(body instanceof FormData) ? JSON.stringify(body) : body,
        ...rest
      });
    });
  };
  const lianxiUrl = `https://www.fenbi.com/spa/tiku/exam/practice/xingce/xingce`;
  function shenlun() {
    const leftSubject = $(".zhenti-body-left.zhenti-body-part.bg-color-gray-light5");
    leftSubject.find(".materials-container").css({ width: "100%", padding: 12 });
    leftSubject.find(".material-content.ng-tns-c41-0").css({ width: "100%" });
    leftSubject.find(".material-content.ng-tns-c41-0").find("#material").css({ width: "100%" });
    const rightAnser = $(".zhenti-body-right.zhenti-body-part");
    rightAnser.css({ flex: "none" });
    rightAnser.find(".questions-container").css({ "padding-left": "12px" });
  }
  const kuaisu = () => {
    processElements("main.exam-content", () => {
      const css = `
    .solu-list-item.video-item fb-ng-solution-detail-item,
    .bg-color-gray-light2.border-gray-light3.font-color-gray-mid.expend-btn,
    .simple-nav-header.bg-color-gray-bold,
    .nav-coll-divider,
    .solu-answer-text.clear-float {
      display: none
    }
    
    main.exam-content {
      margin: 0 !important
    }
    
    .options.choice-options.font-color-gray-mid {
      display: flex
    }
    
    .solu-list.border-gray-light4 {
      margin-top: 0
    }
    
    .solu-list-item.video-item {
      margin-bottom: 0
    }
    
    .fb-collpase-bottom {
      width: calc(100% - 1024px);
      right: 0;
    }
    
    .fb-collpase-bottom.bg-color-gray-mid {
      margin: 0;
      width: 100% !important
    }
    
    .fixedActions.bg-color-gray-bold {
      right: 0
    }
    `;
      _GM_addStyle(css);
      shenlun();
    });
    processElements(".fb-question-material", () => {
      $(".fb-question-material").css({ margin: 12 });
      $(".material-content").css({ padding: 0 });
      $(".ques-options-dry").css({ padding: 0 });
      $(".options.font-color-gray-mid").css({ display: "flex", "flex-flow": "wrap" });
    });
    processElements(".solution-item.bg-color-gray-bold", (node) => {
      const solution = $(node).find(".solu-list.border-gray-light4");
      $(solution).css({ padding: 8 });
      $(solution).find("fb-ng-solution-detail-answer").hide();
    });
    processElements(
      ".solution-item.bg-color-gray-bold>app-fb-solution>fb-ng-solution > div[_ngcontent-fenbi-web-exams-c75] > div[_ngcontent-fenbi-web-exams-c75]",
      (node) => {
        node.css({ position: "absolute", right: 0 });
      }
    );
    processElements(".options.font-color-gray-mid", (node) => {
      node.css({ display: "flex", "flex-flow": "wrap", "justify-content": "space-between" });
    });
    processElements("app-report-header-test .exam-report", () => {
      $(".fixedActions.bg-color-gray-bold").removeClass(processCls);
      processElements(".fixedActions.bg-color-gray-bold", () => {
        var newButton = $("<button>重刷</button>");
        $(".fixedActions.bg-color-gray-bold").children().first().before(newButton);
        newButton.on("click", async function() {
          const requestConfig = await _GM_getValue(kuaiSuShuaTiKey, null);
          const data = await request(requestConfig);
          const { id } = JSON.parse(data == null ? void 0 : data.response);
          location.href = `${lianxiUrl}/${id}/2`;
        });
      });
    });
  };
  const dealWidth = () => {
    const cssRules = `
@media (max-width: 1000px) {
.exam-content {
  width: calc(100% - 45px) !important;
}
#app-practice {
  min-width: 100% !important;
}
.tools-container {
left: 0;
}
.fb-collpase-bottom {
left: 0;
width: 100% !important;
}
}

@media (min-width: 1700px) {
  main.exam-content {
    width: 1600px !important;
  }

  aside.fb-collpase-bottom {
    width: calc(100% - 1600px) !important;
  }
}

.collapse-content {
}

.collapse-title {
  cursor: pointer;
  text-decoration: underline;
  color: blue;
}

.extra-dom {
  position: fixed;
  background-color: #fff;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 4px;
  box-sizing: content-box;
}

.extra-dom input[type=number] {
  width: 100%;
}
`;
    const styleTag = document.createElement("style");
    styleTag.innerHTML = cssRules;
    document.head.appendChild(styleTag);
  };
  function genQuestionTypes() {
    const options = [];
    $(".chapter-control-item").each(function() {
      const label = $(this).find(".font-color-gray-blod").text().slice(0, 2);
      const items = $(this).children("div").children().length;
      const rangeStart = options.length > 0 ? options[options.length - 1].range[1] + 1 : 1;
      const rangeEnd = rangeStart + items - 1;
      options.push({ label, range: [rangeStart, rangeEnd] });
    });
    return options;
  }
  const modalHtml = `
  <div class="modal" tabindex="-1" role="dialog" id="myModal">
    <div class="modal-dialog" role="document">
      <div class="modal-content">
        <div class="modal-header">
          <h3 class="modal-title">输入考试链接和选择选项</h3>
          <span type="button" class="close" data-dismiss="modal" aria-label="Close">
            <span aria-hidden="true">
              <svg t="1701174403239" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8094" width="24" height="24"><path d="M557.312 513.248l265.28-263.904c12.544-12.48 12.608-32.704 0.128-45.248-12.512-12.576-32.704-12.608-45.248-0.128l-265.344 263.936-263.04-263.84C236.64 191.584 216.384 191.52 203.84 204 191.328 216.48 191.296 236.736 203.776 249.28l262.976 263.776L201.6 776.8c-12.544 12.48-12.608 32.704-0.128 45.248 6.24 6.272 14.464 9.44 22.688 9.44 8.16 0 16.32-3.104 22.56-9.312l265.216-263.808 265.44 266.24c6.24 6.272 14.432 9.408 22.656 9.408 8.192 0 16.352-3.136 22.592-9.344 12.512-12.48 12.544-32.704 0.064-45.248L557.312 513.248z" p-id="8095" fill="#707070"></path></svg>
            </span>
          </span>
        </div>
        <div class="modal-body">
          <form id="myForm">
            <div class="form-group">
              <label for="examLink" class="sub-title">考试链接</label>
              <div class="input-group">
                <textarea class="form-control" id="examLink" rows="5" placeholder="输入考试链接,多个可回车输入"></textarea>
              </div>
            </div>
            <div class="form-group">
              <label class="sub-title">题干关键字</label>
              <div class="input-group regex">
                <input class="form-control" id="question-keywords" placeholder="输入题干关键字,可输入正则;如你想排除 aaa 之外的题干,可写入正则 /^(?!.*aaa).*$/"></input>
                <span>/^(?!.*aaa).*$/</span>
              </div>
            </div>
            <div class="form-group">
              <label class="sub-title">是否显示考试name</label>  
              <input type="checkbox" id="option-display-exam-name" name="display-exam-name" value="言语" checked>
            </div>
            <div class="form-group">
              <label class="sub-title">选择选项</label><br>
              <div class="exam-type">
                <div><input type="checkbox" id="option1" name="options" value="言语" checked><label for="option1">言语</label></div>
                <div><input type="checkbox" id="option2" name="options" value="数量" checked><label for="option2">数量</label></div>
                <div><input type="checkbox" id="option3" name="options" value="判断" checked><label for="option3">判断</label></div>
                <div><input type="checkbox" id="option4" name="options" value="资料" checked><label for="option4">资料</label></div>
                <div><input type="checkbox" id="option5" name="options" value="常识"><label for="option5">常识</label></div>
              </div>
            </div>
          </form>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-primary" id="submitForm">确认</button>
          <button type="button" class="btn btn-secondary" data-dismiss="modal" class="close">关闭</button>
        </div>
      </div>
    </div>
  </div>`;
  const modalCss = `
  <style>
    .modal {
      display: none;
      position: fixed;
      z-index: 1;
      left: 0;
      top: 0;
      width: 100vw;
      height: 100vh;
      overflow: auto;
      background-color: rgba(0, 0, 0, 0.4);
    }
    .modal-title {
      font-size: 18px;
    }
    .sub-title {
      margin-top: 8px;
      display: inline-block;
      font-weight: bold;
      font-size: 17px;
    }
    .modal-content {
      background-color: #fefefe;
      margin: 100px auto;
      padding: 20px;
      border: 1px solid #888;
      width: 80%;
      position: relative;
    }
    .close {
      color: #aaa;
      float: right;
      font-size: 20px;
      font-weight: bold;
      position: absolute;
      right: 10px;
      top: 10px;
    }
    .close:hover,
    .close:focus {
      color: black;
      text-decoration: none;
      cursor: pointer;
    }

    .exam-link-delete {}

    #examLink,#question-keywords {
      width: 100%;
    }

    .exam-type {
      display: flex;
      gap: 18px;
    }

    .regex {
      display: flex;
      gap: 8px;
    }
  </style>`;
  const bodyStyle = (inputValue, fontValue) => `<style>
  .fixedActions.bg-color-gray-bold,.fb-collpase-bottom, app-side-tool,.fb-question > div:last-child[_ngcontent-fenbi-web-exams-c68],div[_ngcontent-fenbi-web-exams-c69] > div[_ngcontent-fenbi-web-exams-c69],.content.font-color-gray-mid>p.ques-type {
  display: none;
  }

  .fb-question-options.fenbi-ng-utils > div[_ngcontent-fenbi-web-exams-c40],div.ques-options-dry {
padding: 16px 0 0 0;
margin-bottom: ${inputValue}px;
  }

  .options.font-color-gray-mid {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
  }

  .options.font-color-gray-mid > li {
margin: 0 !important;
  }
  [_nghost-fenbi-web-exams-c40] p, [_nghost-fenbi-web-exams-c40] .options-material {
  font-weight: normal;
  font-size: ${fontValue}px;
  }

  main.exam-content {
margin-right: 35px !important;
  }
  .material-nav.bg-color-gray-light {
  display: none;
  }
  </style>`;
  function escapeRegExp(string) {
    const [pattern, flags] = string.match(/^\/(.*)\/([a-z]*)$/).slice(1);
    const reg = new RegExp(pattern, flags);
    return reg;
  }
  function matchElement($element, matchContent) {
    if (matchContent instanceof RegExp) {
      if (matchContent.test($element.text())) {
        $element.show();
      } else {
        $element.hide();
      }
    } else if ($element.text().match(matchContent)) {
      $element.show();
    } else {
      $element.hide();
    }
  }
  const isExam = () => {
    const { pathname } = location;
    return pathname.slice(pathname.lastIndexOf("/") + 1) === "3";
  };
  function delay(ms) {
    return new Promise((resolve) => setTimeout(resolve, ms));
  }
  function isImageLoaded(img) {
    if (!img.complete) {
      return false;
    }
    if (typeof img.naturalWidth !== "undefined" && img.naturalWidth === 0) {
      return false;
    }
    return true;
  }
  async function scrollToNextImage() {
    var _a, _b;
    const images = $("#app-practice img").toArray().sort((a, b) => {
      var _a2, _b2;
      const aTop = ((_a2 = $(a).offset()) == null ? void 0 : _a2.top) ?? 0;
      const bTop = ((_b2 = $(b).offset()) == null ? void 0 : _b2.top) ?? 0;
      return aTop - bTop;
    });
    const filteredImages = images.filter((image, index) => {
      var _a2, _b2;
      if (index > 0) {
        const prevImage = images[index - 1];
        return (((_a2 = $(image).offset()) == null ? void 0 : _a2.top) ?? 0) !== (((_b2 = $(prevImage).offset()) == null ? void 0 : _b2.top) ?? 0);
      }
      return true;
    });
    const scrollContainer = $("#fenbi-web-exams");
    for (const image of filteredImages) {
      if (!isImageLoaded(image)) {
        await new Promise((resolve) => {
          $(image).on("load", function() {
            resolve();
          });
        });
      }
      const imagePositionInContainer = (((_a = $(image).offset()) == null ? void 0 : _a.top) ?? 0) - (((_b = scrollContainer.offset()) == null ? void 0 : _b.top) ?? 0) + (scrollContainer.scrollTop() ?? 0);
      await new Promise((resolve) => {
        scrollContainer.animate(
          {
            scrollTop: imagePositionInContainer
          },
          50,
          function() {
            resolve();
          }
        );
      });
      await delay(100);
    }
  }
  const customExamUrls = await( getLinks());
  const fixedActions = () => {
    let options = [];
    processElements(".chapter-control-item > div:nth-child(2) > fb-ng-ans-button", async () => {
      console.timeEnd("答题卡");
      options = genQuestionTypes();
      var clearScreenButton = $("<button>清屏</button>");
      const marginLabel = '<label for="ti-jian-ju">题间距</label>';
      var newInput = $('<input id="ti-jian-ju" type="number" value="180">');
      const fontLabel = '<label for="zi-ti">字体</label>';
      const fontInput = $('<input id="zi-ti" type="number" value="20">');
      const $settingContainer = $(`<div class="collapse">
  <a class="collapse-title">设置></a>
  <div class="collapse-content">
  </div>
</div>`);
      $settingContainer.find(".collapse-content").append(marginLabel, newInput, fontLabel, fontInput);
      const $checkboxContainer = $(`<div class="collapse">
  <a class="collapse-title">题型></a>
  <div class="collapse-content">
  </div>
</div>`);
      await options.forEach(async (option, index) => {
        let isChecked;
        const gmOptions = await getOptions();
        if (gmOptions == null ? void 0 : gmOptions.length) {
          isChecked = gmOptions == null ? void 0 : gmOptions.includes(option.label);
        } else {
          isChecked = option.label !== "常识";
        }
        const $checkbox = $(`<input type="checkbox" id="option-${index}" ${isChecked ? "checked" : ""} />`);
        const $label = $(`<label for="option-${index}">${option.label}</label>`);
        $checkboxContainer.find(".collapse-content").append($checkbox, $label);
      });
      const customBtn = $('<button id="showModal">自定义</button>');
      if (isExam()) {
        $(".fixedActions.bg-color-gray-bold").children().first().before($checkboxContainer);
      }
      const fixedActions2 = $(".fixedActions.bg-color-gray-bold");
      const width = fixedActions2.outerWidth() || 0;
      const extraDom = $("<div>", { class: "extra-dom" });
      extraDom.css({
        right: width + 4,
        top: "10vh",
        width: width + 6
      });
      extraDom.append(clearScreenButton, $settingContainer, $checkboxContainer);
      if (isExam()) {
        extraDom.append(customBtn);
      }
      $("body").append(extraDom);
      addCustomBtn();
      $(".collapse-title").on("click", function() {
        $(this).next(".collapse-content").slideToggle();
      });
      clearScreenButton.on("click", async function() {
        if (isExam()) {
          $(".exam-detail.bg-color-gray-bold > div").hide();
          const matchExamContent = await getMatchContent();
          options.forEach((option, index) => {
            const $checkbox = $(`#option-${index}`);
            if ($checkbox.prop("checked")) {
              const [start, end] = option.range;
              $(".exam-detail.bg-color-gray-bold > div").each(function(i) {
                const $element = $(this);
                if (i >= start - 1 && i < end) {
                  if (matchExamContent) {
                    let regMatchExamContent;
                    try {
                      regMatchExamContent = escapeRegExp(matchExamContent);
                    } catch (error) {
                      console.error(`RegExp error: ${error}`);
                      regMatchExamContent = matchExamContent;
                    }
                    matchElement($element, regMatchExamContent);
                  } else {
                    $element.show();
                  }
                }
              });
            }
          });
        }
        await scrollToNextImage();
        var examContent = $("main.exam-content").html();
        var inputValue = newInput.val();
        var fontValue = fontInput.val();
        const indexOfLink = customExamUrls == null ? void 0 : customExamUrls.indexOf(location.href);
        if (indexOfLink >= 0) {
          customExamUrls.splice(indexOfLink, 1);
          const examName = await _GM_getValue(cacheExamName);
          if (examName) {
            const examLink = $(
              `<a href=${location.href} target="_blank" style="margin-bottom: 8px; text-align: center; font-size: 18px; width: 100%;display: inline-block; ">`
            ).text(examName);
            $("main.exam-content").prepend(examLink);
            examContent = $("main.exam-content").html();
            console.log("examContent===>", examContent);
          }
          $("body").empty();
          await setContents(examContent);
          const newContents = await getContents();
          console.log(`设置content===>`, examContent, newContents);
          if ((customExamUrls == null ? void 0 : customExamUrls.length) > 0) {
            location.href = customExamUrls[0];
          } else {
            const gmContents = await getContents();
            appendExamContent(gmContents, inputValue, fontValue);
          }
          await setLinks(customExamUrls);
        } else {
          $("body").empty();
          appendExamContent(examContent, inputValue, fontValue);
        }
      });
      const link = await getLinks();
      if (link == null ? void 0 : link.length) {
        clearScreenButton.click();
      }
    });
  };
  const addCustomBtn = () => {
    $("head").append(modalCss);
    $("body").append(modalHtml);
    $("#showModal").on("click", function() {
      $("#myModal").show();
    });
    $("#submitForm").on("click", async function() {
      var _a;
      let links = [];
      const selectedOptions = [];
      const examLink = $("#examLink").val();
      if (examLink) {
        const inputLinks = (_a = examLink == null ? void 0 : examLink.split("\n")) == null ? void 0 : _a.filter((en) => en.trim());
        links = inputLinks;
        $("#examLink").val("");
      }
      $("input[name='options']:checked").each(function() {
        selectedOptions.push($(this).val());
      });
      const matchExamContent = $("#question-keywords").val();
      console.log("考试链接:", links);
      await setLinks(links);
      console.log("选中的选项:", selectedOptions);
      await setOptions(selectedOptions);
      await setMatchContent(matchExamContent);
      await _GM_setValue(cacheExamNameFLag, $("#option-display-exam-name").prop("checked"));
      $("#myModal").hide();
      if ((links == null ? void 0 : links.length) > 0)
        location.href = links[0];
    });
    $(".close").on("click", () => {
      $("#myModal").hide();
    });
    $("#myForm").on("submit", function(event) {
      event.preventDefault();
    });
  };
  const appendExamContent = async (content, inputValue, fontValue) => {
    if (Array.isArray(content)) {
      content == null ? void 0 : content.forEach((en, index) => {
        $("body").append(en);
        if (index < content.length - 1) {
          $("body").append("<hr>");
        }
      });
    } else {
      $("body").append(content);
    }
    $("body").append(bodyStyle(inputValue, fontValue));
    $(".nav-coll-divider").hide();
    $(".fb-question>div:last-child > button").hide();
    const pdfName = await genPdfName();
    await _GM_setClipboard(pdfName, "text");
    await clearCustom();
  };
  const isReport = () => {
    var _a;
    return (_a = location.pathname) == null ? void 0 : _a.includes("/report/");
  };
  const isRightNumber = (value) => {
    const transNumber = Number(value);
    return !isNaN(transNumber) && transNumber !== Infinity && typeof transNumber === "number";
  };
  const optimizationResultPage = () => {
    if (isReport()) {
      const parentSelector = "app-report-keypoints .exam-report.bg-color-gray-bold";
      processElements(parentSelector, () => {
        addCollapseButton(parentSelector);
        expandResultTree();
        setCorrectRateColor();
      });
    }
  };
  const expandResultTree = () => {
    clickAll(".keypoint-tree-title");
    clickAll(".pd-sub-category-item");
    clickAll(".pd-item-name");
    addKeyItemClick(".pd-item-name");
  };
  const clickAll = (selector) => {
    var _a;
    const selectorVal = ((_a = $(`${selector},.expand`)) == null ? void 0 : _a.length) ? selector + ":not(.expand)" : selector + ".expand";
    $(selectorVal).each(function() {
      $(this).trigger("click");
    });
  };
  let currentIndex = 0;
  function scrollToMatchingKeyPoint(element) {
    var textToMatch = $(element).text().trim();
    var matchedKeyPoints = $(".keypoint-btn").filter(function() {
      return $(this).text().trim() === textToMatch;
    });
    const { length } = matchedKeyPoints;
    const doScroll = () => {
      var _a, _b, _c;
      const scrollContainer = $("#fenbi-web-exams");
      const index = currentIndex % length;
      const currentDom = (_a = $(matchedKeyPoints == null ? void 0 : matchedKeyPoints[index])) == null ? void 0 : _a.closest(".solution-item");
      var containerTop = ((_b = scrollContainer == null ? void 0 : scrollContainer.offset()) == null ? void 0 : _b.top) || 0;
      var top = getNumber((_c = currentDom == null ? void 0 : currentDom.offset()) == null ? void 0 : _c.top) - containerTop + getNumber(scrollContainer.scrollTop());
      scrollContainer.animate(
        {
          scrollTop: top
        },
        200,
        function() {
          currentIndex++;
        }
      );
    };
    if (length > 0) {
      if (currentIndex <= length - 1) {
        doScroll();
      } else {
        currentIndex = 0;
        doScroll();
      }
    }
  }
  function addKeyItemClick(selector) {
    $(selector).each(function() {
      $(this).on("click", function() {
        currentIndex = 0;
        const clickItem = this;
        scrollToMatchingKeyPoint(this);
        $(document).on("keydown", function(e) {
          if (e.which === 13) {
            scrollToMatchingKeyPoint(clickItem);
          }
        });
        $(this).on("blur", function() {
          $(document).off("keydown");
        });
      });
    });
  }
  const getNumber = (val) => {
    if (typeof val === "number" && !Number.isNaN(val)) {
      return val;
    }
    return 0;
  };
  const addCollapseButton = (parentSelector) => {
    const newElement = $('<button style="margin-left: 12px">展开/折叠</button>');
    newElement.on("click", expandResultTree);
    $(`${parentSelector} .font-color-gray-blod.report-keypoint-header`).append(newElement);
  };
  const setCorrectRateColor = () => {
    _GM_addStyle(`
    .red > span:nth-child(3) {
      color: red !important;
    }
  `);
    $(".pd-item-stat").each(function() {
      var _a, _b;
      const $pdItemStat = $(this);
      const correctRate = Number((_b = (_a = $pdItemStat == null ? void 0 : $pdItemStat.text()) == null ? void 0 : _a.match(/正确率(\d+)%/)) == null ? void 0 : _b[1]);
      if (isRightNumber(correctRate) && correctRate < 50) {
        $pdItemStat.addClass("red");
      }
    });
  };
  console.time("答题卡");
  kuaisu();
  caogao();
  mokao();
  fixedActions();
  optimizationResultPage();
  const initCbs = [];
  initCbs.push(dealWidth);
  initCbs.forEach((cb) => cb());
  jiankong();

})($);