yacu - Yet another CC98 userscript

CC98 增强脚本

// ==UserScript==
// @name        yacu - Yet another CC98 userscript
// @description CC98 增强脚本
// @namespace   https://github.com/CoolSpring8/
// @match       *://www.cc98.org/*
// @match       *://www-cc98-org-s.webvpn.zju.edu.cn:8001/*
// @run-at      document-idle
// @version     1.0.1
// @homepage    https://github.com/CoolSpring8/yacu
// @author      CoolSpring8
// @license     MIT
// @grant       none
// ==/UserScript==
function _defineProperty(obj, key, value) {
  return (
    key in obj
      ? Object.defineProperty(obj, key, {
          value: value,
          enumerable: !0,
          configurable: !0,
          writable: !0,
        })
      : (obj[key] = value),
    obj
  );
}
function noop() {}
function run(fn) {
  return fn();
}
function blank_object() {
  return Object.create(null);
}
function run_all(fns) {
  fns.forEach(run);
}
function is_function(thing) {
  return "function" == typeof thing;
}
function safe_not_equal(a, b) {
  return a != a
    ? b == b
    : a !== b || (a && "object" == typeof a) || "function" == typeof a;
}
function append(target, node) {
  target.appendChild(node);
}
function append_styles(target, style_sheet_id, styles) {
  const append_styles_to = (function (node) {
    if (!node) return document;
    const root = node.getRootNode ? node.getRootNode() : node.ownerDocument;
    if (root && root.host) return root;
    return node.ownerDocument;
  })(target);
  if (!append_styles_to.getElementById(style_sheet_id)) {
    const style = element("style");
    (style.id = style_sheet_id),
      (style.textContent = styles),
      (function (node, style) {
        append(node.head || node, style);
      })(append_styles_to, style);
  }
}
function insert(target, node, anchor) {
  target.insertBefore(node, anchor || null);
}
function detach(node) {
  node.parentNode.removeChild(node);
}
function element(name) {
  return document.createElement(name);
}
function text(data) {
  return document.createTextNode(data);
}
function space() {
  return text(" ");
}
function listen(node, event, handler, options) {
  return (
    node.addEventListener(event, handler, options),
    () => node.removeEventListener(event, handler, options)
  );
}
function attr(node, attribute, value) {
  null == value
    ? node.removeAttribute(attribute)
    : node.getAttribute(attribute) !== value &&
      node.setAttribute(attribute, value);
}
function set_data(text, data) {
  (data = "" + data), text.wholeText !== data && (text.data = data);
}
function set_input_value(input, value) {
  input.value = null == value ? "" : value;
}
function toggle_class(element, name, toggle) {
  element.classList[toggle ? "add" : "remove"](name);
}
let current_component;
function set_current_component(component) {
  current_component = component;
}
function onMount(fn) {
  (function () {
    if (!current_component)
      throw new Error("Function called outside component initialization");
    return current_component;
  })().$$.on_mount.push(fn);
}
!(function (css, ref) {
  void 0 === ref && (ref = {});
  var insertAt = ref.insertAt;
  if (css && "undefined" != typeof document) {
    var head = document.head || document.getElementsByTagName("head")[0],
      style = document.createElement("style");
    (style.type = "text/css"),
      "top" === insertAt && head.firstChild
        ? head.insertBefore(style, head.firstChild)
        : head.appendChild(style),
      style.styleSheet
        ? (style.styleSheet.cssText = css)
        : style.appendChild(document.createTextNode(css));
  }
})(
  "*,:after,:before{--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.flex{display:flex}.hidden{display:none}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.cursor-pointer{cursor:pointer}.items-center{align-items:center}.justify-between{justify-content:space-between}.gap-2{gap:.5rem}.rounded-lg{border-radius:.5rem}.bg-gray-100{--tw-bg-opacity:1;background-color:rgb(243 244 246/var(--tw-bg-opacity))}.text-3xl{font-size:1.875rem;line-height:2.25rem}.shadow-2xl{--tw-shadow:0 25px 50px -12px #00000040;--tw-shadow-colored:0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}"
);
const dirty_components = [],
  binding_callbacks = [],
  render_callbacks = [],
  flush_callbacks = [],
  resolved_promise = Promise.resolve();
let update_scheduled = !1;
function add_render_callback(fn) {
  render_callbacks.push(fn);
}
const seen_callbacks = new Set();
let flushidx = 0;
function flush() {
  const saved_component = current_component;
  do {
    for (; flushidx < dirty_components.length; ) {
      const component = dirty_components[flushidx];
      flushidx++, set_current_component(component), update(component.$$);
    }
    for (
      set_current_component(null), dirty_components.length = 0, flushidx = 0;
      binding_callbacks.length;

    )
      binding_callbacks.pop()();
    for (let i = 0; i < render_callbacks.length; i += 1) {
      const callback = render_callbacks[i];
      seen_callbacks.has(callback) ||
        (seen_callbacks.add(callback), callback());
    }
    render_callbacks.length = 0;
  } while (dirty_components.length);
  for (; flush_callbacks.length; ) flush_callbacks.pop()();
  (update_scheduled = !1),
    seen_callbacks.clear(),
    set_current_component(saved_component);
}
function update($$) {
  if (null !== $$.fragment) {
    $$.update(), run_all($$.before_update);
    const dirty = $$.dirty;
    ($$.dirty = [-1]),
      $$.fragment && $$.fragment.p($$.ctx, dirty),
      $$.after_update.forEach(add_render_callback);
  }
}
const outroing = new Set();
let outros, defaultGetStoreFunc;
function transition_in(block, local) {
  block && block.i && (outroing.delete(block), block.i(local));
}
function transition_out(block, local, detach, callback) {
  if (block && block.o) {
    if (outroing.has(block)) return;
    outroing.add(block),
      outros.c.push(() => {
        outroing.delete(block), callback && (detach && block.d(1), callback());
      }),
      block.o(local);
  }
}
function mount_component(component, target, anchor, customElement) {
  const {
    fragment: fragment,
    on_mount: on_mount,
    on_destroy: on_destroy,
    after_update: after_update,
  } = component.$$;
  fragment && fragment.m(target, anchor),
    customElement ||
      add_render_callback(() => {
        const new_on_destroy = on_mount.map(run).filter(is_function);
        on_destroy
          ? on_destroy.push(...new_on_destroy)
          : run_all(new_on_destroy),
          (component.$$.on_mount = []);
      }),
    after_update.forEach(add_render_callback);
}
function destroy_component(component, detaching) {
  const $$ = component.$$;
  null !== $$.fragment &&
    (run_all($$.on_destroy),
    $$.fragment && $$.fragment.d(detaching),
    ($$.on_destroy = $$.fragment = null),
    ($$.ctx = []));
}
function make_dirty(component, i) {
  -1 === component.$$.dirty[0] &&
    (dirty_components.push(component),
    update_scheduled || ((update_scheduled = !0), resolved_promise.then(flush)),
    component.$$.dirty.fill(0)),
    (component.$$.dirty[(i / 31) | 0] |= 1 << i % 31);
}
function init(
  component,
  options,
  instance,
  create_fragment,
  not_equal,
  props,
  append_styles,
  dirty = [-1]
) {
  const parent_component = current_component;
  set_current_component(component);
  const $$ = (component.$$ = {
    fragment: null,
    ctx: null,
    props: props,
    update: noop,
    not_equal: not_equal,
    bound: blank_object(),
    on_mount: [],
    on_destroy: [],
    on_disconnect: [],
    before_update: [],
    after_update: [],
    context: new Map(
      options.context || (parent_component ? parent_component.$$.context : [])
    ),
    callbacks: blank_object(),
    dirty: dirty,
    skip_bound: !1,
    root: options.target || parent_component.$$.root,
  });
  append_styles && append_styles($$.root);
  let ready = !1;
  if (
    (($$.ctx = instance
      ? instance(component, options.props || {}, (i, ret, ...rest) => {
          const value = rest.length ? rest[0] : ret;
          return (
            $$.ctx &&
              not_equal($$.ctx[i], ($$.ctx[i] = value)) &&
              (!$$.skip_bound && $$.bound[i] && $$.bound[i](value),
              ready && make_dirty(component, i)),
            ret
          );
        })
      : []),
    $$.update(),
    (ready = !0),
    run_all($$.before_update),
    ($$.fragment = !!create_fragment && create_fragment($$.ctx)),
    options.target)
  ) {
    if (options.hydrate) {
      const nodes = (function (element) {
        return Array.from(element.childNodes);
      })(options.target);
      $$.fragment && $$.fragment.l(nodes), nodes.forEach(detach);
    } else $$.fragment && $$.fragment.c();
    options.intro && transition_in(component.$$.fragment),
      mount_component(
        component,
        options.target,
        options.anchor,
        options.customElement
      ),
      flush();
  }
  set_current_component(parent_component);
}
class SvelteComponent {
  $destroy() {
    destroy_component(this, 1), (this.$destroy = noop);
  }
  $on(type, callback) {
    const callbacks = this.$$.callbacks[type] || (this.$$.callbacks[type] = []);
    return (
      callbacks.push(callback),
      () => {
        const index = callbacks.indexOf(callback);
        -1 !== index && callbacks.splice(index, 1);
      }
    );
  }
  $set($$props) {
    var obj;
    this.$$set &&
      ((obj = $$props), 0 !== Object.keys(obj).length) &&
      ((this.$$.skip_bound = !0),
      this.$$set($$props),
      (this.$$.skip_bound = !1));
  }
}
function add_css$2(target) {
  append_styles(
    target,
    "svelte-1hz6wor",
    ".award-info-stats.svelte-1hz6wor{display:flex;gap:2px;font-size:12px}.item.svelte-1hz6wor{color:grey;margin-right:4px}"
  );
}
function get_each_context(ctx, list, i) {
  const child_ctx = ctx.slice();
  return (child_ctx[1] = list[i]), child_ctx;
}
function create_each_block(ctx) {
  let p,
    t0,
    t1,
    t2,
    t3,
    t0_value = ctx[1][0] + "",
    t2_value = ctx[1][1] + "";
  return {
    c() {
      (p = element("p")),
        (t0 = text(t0_value)),
        (t1 = text("×")),
        (t2 = text(t2_value)),
        (t3 = text(";")),
        attr(p, "class", "item svelte-1hz6wor");
    },
    m(target, anchor) {
      insert(target, p, anchor),
        append(p, t0),
        append(p, t1),
        append(p, t2),
        append(p, t3);
    },
    p(ctx, dirty) {
      1 & dirty &&
        t0_value !== (t0_value = ctx[1][0] + "") &&
        set_data(t0, t0_value),
        1 & dirty &&
          t2_value !== (t2_value = ctx[1][1] + "") &&
          set_data(t2, t2_value);
    },
    d(detaching) {
      detaching && detach(p);
    },
  };
}
function create_fragment$2(ctx) {
  let div,
    p,
    t1,
    each_value = ctx[0],
    each_blocks = [];
  for (let i = 0; i < each_value.length; i += 1)
    each_blocks[i] = create_each_block(get_each_context(ctx, each_value, i));
  return {
    c() {
      (div = element("div")),
        (p = element("p")),
        (p.textContent = "统计:"),
        (t1 = space());
      for (let i = 0; i < each_blocks.length; i += 1) each_blocks[i].c();
      attr(div, "class", "award-info-stats svelte-1hz6wor");
    },
    m(target, anchor) {
      insert(target, div, anchor), append(div, p), append(div, t1);
      for (let i = 0; i < each_blocks.length; i += 1)
        each_blocks[i].m(div, null);
    },
    p(ctx, [dirty]) {
      if (1 & dirty) {
        let i;
        for (each_value = ctx[0], i = 0; i < each_value.length; i += 1) {
          const child_ctx = get_each_context(ctx, each_value, i);
          each_blocks[i]
            ? each_blocks[i].p(child_ctx, dirty)
            : ((each_blocks[i] = create_each_block(child_ctx)),
              each_blocks[i].c(),
              each_blocks[i].m(div, null));
        }
        for (; i < each_blocks.length; i += 1) each_blocks[i].d(1);
        each_blocks.length = each_value.length;
      }
    },
    i: noop,
    o: noop,
    d(detaching) {
      detaching && detach(div),
        (function (iterations, detaching) {
          for (let i = 0; i < iterations.length; i += 1)
            iterations[i] && iterations[i].d(detaching);
        })(each_blocks, detaching);
    },
  };
}
function instance$2($$self, $$props, $$invalidate) {
  let { stats: stats } = $$props;
  return (
    ($$self.$$set = ($$props) => {
      "stats" in $$props && $$invalidate(0, (stats = $$props.stats));
    }),
    [stats]
  );
}
class AwardInfoStats$1 extends SvelteComponent {
  constructor(options) {
    super(),
      init(
        this,
        options,
        instance$2,
        create_fragment$2,
        safe_not_equal,
        { stats: 0 },
        add_css$2
      );
  }
}
function promisifyRequest(request) {
  return new Promise((resolve, reject) => {
    (request.oncomplete = request.onsuccess = () => resolve(request.result)),
      (request.onabort = request.onerror = () => reject(request.error));
  });
}
function createStore(dbName, storeName) {
  const dbp = (
    !navigator.userAgentData &&
    /Safari\//.test(navigator.userAgent) &&
    !/Chrom(e|ium)\//.test(navigator.userAgent) &&
    indexedDB.databases
      ? new Promise(function (resolve) {
          var tryIdb = function () {
            return indexedDB.databases().finally(resolve);
          };
          (intervalId = setInterval(tryIdb, 100)), tryIdb();
        }).finally(function () {
          return clearInterval(intervalId);
        })
      : Promise.resolve()
  ).then(() => {
    const request = indexedDB.open(dbName);
    return (
      (request.onupgradeneeded = () =>
        request.result.createObjectStore(storeName)),
      promisifyRequest(request)
    );
  });
  var intervalId;
  return (txMode, callback) =>
    dbp.then((db) =>
      callback(db.transaction(storeName, txMode).objectStore(storeName))
    );
}
function defaultGetStore() {
  return (
    defaultGetStoreFunc ||
      (defaultGetStoreFunc = createStore("keyval-store", "keyval")),
    defaultGetStoreFunc
  );
}
function get(key, customStore = defaultGetStore()) {
  return customStore("readonly", (store) => promisifyRequest(store.get(key)));
}
function add_css$1(target) {
  append_styles(
    target,
    "svelte-4qi5da",
    ".user-preference-modal.svelte-4qi5da{position:fixed;left:50%;top:50%;transform:translate(-50%, -50%);z-index:100;width:400px;height:300px;background-color:whitesmoke;padding:40px}"
  );
}
function create_fragment$1(ctx) {
  let div5,
    div1,
    h2,
    t1,
    div0,
    t3,
    div4,
    div3,
    h3,
    t5,
    div2,
    input,
    t6,
    button,
    mounted,
    dispose;
  return {
    c() {
      (div5 = element("div")),
        (div1 = element("div")),
        (h2 = element("h2")),
        (h2.textContent = "偏好设置"),
        (t1 = space()),
        (div0 = element("div")),
        (div0.textContent = "×"),
        (t3 = space()),
        (div4 = element("div")),
        (div3 = element("div")),
        (h3 = element("h3")),
        (h3.textContent = "屏蔽用户发言"),
        (t5 = space()),
        (div2 = element("div")),
        (input = element("input")),
        (t6 = space()),
        (button = element("button")),
        (button.textContent = "保存"),
        attr(div0, "class", "text-3xl cursor-pointer"),
        attr(div1, "class", "flex justify-between items-center"),
        attr(input, "type", "text"),
        attr(div2, "class", "flex gap-2"),
        attr(div3, "class", "block-users"),
        attr(div4, "class", "user-preference-items"),
        attr(
          div5,
          "class",
          "user-preference-modal bg-gray-100 shadow-2xl rounded-lg svelte-4qi5da"
        ),
        toggle_class(div5, "hidden", !ctx[0]);
    },
    m(target, anchor) {
      insert(target, div5, anchor),
        append(div5, div1),
        append(div1, h2),
        append(div1, t1),
        append(div1, div0),
        append(div5, t3),
        append(div5, div4),
        append(div4, div3),
        append(div3, h3),
        append(div3, t5),
        append(div3, div2),
        append(div2, input),
        set_input_value(input, ctx[1]),
        append(div2, t6),
        append(div2, button),
        mounted ||
          ((dispose = [
            listen(div0, "click", ctx[2]),
            listen(input, "input", ctx[3]),
            listen(button, "click", ctx[4]),
          ]),
          (mounted = !0));
    },
    p(ctx, [dirty]) {
      2 & dirty && input.value !== ctx[1] && set_input_value(input, ctx[1]),
        1 & dirty && toggle_class(div5, "hidden", !ctx[0]);
    },
    i: noop,
    o: noop,
    d(detaching) {
      detaching && detach(div5), (mounted = !1), run_all(dispose);
    },
  };
}
function instance$1($$self, $$props, $$invalidate) {
  let blockedUsers,
    { open: open } = $$props;
  onMount(async () => {
    $$invalidate(
      1,
      (blockedUsers = [...(await get("blocked-users"))]?.join(" ") || "")
    );
  });
  return (
    ($$self.$$set = ($$props) => {
      "open" in $$props && $$invalidate(0, (open = $$props.open));
    }),
    [
      open,
      blockedUsers,
      () => $$invalidate(0, (open = !1)),
      function () {
        (blockedUsers = this.value), $$invalidate(1, blockedUsers);
      },
      () => {
        !(function (key, value, customStore = defaultGetStore()) {
          customStore(
            "readwrite",
            (store) => (
              store.put(value, key), promisifyRequest(store.transaction)
            )
          );
        })("blocked-users", new Set(blockedUsers.split(" ")));
      },
    ]
  );
}
class Modal extends SvelteComponent {
  constructor(options) {
    super(),
      init(
        this,
        options,
        instance$1,
        create_fragment$1,
        safe_not_equal,
        { open: 0 },
        add_css$1
      );
  }
}
function add_css(target) {
  append_styles(
    target,
    "svelte-w6hddt",
    ".user-preference-button.svelte-w6hddt{position:fixed;right:30px;top:80px;z-index:2;background-color:white}"
  );
}
function create_if_block(ctx) {
  let userpreferencemodal, updating_open, current;
  function userpreferencemodal_open_binding(value) {
    ctx[2](value);
  }
  let userpreferencemodal_props = {};
  return (
    void 0 !== ctx[0] && (userpreferencemodal_props.open = ctx[0]),
    (userpreferencemodal = new Modal({ props: userpreferencemodal_props })),
    binding_callbacks.push(() =>
      (function (component, name, callback) {
        const index = component.$$.props[name];
        void 0 !== index &&
          ((component.$$.bound[index] = callback),
          callback(component.$$.ctx[index]));
      })(userpreferencemodal, "open", userpreferencemodal_open_binding)
    ),
    {
      c() {
        var block;
        (block = userpreferencemodal.$$.fragment) && block.c();
      },
      m(target, anchor) {
        mount_component(userpreferencemodal, target, anchor), (current = !0);
      },
      p(ctx, dirty) {
        const userpreferencemodal_changes = {};
        var fn;
        !updating_open &&
          1 & dirty &&
          ((updating_open = !0),
          (userpreferencemodal_changes.open = ctx[0]),
          (fn = () => (updating_open = !1)),
          flush_callbacks.push(fn)),
          userpreferencemodal.$set(userpreferencemodal_changes);
      },
      i(local) {
        current ||
          (transition_in(userpreferencemodal.$$.fragment, local),
          (current = !0));
      },
      o(local) {
        transition_out(userpreferencemodal.$$.fragment, local), (current = !1);
      },
      d(detaching) {
        destroy_component(userpreferencemodal, detaching);
      },
    }
  );
}
function create_fragment(ctx) {
  let button,
    t1,
    if_block_anchor,
    current,
    mounted,
    dispose,
    if_block = ctx[0] && create_if_block(ctx);
  return {
    c() {
      (button = element("button")),
        (button.textContent = "偏好设置"),
        (t1 = space()),
        if_block && if_block.c(),
        (if_block_anchor = text("")),
        attr(button, "class", "user-preference-button svelte-w6hddt");
    },
    m(target, anchor) {
      insert(target, button, anchor),
        insert(target, t1, anchor),
        if_block && if_block.m(target, anchor),
        insert(target, if_block_anchor, anchor),
        (current = !0),
        mounted ||
          ((dispose = listen(button, "click", ctx[1])), (mounted = !0));
    },
    p(ctx, [dirty]) {
      ctx[0]
        ? if_block
          ? (if_block.p(ctx, dirty), 1 & dirty && transition_in(if_block, 1))
          : ((if_block = create_if_block(ctx)),
            if_block.c(),
            transition_in(if_block, 1),
            if_block.m(if_block_anchor.parentNode, if_block_anchor))
        : if_block &&
          ((outros = { r: 0, c: [], p: outros }),
          transition_out(if_block, 1, 1, () => {
            if_block = null;
          }),
          outros.r || run_all(outros.c),
          (outros = outros.p));
    },
    i(local) {
      current || (transition_in(if_block), (current = !0));
    },
    o(local) {
      transition_out(if_block), (current = !1);
    },
    d(detaching) {
      detaching && detach(button),
        detaching && detach(t1),
        if_block && if_block.d(detaching),
        detaching && detach(if_block_anchor),
        (mounted = !1),
        dispose();
    },
  };
}
function instance($$self, $$props, $$invalidate) {
  let open = !1;
  return [
    open,
    () => $$invalidate(0, (open = !0)),
    function (value) {
      (open = value), $$invalidate(0, open);
    },
  ];
}
class UserPreference$1 extends SvelteComponent {
  constructor(options) {
    super(),
      init(
        this,
        options,
        instance,
        create_fragment,
        safe_not_equal,
        {},
        add_css
      );
  }
}
class BasicError extends Error {
  constructor(message) {
    super(`[yacu] ${message}`);
  }
}
const emitter = (() => {
  const emitter = {
    all: (n = n || new Map()),
    on: function (t, e) {
      var i = n.get(t);
      i ? i.push(e) : n.set(t, [e]);
    },
    off: function (t, e) {
      var i = n.get(t);
      i && (e ? i.splice(i.indexOf(e) >>> 0, 1) : n.set(t, []));
    },
    emit: function (t, e) {
      var i = n.get(t);
      i &&
        i.slice().map(function (n) {
          n(e);
        }),
        (i = n.get("*")) &&
          i.slice().map(function (n) {
            n(t, e);
          });
    },
  };
  var n;
  return emitter.on("*", (...arguments_) => console.log(arguments_)), emitter;
})();
class ReactInteropError extends BasicError {
  constructor(message) {
    super(message), (this.name = "ReactInteropError");
  }
}
function renderToNewElement(component, properties) {
  const element = (function ({ className: className, id: id } = {}) {
    const element = document.createElement("div");
    return (
      className && (element.className = className),
      id && (element.id = id),
      element
    );
  })();
  return new component({ target: element, props: properties }), element;
}
class AwardInfoStats {
  constructor() {
    _defineProperty(this, "pending", !1),
      emitter.on("after-url-change", ({ to: to }) => {
        to?.startsWith("/topic/") && this.activate();
      });
  }
  async activate() {
    this.pending = !0;
    const cancel = (function (selector, callback) {
      let start,
        canceled = !1,
        elapsed = 0;
      const processedElements = new WeakSet();
      return (
        requestAnimationFrame(function step(timestamp) {
          const elements = document.querySelectorAll(selector);
          for (const element of elements.values())
            processedElements.has(element) ||
              (console.log(element),
              callback(element),
              processedElements.add(element));
          canceled ||
            (timestamp &&
              (void 0 === start && (start = timestamp),
              (elapsed = timestamp - start)),
            elapsed < 1e4
              ? requestAnimationFrame(step)
              : setTimeout(step, 5e3));
        }),
        () => {
          canceled = !0;
        }
      );
    })(".awardInfo", (element) => this._activate(element));
    emitter.on("before-url-change", () => cancel());
  }
  _activate(element) {
    const r = (function (element) {
        const [, instance] =
          Object.entries(element).find(([name]) =>
            name.startsWith("__reactInternalInstance")
          ) ?? [];
        if (!instance) throw new ReactInteropError("未发现 React 实例");
        return (function (instance) {
          let parent = instance.return;
          for (; "string" == typeof parent.type; ) parent = parent.return;
          return parent;
        })(instance).stateNode;
      })(element),
      accumulator = {};
    for (const award of r.props.awardInfo)
      accumulator[award.content]
        ? accumulator[award.content]++
        : (accumulator[award.content] = 1);
    const stats = Object.entries(accumulator),
      statsElement = renderToNewElement(AwardInfoStats$1, { stats: stats });
    element.prepend(statsElement), (this.pending = !1);
  }
}
const beforeRequestHooks = [],
  afterResponseHooks = [];
function addAfterResponseHooks(hook) {
  afterResponseHooks.push(async (request, response) => {
    if (!hook.url.some((regex) => regex.test(request.url))) return;
    const oldData = await response.json(),
      newData = hook.process(oldData);
    if (Array.isArray(oldData) && Array.isArray(newData)) {
      const count = oldData.length - newData.length;
      0 === count
        ? console.log("没有内容需要过滤")
        : console.log(`过滤了${count}条内容`);
    }
    return new Response(JSON.stringify(newData), response);
  });
}
class BlockUserTopic {
  constructor() {
    _defineProperty(this, "blockedUsers", void 0);
    const newTopics = new RegExp("^https://api.cc98.org/topic/new?"),
      topicPosts = new RegExp("^https://api.cc98.org/Topic/\\d+/post?");
    this.getBlockedUsers().then(() => {
      addAfterResponseHooks({
        url: [newTopics],
        process: (topics) =>
          topics.filter(
            (topic) =>
              null === topic.userName || !this.blockedUsers?.has(topic.userName)
          ),
      }),
        addAfterResponseHooks({
          url: [topicPosts],
          process: (posts) =>
            posts.filter(
              (post) =>
                null === post.userName || !this.blockedUsers?.has(post.userName)
            ),
        });
    });
  }
  async getBlockedUsers() {
    this.blockedUsers = await get("blocked-users");
  }
}
class UserPreference {
  constructor() {
    const element = renderToNewElement(UserPreference$1);
    document.body.append(element);
  }
}
const defaultOptions = {
    apiBase: ["https://math.vercel.app", "https://math.now.sh"],
    color: "black",
  },
  getPostsRequestRegExp = /post\/\d+\/original$/,
  putPostRequestRegExp = /post\/\d+$/,
  newPostRequestRegExp = /topic\/\d+\/post$/,
  newTopicRequestRegExp = /board\/\d+\/topic$/,
  texImageURLRegExp =
    /(?<=\n|^)( *(?:> *)*)<center>\s*!\[.*?]\((.+?)\)\s*<\/center>|!\[.*?]\((.+?)\)/g,
  texInlineRegExp = /\$(\S|(?:\S.*?\S))\$/g,
  blockquoteAwareTexBlockRegExp =
    /(?<=^|\n)( *(?:> *)*)\${2}((?:\n\1[^\n$]+)+)\n\1\${2}(?=\n|$)/g;
function standardizeColor(string_) {
  const context = document.createElement("canvas").getContext("2d");
  return (context.fillStyle = string_), context.fillStyle;
}
class MarkdownMath {
  constructor() {
    var hook;
    addAfterResponseHooks({
      url: [getPostsRequestRegExp],
      process: (post) => (
        1 === post.contentType &&
          (post.content = (function (
            content,
            { apiBase: apiBase = defaultOptions.apiBase } = defaultOptions
          ) {
            return content.replace(
              texImageURLRegExp,
              function (match, indent, blockURLString, inlineURLString) {
                const url = new URL(blockURLString || inlineURLString);
                if (apiBase.includes(url.origin)) {
                  const searchParameters = url.searchParams;
                  return searchParameters.has("from")
                    ? ["$$", searchParameters.get("from").trim(), "$$"]
                        .join("\n")
                        .replace(/(?<=^|\n)/g, indent)
                    : searchParameters.has("inline")
                    ? `$${searchParameters.get("inline")}$`
                    : match;
                }
                return match;
              }
            );
          })(post.content)),
        post
      ),
    }),
      (hook = {
        url: [
          putPostRequestRegExp,
          newPostRequestRegExp,
          newTopicRequestRegExp,
        ],
        process: (post) => (
          1 === post.contentType &&
            (post.content = (function (
              content,
              {
                apiBase: apiBase = defaultOptions.apiBase,
                color: color = defaultOptions.color,
                alternateColor: alternateColor = defaultOptions.alternateColor,
              } = defaultOptions
            ) {
              function isInsideCodeFence(quoteLayers, precedingLines) {
                for (let index = quoteLayers; index >= 0; --index) {
                  let backtickDelimiterCount = 0,
                    tildeDelimiterCount = 0;
                  for (const line of precedingLines.reverse()) {
                    const matchResult = line.match(
                      new RegExp(String.raw`^ *(?:> *){${index}}(\`\`\`|~~~)?`)
                    );
                    if (null === matchResult) break;
                    if (void 0 !== matchResult[1])
                      switch (matchResult[1]) {
                        case "```":
                          ++backtickDelimiterCount;
                          break;
                        case "~~~":
                          ++tildeDelimiterCount;
                      }
                  }
                  if (
                    backtickDelimiterCount % 2 == 1 ||
                    tildeDelimiterCount % 2 == 1
                  )
                    return !0;
                }
                return !1;
              }
              return content
                .replace(
                  blockquoteAwareTexBlockRegExp,
                  function (match, quote, quotedTex, offset, string) {
                    const precedingString = string.slice(0, offset);
                    if (
                      isInsideCodeFence(
                        (quote.match(/>/g) || []).length,
                        precedingString.replace(/\n$/, "").split("\n")
                      )
                    )
                      return match;
                    const url = new URL(apiBase[0]),
                      searchParameters = url.searchParams;
                    return (
                      searchParameters.set(
                        "from",
                        quotedTex.replaceAll(quote, "").trim()
                      ),
                      void 0 !== color &&
                        searchParameters.set("color", standardizeColor(color)),
                      void 0 !== alternateColor &&
                        searchParameters.set("alternateColor", alternateColor),
                      `${quote}<center>![](${url.href})</center>`
                    );
                  }
                )
                .replace(
                  texInlineRegExp,
                  function (match, tex, offset, string) {
                    const precedingString = string.slice(0, offset),
                      precedingLines = precedingString.split("\n"),
                      currentLine = precedingLines.pop();
                    if (
                      (precedingString.split("\n").pop().match(/`/g) || [])
                        .length %
                        2 ==
                      1
                    )
                      return match;
                    if (
                      isInsideCodeFence(
                        (
                          currentLine.match(/^( *(?:> *)*)/)[0].match(/>/g) ||
                          []
                        ).length,
                        precedingLines
                      )
                    )
                      return match;
                    const url = new URL(apiBase[0]),
                      searchParameters = url.searchParams;
                    return (
                      searchParameters.set("inline", tex),
                      void 0 !== color &&
                        searchParameters.set("color", standardizeColor(color)),
                      void 0 !== alternateColor &&
                        searchParameters.set("alternateColor", alternateColor),
                      `![](${url.href})`
                    );
                  }
                );
            })(post.content)),
          post
        ),
      }),
      beforeRequestHooks.push(async (request, options) => {
        if (!hook.url.some((regex) => regex.test(request.url))) return;
        let oldData;
        options.body && (oldData = JSON.parse(options.body));
        const newData = hook.process(oldData);
        return new Request(request, { body: JSON.stringify(newData) });
      });
  }
}
const changeStates = ["pushState", "replaceState"];
for (const c of [AwardInfoStats, BlockUserTopic, UserPreference, MarkdownMath])
  new c();
for (const f of [
  function () {
    emitter.emit("after-url-change", { to: window.location.pathname });
    for (const changeState of changeStates)
      window.History.prototype[changeState] = new Proxy(
        window.History.prototype[changeState],
        {
          apply: (target, thisArgument, arguments_) => {
            const url = arguments_[2],
              from = window.location.pathname,
              to = url ? String(url) : void 0;
            emitter.emit("before-url-change", { from: from, to: to }),
              Reflect.apply(target, thisArgument, arguments_),
              setTimeout(() =>
                emitter.emit("after-url-change", { from: from, to: to })
              );
          },
        }
      );
  },
  function () {
    var hooks;
    (hooks = {
      beforeRequest: beforeRequestHooks,
      afterResponse: afterResponseHooks,
    }),
      (window.fetch = new Proxy(window.fetch, {
        async apply(target, thisArgument, arguments_) {
          const [input, init] = arguments_;
          let request = new Request(input, init);
          for (const preProcess of hooks.beforeRequest) {
            const temporary = await preProcess(request, init);
            if (temporary instanceof Response) return temporary;
            if (temporary instanceof Request) {
              request = temporary;
              break;
            }
          }
          let response = await Reflect.apply(target, thisArgument, [request]);
          for (const postProcess of hooks.afterResponse) {
            const temporary = await postProcess(request, response.clone());
            temporary instanceof Response && (response = temporary);
          }
          return response;
        },
      }));
  },
])
  f();