{"version":3,"file":"Artalk.cjs","sources":["../src/lib/utils.ts","../src/i18n/en.ts","../src/i18n/external.ts","../src/i18n/index.ts","../src/i18n/zh-CN.ts","../../../node_modules/.pnpm/marked@14.1.3/node_modules/marked/lib/marked.esm.js","../../../node_modules/.pnpm/insane@2.6.2/node_modules/insane/she.js","../../../node_modules/.pnpm/assignment@2.0.0/node_modules/assignment/assignment.js","../../../node_modules/.pnpm/insane@2.6.2/node_modules/insane/lowercase.js","../../../node_modules/.pnpm/insane@2.6.2/node_modules/insane/toMap.js","../../../node_modules/.pnpm/insane@2.6.2/node_modules/insane/attributes.js","../../../node_modules/.pnpm/insane@2.6.2/node_modules/insane/elements.js","../../../node_modules/.pnpm/insane@2.6.2/node_modules/insane/parser.js","../../../node_modules/.pnpm/insane@2.6.2/node_modules/insane/sanitizer.js","../../../node_modules/.pnpm/insane@2.6.2/node_modules/insane/insane.js","../../../node_modules/.pnpm/insane@2.6.2/node_modules/insane/defaults.js","../src/lib/sanitizer.ts","../../../node_modules/.pnpm/hanabi@0.4.0/node_modules/hanabi/dist/hanabi.js","../src/lib/highlight.ts","../src/lib/marked-renderer.ts","../src/lib/marked.ts","../src/context.ts","../src/lib/injection/container.ts","../src/lib/merge-deep.ts","../src/defaults.ts","../src/config.ts","../src/plugins/stat.ts","../src/api/v2.ts","../src/api/fetch.ts","../src/api/index.ts","../src/plugins/editor/_plug.ts","../src/plugins/editor/local-storage.ts","../src/plugins/editor/submit-add.ts","../src/plugins/editor/submit.ts","../src/plugins/editor/mover.ts","../src/lib/ui.ts","../src/plugins/editor/emoticons.ts","../src/plugins/editor/upload.ts","../src/plugins/editor/preview.ts","../src/plugins/editor/index.ts","../src/plugins/editor/header-event.ts","../src/plugins/editor/header-user.ts","../src/plugins/editor/header-link.ts","../src/plugins/editor/textarea.ts","../src/plugins/editor/submit-btn.ts","../src/plugins/editor/state-reply.ts","../src/plugins/editor/state-edit.ts","../src/plugins/editor/closable.ts","../src/plugins/editor/_kit.ts","../src/lib/event-manager.ts","../src/plugins/editor-kit.ts","../src/plugins/list/goto-focus.ts","../src/components/error-dialog.ts","../src/plugins/list/error-dialog.ts","../src/plugins/list/index.ts","../src/plugins/list/fetch.ts","../src/plugins/list/loading.ts","../src/plugins/list/unread.ts","../src/plugins/list/with-editor.ts","../src/plugins/list/count.ts","../src/plugins/list/sidebar-btn.ts","../src/plugins/list/unread-badge.ts","../src/plugins/list/dropdown.ts","../src/plugins/list/goto-dispatcher.ts","../src/plugins/list/no-comment.ts","../src/plugins/list/copyright.ts","../src/plugins/list/time-ticking.ts","../src/plugins/list/reach-bottom.ts","../src/plugins/list/goto-first.ts","../src/plugins/version-check.ts","../src/plugins/dark-mode.ts","../src/plugins/page-vote.ts","../src/services/api.ts","../src/lib/user.ts","../src/components/checker/captcha-renders.ts","../src/components/checker/captcha.ts","../src/components/checker/admin.ts","../src/components/dialog.ts","../src/components/checker/index.ts","../src/services/checkers.ts","../src/editor/ui.ts","../src/editor/state.ts","../src/editor/editor.ts","../src/editor/editor.html?raw","../src/data.ts","../src/layer/layer.ts","../src/layer/scrollbar-helper.ts","../src/layer/wrap.ts","../src/layer/layer-manager.ts","../src/list/layout/nest.ts","../src/list/nest.ts","../src/list/layout/flat.ts","../src/list/layout/index.ts","../src/comment/height-limit.ts","../src/comment/renders/header.ts","../src/components/action-btn.ts","../src/comment/renders/actions.ts","../src/comment/renders/index.ts","../src/comment/renders/avatar.ts","../src/comment/renders/content.ts","../src/comment/renders/reply-at.ts","../src/comment/renders/reply-to.ts","../src/comment/renders/pending.ts","../src/comment/render.ts","../src/comment/comment.html?raw","../src/comment/actions.ts","../src/comment/comment-node.ts","../src/lib/detect.ts","../src/components/read-more-btn.ts","../src/list/paginator/read-more.ts","../src/components/pagination.ts","../src/list/paginator/up-down.ts","../src/list/page.ts","../src/list/list.ts","../src/list/list.html?raw","../src/list/comment.ts","../src/layer/sidebar-layer.ts","../src/layer/sidebar-layer.html?raw","../src/services/sidebar.ts","../src/plugins/index.ts","../src/services/index.ts","../src/services/data.ts","../src/api/handler.ts","../src/services/i18n.ts","../src/services/user.ts","../src/services/editor.ts","../src/services/list.ts","../src/services/layer.ts","../src/plugins/markdown.ts","../src/plugins/admin-only-elem.ts","../src/plugins/notifies.ts","../src/mount.ts","../src/plugins/mount-error.ts","../src/lib/watch-conf.ts","../src/artalk.ts","../src/services/events.ts","../src/services/config.ts","../src/main.ts"],"sourcesContent":["export function createElement<E extends HTMLElement = HTMLElement>(htmlStr: string = ''): E {\n  const div = document.createElement('div')\n  div.innerHTML = htmlStr.trim()\n  return (div.firstElementChild || div) as E\n}\n\nexport function getHeight(el: HTMLElement): number {\n  const num = parseFloat(getComputedStyle(el, null).height.replace('px', ''))\n  return num || 0 // NaN -> 0\n}\n\nexport function htmlEncode(str: string) {\n  const temp = document.createElement('div')\n  temp.innerText = str\n  const output = temp.innerHTML\n  return output\n}\n\nexport function htmlDecode(str: string) {\n  const temp = document.createElement('div')\n  temp.innerHTML = str\n  const output = temp.innerText\n  return output\n}\n\nexport function getQueryParam(name: string) {\n  const match = RegExp(`[?&]${name}=([^&]*)`).exec(window.location.search)\n  return match && decodeURIComponent(match[1].replace(/\\+/g, ' '))\n}\n\nexport function getOffset(el: HTMLElement, relativeTo?: HTMLElement) {\n  const getOffsetRecursive = (element: HTMLElement): { top: number; left: number } => {\n    const rect = element.getBoundingClientRect()\n    const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft\n    const scrollTop = window.pageYOffset || document.documentElement.scrollTop\n    return {\n      top: rect.top + scrollTop,\n      left: rect.left + scrollLeft,\n    }\n  }\n\n  const elOffset = getOffsetRecursive(el)\n  if (!relativeTo) return elOffset\n\n  const relativeToOffset = getOffsetRecursive(relativeTo)\n\n  return {\n    top: elOffset.top - relativeToOffset.top,\n    left: elOffset.left - relativeToOffset.left,\n  }\n}\n\nexport function padWithZeros(vNumber: number, width: number) {\n  let numAsString = vNumber.toString()\n  while (numAsString.length < width) {\n    numAsString = `0${numAsString}`\n  }\n  return numAsString\n}\n\nexport function dateFormat(date: Date) {\n  const vDay = padWithZeros(date.getDate(), 2)\n  const vMonth = padWithZeros(date.getMonth() + 1, 2)\n  const vYear = padWithZeros(date.getFullYear(), 2)\n  // var vHour = padWithZeros(date.getHours(), 2);\n  // var vMinute = padWithZeros(date.getMinutes(), 2);\n  // var vSecond = padWithZeros(date.getSeconds(), 2);\n  return `${vYear}-${vMonth}-${vDay}`\n}\n\nexport function timeAgo(date: Date, $t = (n: any) => n) {\n  try {\n    const oldTime = date.getTime()\n    const currTime = new Date().getTime()\n    const diffValue = currTime - oldTime\n\n    const days = Math.floor(diffValue / (24 * 3600 * 1000))\n    if (days === 0) {\n      // 计算相差小时数\n      const leave1 = diffValue % (24 * 3600 * 1000) // 计算天数后剩余的毫秒数\n      const hours = Math.floor(leave1 / (3600 * 1000))\n      if (hours === 0) {\n        // 计算相差分钟数\n        const leave2 = leave1 % (3600 * 1000) // 计算小时数后剩余的毫秒数\n        const minutes = Math.floor(leave2 / (60 * 1000))\n        if (minutes === 0) {\n          // 计算相差秒数\n          const leave3 = leave2 % (60 * 1000) // 计算分钟数后剩余的毫秒数\n          const seconds = Math.round(leave3 / 1000)\n          if (seconds < 10) return $t('now')\n          return `${seconds} ${$t('seconds')}`\n        }\n        return `${minutes} ${$t('minutes')}`\n      }\n      return `${hours} ${$t('hours')}`\n    }\n    if (days < 0) return $t('now')\n\n    if (days < 8) {\n      return `${days} ${$t('days')}`\n    }\n\n    return dateFormat(date)\n  } catch (error) {\n    console.error(error)\n    return ' - '\n  }\n}\n\nexport function getGravatarURL(opts: { params: string; mirror: string; emailHash: string }) {\n  return `${opts.mirror.replace(/\\/$/, '')}/${opts.emailHash}?${opts.params.replace(/^\\?/, '')}`\n}\n\nexport function sleep(ms: number) {\n  return new Promise((resolve) => {\n    setTimeout(resolve, ms)\n  })\n}\n\n/** 版本号比较（a < b :-1 | 0 | b < a :1） */\nexport function versionCompare(a: string, b: string) {\n  const pa = a.split('.')\n  const pb = b.split('.')\n  for (let i = 0; i < 3; i++) {\n    const na = Number(pa[i])\n    const nb = Number(pb[i])\n    if (na > nb) return 1\n    if (nb > na) return -1\n    if (!Number.isNaN(na) && Number.isNaN(nb)) return 1\n    if (Number.isNaN(na) && !Number.isNaN(nb)) return -1\n  }\n  return 0\n}\n\n/** 获取修正后的 UserAgent */\nexport async function getCorrectUserAgent() {\n  const uaRaw = navigator.userAgent\n  if (!(navigator as any).userAgentData || !(navigator as any).userAgentData.getHighEntropyValues) {\n    return uaRaw\n  }\n\n  // @link https://web.dev/migrate-to-ua-ch/\n  // @link https://web.dev/user-agent-client-hints/\n  const uaData = (navigator as any).userAgentData\n  let uaGot: any = null\n  try {\n    uaGot = await uaData.getHighEntropyValues(['platformVersion'])\n  } catch (err) {\n    console.error(err)\n    return uaRaw\n  }\n  const majorPlatformVersion = Number(uaGot.platformVersion.split('.')[0])\n\n  if (uaData.platform === 'Windows') {\n    if (majorPlatformVersion >= 13) {\n      // @link https://docs.microsoft.com/en-us/microsoft-edge/web-platform/how-to-detect-win11\n      // @date 2022-4-29\n      // Win 11 样本：\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36\"\n      return uaRaw.replace(/Windows NT 10.0/, 'Windows NT 11.0')\n    }\n  }\n  if (uaData.platform === 'macOS') {\n    if (majorPlatformVersion >= 11) {\n      // 11 => BigSur\n      // @date 2022-4-29\n      // (Intel Chip) macOS 12.3 样本：\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36\"\n      // (Arm Chip) macOS 样本：\"Mozilla/5.0 (Macintosh; ARM Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.2 Safari/605.1.15\"\n      return uaRaw.replace(\n        /(Mac OS X \\d+_\\d+_\\d+|Mac OS X)/,\n        `Mac OS X ${uaGot.platformVersion.replace(/\\./g, '_')}`,\n      )\n    }\n  }\n\n  return uaRaw\n}\n\n/** 是否为完整的 URL */\nexport function isValidURL(urlRaw: string) {\n  // @link https://www.rfc-editor.org/rfc/rfc3986\n  let url: URL\n  try {\n    url = new URL(urlRaw)\n  } catch (_) {\n    return false\n  }\n  return url.protocol === 'http:' || url.protocol === 'https:'\n}\n\n/** 获取基于 conf.server 的 URL */\nexport function getURLBasedOnApi(opts: { base: string; path: string }) {\n  return getURLBasedOn(opts.base, opts.path)\n}\n\n/** 获取基于某个 baseURL 的 URL */\nexport function getURLBasedOn(baseURL: string, path: string) {\n  return `${baseURL.replace(/\\/$/, '')}/${path.replace(/^\\//, '')}`\n}\n","const en = {\n  /* Editor */\n  placeholder: 'Leave a comment',\n  noComment: 'No Comment',\n  send: 'Send',\n  signIn: 'Sign in',\n  signUp: 'Sign up',\n  save: 'Save',\n  nick: 'Nickname',\n  email: 'Email',\n  link: 'Website',\n  emoticon: 'Emoji',\n  preview: 'Preview',\n  uploadImage: 'Upload Image',\n  uploadFail: 'Upload Failed',\n  commentFail: 'Failed to comment',\n  restoredMsg: 'Content has been restored',\n  onlyAdminCanReply: 'Only admin can reply',\n  uploadLoginMsg: 'Please fill in your name and email to upload',\n\n  /* List */\n  counter: '{count} Comments',\n  sortLatest: 'Latest',\n  sortOldest: 'Oldest',\n  sortBest: 'Best',\n  sortAuthor: 'Author',\n  openComment: 'Open Comment',\n  closeComment: 'Close Comment',\n  listLoadFailMsg: 'Failed to load comments',\n  listRetry: 'Retry',\n  loadMore: 'Load More',\n\n  /* Comment */\n  admin: 'Admin',\n  reply: 'Reply',\n  voteUp: 'Up',\n  voteDown: 'Down',\n  voteFail: 'Vote Failed',\n  readMore: 'Read More',\n  actionConfirm: 'Confirm',\n  collapse: 'Collapse',\n  collapsed: 'Collapsed',\n  collapsedMsg: 'This comment has been collapsed',\n  expand: 'Expand',\n  approved: 'Approved',\n  pending: 'Pending',\n  pendingMsg: 'Pending, visible only to commenter.',\n  edit: 'Edit',\n  editCancel: 'Cancel Edit',\n  delete: 'Delete',\n  deleteConfirm: 'Confirm',\n  pin: 'Pin',\n  unpin: 'Unpin',\n\n  /* Time */\n  seconds: 'seconds ago',\n  minutes: 'minutes ago',\n  hours: 'hours ago',\n  days: 'days ago',\n  now: 'just now',\n\n  /* Checker */\n  adminCheck: 'Enter admin password:',\n  captchaCheck: 'Enter the CAPTCHA to continue:',\n  confirm: 'Confirm',\n  cancel: 'Cancel',\n\n  /* Sidebar */\n  msgCenter: 'Messages',\n  ctrlCenter: 'Dashboard',\n\n  /* Auth */\n  userProfile: 'Profile',\n  noAccountPrompt: \"Don't have an account?\",\n  haveAccountPrompt: 'Already have an account?',\n  forgetPassword: 'Forget Password',\n  resetPassword: 'Reset Password',\n  changePassword: 'Change Password',\n  confirmPassword: 'Confirm Password',\n  passwordMismatch: 'Passwords do not match',\n  verificationCode: 'Verification Code',\n  verifySend: 'Send Code',\n  verifyResend: 'Resend',\n  waitSeconds: 'Wait {seconds}s',\n  emailVerified: 'Email has been verified',\n  password: 'Password',\n  username: 'Username',\n  nextStep: 'Next Step',\n  skipVerify: 'Skip verification',\n  logoutConfirm: 'Are you sure to logout?',\n  accountMergeNotice: 'Your email has multiple accounts with different id.',\n  accountMergeSelectOne: 'Please select one you want to merge all the data into it.',\n  accountMergeConfirm: 'All data will be merged into one account, the id is {id}.',\n  dismiss: 'Dismiss',\n  merge: 'Merge',\n\n  /* General */\n  client: 'Client',\n  server: 'Server',\n  loading: 'Loading',\n  loadFail: 'Load Failed',\n  editing: 'Editing',\n  editFail: 'Edit Failed',\n  deleting: 'Deleting',\n  deleteFail: 'Delete Failed',\n  reqGot: 'Request got',\n  reqAborted: 'Request timed out or terminated unexpectedly',\n  updateMsg: 'Please update Artalk {name} to get the best experience!',\n  currentVersion: 'Current Version',\n  ignore: 'Ignore',\n  open: 'Open',\n  openName: 'Open {name}',\n}\n\nexport type I18n = typeof en\nexport type I18nKeys = keyof I18n\n\nexport default en\n","import type { I18n } from '.'\n\nexport const GLOBAL_LOCALES_KEY = 'ArtalkI18n'\n\nexport function defineLocaleExternal(lang: string, locale: I18n, aliases?: string[]) {\n  if (!window[GLOBAL_LOCALES_KEY]) window[GLOBAL_LOCALES_KEY] = {}\n  window[GLOBAL_LOCALES_KEY][lang] = locale\n  if (aliases)\n    aliases.forEach((l) => {\n      window[GLOBAL_LOCALES_KEY][l] = locale\n    })\n  return locale\n}\n","import * as Utils from '../lib/utils'\nimport en, { I18n, I18nKeys } from './en'\nimport zhCN from './zh-CN'\nimport { GLOBAL_LOCALES_KEY } from './external'\n\nexport type * from './en'\n\n// @note the key of language is followed by `ISO 639`\n// https://en.wikipedia.org/wiki/ISO_639\n// https://datatracker.ietf.org/doc/html/rfc5646#section-2.1\nexport const internal = {\n  en,\n  'en-US': en,\n  'zh-CN': zhCN,\n}\n\n/**\n * find a locale object by language name\n */\nexport function findLocaleSet(lang: string): I18n {\n  // normalize a key of language to `ISO 639`\n  lang = lang.replace(\n    /^([a-zA-Z]+)(-[a-zA-Z]+)?$/,\n    (_, p1: string, p2: string) => p1.toLowerCase() + (p2 || '').toUpperCase(),\n  )\n\n  // internal finding\n  if (internal[lang]) {\n    return internal[lang]\n  }\n\n  // external finding\n  if (window[GLOBAL_LOCALES_KEY] && window[GLOBAL_LOCALES_KEY][lang]) {\n    return window[GLOBAL_LOCALES_KEY][lang]\n  }\n\n  // case when not found:\n  // use `en` by default\n  return internal.en\n}\n\n/**\n * System locale setting\n */\nlet LocaleConf: I18n | string = 'en'\nlet LocaleDict: I18n = findLocaleSet(LocaleConf) // en by default\n\n/**\n * Set system locale\n */\nexport function setLocale(locale: I18n | string) {\n  if (locale === LocaleConf) return\n  LocaleConf = locale\n  LocaleDict = typeof locale === 'string' ? findLocaleSet(locale) : locale\n}\n\n/**\n * Get an i18n message by key\n */\nexport function t(key: I18nKeys, args: { [key: string]: string } = {}) {\n  let str = LocaleDict?.[key] || key\n  str = str.replace(/\\{\\s*(\\w+?)\\s*\\}/g, (_, token) => args[token] || '')\n\n  return Utils.htmlEncode(str)\n}\n\nexport default t\n","import type { I18n } from '.'\n\nconst zhCN: I18n = {\n  /* Editor */\n  placeholder: '键入内容...',\n  noComment: '「此时无声胜有声」',\n  send: '发送',\n  signIn: '登录',\n  signUp: '注册',\n  save: '保存',\n  nick: '昵称',\n  email: '邮箱',\n  link: '网址',\n  emoticon: '表情',\n  preview: '预览',\n  uploadImage: '上传图片',\n  uploadFail: '上传失败',\n  commentFail: '评论失败',\n  restoredMsg: '内容已自动恢复',\n  onlyAdminCanReply: '仅管理员可评论',\n  uploadLoginMsg: '填入你的名字邮箱才能上传哦',\n\n  /* List */\n  counter: '{count} 条评论',\n  sortLatest: '最新',\n  sortOldest: '最早',\n  sortBest: '最热',\n  sortAuthor: '作者',\n  openComment: '打开评论',\n  closeComment: '关闭评论',\n  listLoadFailMsg: '无法获取评论列表数据',\n  listRetry: '点击重新获取',\n  loadMore: '加载更多',\n\n  /* Comment */\n  admin: '管理员',\n  reply: '回复',\n  voteUp: '赞同',\n  voteDown: '反对',\n  voteFail: '投票失败',\n  readMore: '阅读更多',\n  actionConfirm: '确认操作',\n  collapse: '折叠',\n  collapsed: '已折叠',\n  collapsedMsg: '该评论已被系统或管理员折叠',\n  expand: '展开',\n  approved: '已审',\n  pending: '待审',\n  pendingMsg: '审核中，仅本人可见。',\n  edit: '编辑',\n  editCancel: '取消编辑',\n  delete: '删除',\n  deleteConfirm: '确认删除',\n  pin: '置顶',\n  unpin: '取消置顶',\n\n  /* Time */\n  seconds: '秒前',\n  minutes: '分钟前',\n  hours: '小时前',\n  days: '天前',\n  now: '刚刚',\n\n  /* Checker */\n  adminCheck: '键入密码来验证管理员身份：',\n  captchaCheck: '键入验证码继续：',\n  confirm: '确认',\n  cancel: '取消',\n\n  /* Sidebar */\n  msgCenter: '通知中心',\n  ctrlCenter: '控制中心',\n\n  /* Auth */\n  userProfile: '个人资料',\n  noAccountPrompt: '没有账号？',\n  haveAccountPrompt: '已有账号？',\n  forgetPassword: '忘记密码',\n  resetPassword: '重置密码',\n  changePassword: '修改密码',\n  confirmPassword: '确认密码',\n  passwordMismatch: '两次输入的密码不一致',\n  verificationCode: '验证码',\n  verifySend: '发送验证码',\n  verifyResend: '重新发送',\n  waitSeconds: '等待 {seconds}秒',\n  emailVerified: '邮箱已验证',\n  password: '密码',\n  username: '用户名',\n  nextStep: '下一步',\n  skipVerify: '跳过验证',\n  logoutConfirm: '确定要退出登录吗？',\n  accountMergeNotice: '您的电子邮件下有多个不同 ID 的账户。',\n  accountMergeSelectOne: '请选择将所有数据合并到其中的一个。',\n  accountMergeConfirm: '所有数据将合并到 ID 为 {id} 的账户中。',\n  dismiss: '忽略',\n  merge: '合并',\n\n  /* General */\n  client: '客户端',\n  server: '服务器',\n  loading: '加载中',\n  loadFail: '加载失败',\n  editing: '修改中',\n  editFail: '修改失败',\n  deleting: '删除中',\n  deleteFail: '删除失败',\n  reqGot: '请求响应',\n  reqAborted: '请求超时或意外终止',\n  updateMsg: '请更新 Artalk {name} 以获得更好的体验！',\n  currentVersion: '当前版本',\n  ignore: '忽略',\n  open: '打开',\n  openName: '打开{name}',\n}\n\nexport default zhCN\n","/**\n * marked v14.1.3 - a markdown parser\n * Copyright (c) 2011-2024, Christopher Jeffrey. (MIT Licensed)\n * https://github.com/markedjs/marked\n */\n\n/**\n * DO NOT EDIT THIS FILE\n * The code in this file is generated from files in ./src/\n */\n\n/**\n * Gets the original marked default options.\n */\nfunction _getDefaults() {\n    return {\n        async: false,\n        breaks: false,\n        extensions: null,\n        gfm: true,\n        hooks: null,\n        pedantic: false,\n        renderer: null,\n        silent: false,\n        tokenizer: null,\n        walkTokens: null,\n    };\n}\nlet _defaults = _getDefaults();\nfunction changeDefaults(newDefaults) {\n    _defaults = newDefaults;\n}\n\n/**\n * Helpers\n */\nconst escapeTest = /[&<>\"']/;\nconst escapeReplace = new RegExp(escapeTest.source, 'g');\nconst escapeTestNoEncode = /[<>\"']|&(?!(#\\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\\w+);)/;\nconst escapeReplaceNoEncode = new RegExp(escapeTestNoEncode.source, 'g');\nconst escapeReplacements = {\n    '&': '&amp;',\n    '<': '&lt;',\n    '>': '&gt;',\n    '\"': '&quot;',\n    \"'\": '&#39;',\n};\nconst getEscapeReplacement = (ch) => escapeReplacements[ch];\nfunction escape$1(html, encode) {\n    if (encode) {\n        if (escapeTest.test(html)) {\n            return html.replace(escapeReplace, getEscapeReplacement);\n        }\n    }\n    else {\n        if (escapeTestNoEncode.test(html)) {\n            return html.replace(escapeReplaceNoEncode, getEscapeReplacement);\n        }\n    }\n    return html;\n}\nconst caret = /(^|[^\\[])\\^/g;\nfunction edit(regex, opt) {\n    let source = typeof regex === 'string' ? regex : regex.source;\n    opt = opt || '';\n    const obj = {\n        replace: (name, val) => {\n            let valSource = typeof val === 'string' ? val : val.source;\n            valSource = valSource.replace(caret, '$1');\n            source = source.replace(name, valSource);\n            return obj;\n        },\n        getRegex: () => {\n            return new RegExp(source, opt);\n        },\n    };\n    return obj;\n}\nfunction cleanUrl(href) {\n    try {\n        href = encodeURI(href).replace(/%25/g, '%');\n    }\n    catch {\n        return null;\n    }\n    return href;\n}\nconst noopTest = { exec: () => null };\nfunction splitCells(tableRow, count) {\n    // ensure that every cell-delimiting pipe has a space\n    // before it to distinguish it from an escaped pipe\n    const row = tableRow.replace(/\\|/g, (match, offset, str) => {\n        let escaped = false;\n        let curr = offset;\n        while (--curr >= 0 && str[curr] === '\\\\')\n            escaped = !escaped;\n        if (escaped) {\n            // odd number of slashes means | is escaped\n            // so we leave it alone\n            return '|';\n        }\n        else {\n            // add space before unescaped |\n            return ' |';\n        }\n    }), cells = row.split(/ \\|/);\n    let i = 0;\n    // First/last cell in a row cannot be empty if it has no leading/trailing pipe\n    if (!cells[0].trim()) {\n        cells.shift();\n    }\n    if (cells.length > 0 && !cells[cells.length - 1].trim()) {\n        cells.pop();\n    }\n    if (count) {\n        if (cells.length > count) {\n            cells.splice(count);\n        }\n        else {\n            while (cells.length < count)\n                cells.push('');\n        }\n    }\n    for (; i < cells.length; i++) {\n        // leading or trailing whitespace is ignored per the gfm spec\n        cells[i] = cells[i].trim().replace(/\\\\\\|/g, '|');\n    }\n    return cells;\n}\n/**\n * Remove trailing 'c's. Equivalent to str.replace(/c*$/, '').\n * /c*$/ is vulnerable to REDOS.\n *\n * @param str\n * @param c\n * @param invert Remove suffix of non-c chars instead. Default falsey.\n */\nfunction rtrim(str, c, invert) {\n    const l = str.length;\n    if (l === 0) {\n        return '';\n    }\n    // Length of suffix matching the invert condition.\n    let suffLen = 0;\n    // Step left until we fail to match the invert condition.\n    while (suffLen < l) {\n        const currChar = str.charAt(l - suffLen - 1);\n        if (currChar === c && !invert) {\n            suffLen++;\n        }\n        else if (currChar !== c && invert) {\n            suffLen++;\n        }\n        else {\n            break;\n        }\n    }\n    return str.slice(0, l - suffLen);\n}\nfunction findClosingBracket(str, b) {\n    if (str.indexOf(b[1]) === -1) {\n        return -1;\n    }\n    let level = 0;\n    for (let i = 0; i < str.length; i++) {\n        if (str[i] === '\\\\') {\n            i++;\n        }\n        else if (str[i] === b[0]) {\n            level++;\n        }\n        else if (str[i] === b[1]) {\n            level--;\n            if (level < 0) {\n                return i;\n            }\n        }\n    }\n    return -1;\n}\n\nfunction outputLink(cap, link, raw, lexer) {\n    const href = link.href;\n    const title = link.title ? escape$1(link.title) : null;\n    const text = cap[1].replace(/\\\\([\\[\\]])/g, '$1');\n    if (cap[0].charAt(0) !== '!') {\n        lexer.state.inLink = true;\n        const token = {\n            type: 'link',\n            raw,\n            href,\n            title,\n            text,\n            tokens: lexer.inlineTokens(text),\n        };\n        lexer.state.inLink = false;\n        return token;\n    }\n    return {\n        type: 'image',\n        raw,\n        href,\n        title,\n        text: escape$1(text),\n    };\n}\nfunction indentCodeCompensation(raw, text) {\n    const matchIndentToCode = raw.match(/^(\\s+)(?:```)/);\n    if (matchIndentToCode === null) {\n        return text;\n    }\n    const indentToCode = matchIndentToCode[1];\n    return text\n        .split('\\n')\n        .map(node => {\n        const matchIndentInNode = node.match(/^\\s+/);\n        if (matchIndentInNode === null) {\n            return node;\n        }\n        const [indentInNode] = matchIndentInNode;\n        if (indentInNode.length >= indentToCode.length) {\n            return node.slice(indentToCode.length);\n        }\n        return node;\n    })\n        .join('\\n');\n}\n/**\n * Tokenizer\n */\nclass _Tokenizer {\n    options;\n    rules; // set by the lexer\n    lexer; // set by the lexer\n    constructor(options) {\n        this.options = options || _defaults;\n    }\n    space(src) {\n        const cap = this.rules.block.newline.exec(src);\n        if (cap && cap[0].length > 0) {\n            return {\n                type: 'space',\n                raw: cap[0],\n            };\n        }\n    }\n    code(src) {\n        const cap = this.rules.block.code.exec(src);\n        if (cap) {\n            const text = cap[0].replace(/^(?: {1,4}| {0,3}\\t)/gm, '');\n            return {\n                type: 'code',\n                raw: cap[0],\n                codeBlockStyle: 'indented',\n                text: !this.options.pedantic\n                    ? rtrim(text, '\\n')\n                    : text,\n            };\n        }\n    }\n    fences(src) {\n        const cap = this.rules.block.fences.exec(src);\n        if (cap) {\n            const raw = cap[0];\n            const text = indentCodeCompensation(raw, cap[3] || '');\n            return {\n                type: 'code',\n                raw,\n                lang: cap[2] ? cap[2].trim().replace(this.rules.inline.anyPunctuation, '$1') : cap[2],\n                text,\n            };\n        }\n    }\n    heading(src) {\n        const cap = this.rules.block.heading.exec(src);\n        if (cap) {\n            let text = cap[2].trim();\n            // remove trailing #s\n            if (/#$/.test(text)) {\n                const trimmed = rtrim(text, '#');\n                if (this.options.pedantic) {\n                    text = trimmed.trim();\n                }\n                else if (!trimmed || / $/.test(trimmed)) {\n                    // CommonMark requires space before trailing #s\n                    text = trimmed.trim();\n                }\n            }\n            return {\n                type: 'heading',\n                raw: cap[0],\n                depth: cap[1].length,\n                text,\n                tokens: this.lexer.inline(text),\n            };\n        }\n    }\n    hr(src) {\n        const cap = this.rules.block.hr.exec(src);\n        if (cap) {\n            return {\n                type: 'hr',\n                raw: rtrim(cap[0], '\\n'),\n            };\n        }\n    }\n    blockquote(src) {\n        const cap = this.rules.block.blockquote.exec(src);\n        if (cap) {\n            let lines = rtrim(cap[0], '\\n').split('\\n');\n            let raw = '';\n            let text = '';\n            const tokens = [];\n            while (lines.length > 0) {\n                let inBlockquote = false;\n                const currentLines = [];\n                let i;\n                for (i = 0; i < lines.length; i++) {\n                    // get lines up to a continuation\n                    if (/^ {0,3}>/.test(lines[i])) {\n                        currentLines.push(lines[i]);\n                        inBlockquote = true;\n                    }\n                    else if (!inBlockquote) {\n                        currentLines.push(lines[i]);\n                    }\n                    else {\n                        break;\n                    }\n                }\n                lines = lines.slice(i);\n                const currentRaw = currentLines.join('\\n');\n                const currentText = currentRaw\n                    // precede setext continuation with 4 spaces so it isn't a setext\n                    .replace(/\\n {0,3}((?:=+|-+) *)(?=\\n|$)/g, '\\n    $1')\n                    .replace(/^ {0,3}>[ \\t]?/gm, '');\n                raw = raw ? `${raw}\\n${currentRaw}` : currentRaw;\n                text = text ? `${text}\\n${currentText}` : currentText;\n                // parse blockquote lines as top level tokens\n                // merge paragraphs if this is a continuation\n                const top = this.lexer.state.top;\n                this.lexer.state.top = true;\n                this.lexer.blockTokens(currentText, tokens, true);\n                this.lexer.state.top = top;\n                // if there is no continuation then we are done\n                if (lines.length === 0) {\n                    break;\n                }\n                const lastToken = tokens[tokens.length - 1];\n                if (lastToken?.type === 'code') {\n                    // blockquote continuation cannot be preceded by a code block\n                    break;\n                }\n                else if (lastToken?.type === 'blockquote') {\n                    // include continuation in nested blockquote\n                    const oldToken = lastToken;\n                    const newText = oldToken.raw + '\\n' + lines.join('\\n');\n                    const newToken = this.blockquote(newText);\n                    tokens[tokens.length - 1] = newToken;\n                    raw = raw.substring(0, raw.length - oldToken.raw.length) + newToken.raw;\n                    text = text.substring(0, text.length - oldToken.text.length) + newToken.text;\n                    break;\n                }\n                else if (lastToken?.type === 'list') {\n                    // include continuation in nested list\n                    const oldToken = lastToken;\n                    const newText = oldToken.raw + '\\n' + lines.join('\\n');\n                    const newToken = this.list(newText);\n                    tokens[tokens.length - 1] = newToken;\n                    raw = raw.substring(0, raw.length - lastToken.raw.length) + newToken.raw;\n                    text = text.substring(0, text.length - oldToken.raw.length) + newToken.raw;\n                    lines = newText.substring(tokens[tokens.length - 1].raw.length).split('\\n');\n                    continue;\n                }\n            }\n            return {\n                type: 'blockquote',\n                raw,\n                tokens,\n                text,\n            };\n        }\n    }\n    list(src) {\n        let cap = this.rules.block.list.exec(src);\n        if (cap) {\n            let bull = cap[1].trim();\n            const isordered = bull.length > 1;\n            const list = {\n                type: 'list',\n                raw: '',\n                ordered: isordered,\n                start: isordered ? +bull.slice(0, -1) : '',\n                loose: false,\n                items: [],\n            };\n            bull = isordered ? `\\\\d{1,9}\\\\${bull.slice(-1)}` : `\\\\${bull}`;\n            if (this.options.pedantic) {\n                bull = isordered ? bull : '[*+-]';\n            }\n            // Get next list item\n            const itemRegex = new RegExp(`^( {0,3}${bull})((?:[\\t ][^\\\\n]*)?(?:\\\\n|$))`);\n            let endsWithBlankLine = false;\n            // Check if current bullet point can start a new List Item\n            while (src) {\n                let endEarly = false;\n                let raw = '';\n                let itemContents = '';\n                if (!(cap = itemRegex.exec(src))) {\n                    break;\n                }\n                if (this.rules.block.hr.test(src)) { // End list if bullet was actually HR (possibly move into itemRegex?)\n                    break;\n                }\n                raw = cap[0];\n                src = src.substring(raw.length);\n                let line = cap[2].split('\\n', 1)[0].replace(/^\\t+/, (t) => ' '.repeat(3 * t.length));\n                let nextLine = src.split('\\n', 1)[0];\n                let blankLine = !line.trim();\n                let indent = 0;\n                if (this.options.pedantic) {\n                    indent = 2;\n                    itemContents = line.trimStart();\n                }\n                else if (blankLine) {\n                    indent = cap[1].length + 1;\n                }\n                else {\n                    indent = cap[2].search(/[^ ]/); // Find first non-space char\n                    indent = indent > 4 ? 1 : indent; // Treat indented code blocks (> 4 spaces) as having only 1 indent\n                    itemContents = line.slice(indent);\n                    indent += cap[1].length;\n                }\n                if (blankLine && /^[ \\t]*$/.test(nextLine)) { // Items begin with at most one blank line\n                    raw += nextLine + '\\n';\n                    src = src.substring(nextLine.length + 1);\n                    endEarly = true;\n                }\n                if (!endEarly) {\n                    const nextBulletRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:[*+-]|\\\\d{1,9}[.)])((?:[ \\t][^\\\\n]*)?(?:\\\\n|$))`);\n                    const hrRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\\\* *){3,})(?:\\\\n+|$)`);\n                    const fencesBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:\\`\\`\\`|~~~)`);\n                    const headingBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}#`);\n                    const htmlBeginRegex = new RegExp(`^ {0,${Math.min(3, indent - 1)}}<[a-z].*>`, 'i');\n                    // Check if following lines should be included in List Item\n                    while (src) {\n                        const rawLine = src.split('\\n', 1)[0];\n                        let nextLineWithoutTabs;\n                        nextLine = rawLine;\n                        // Re-align to follow commonmark nesting rules\n                        if (this.options.pedantic) {\n                            nextLine = nextLine.replace(/^ {1,4}(?=( {4})*[^ ])/g, '  ');\n                            nextLineWithoutTabs = nextLine;\n                        }\n                        else {\n                            nextLineWithoutTabs = nextLine.replace(/\\t/g, '    ');\n                        }\n                        // End list item if found code fences\n                        if (fencesBeginRegex.test(nextLine)) {\n                            break;\n                        }\n                        // End list item if found start of new heading\n                        if (headingBeginRegex.test(nextLine)) {\n                            break;\n                        }\n                        // End list item if found start of html block\n                        if (htmlBeginRegex.test(nextLine)) {\n                            break;\n                        }\n                        // End list item if found start of new bullet\n                        if (nextBulletRegex.test(nextLine)) {\n                            break;\n                        }\n                        // Horizontal rule found\n                        if (hrRegex.test(nextLine)) {\n                            break;\n                        }\n                        if (nextLineWithoutTabs.search(/[^ ]/) >= indent || !nextLine.trim()) { // Dedent if possible\n                            itemContents += '\\n' + nextLineWithoutTabs.slice(indent);\n                        }\n                        else {\n                            // not enough indentation\n                            if (blankLine) {\n                                break;\n                            }\n                            // paragraph continuation unless last line was a different block level element\n                            if (line.replace(/\\t/g, '    ').search(/[^ ]/) >= 4) { // indented code block\n                                break;\n                            }\n                            if (fencesBeginRegex.test(line)) {\n                                break;\n                            }\n                            if (headingBeginRegex.test(line)) {\n                                break;\n                            }\n                            if (hrRegex.test(line)) {\n                                break;\n                            }\n                            itemContents += '\\n' + nextLine;\n                        }\n                        if (!blankLine && !nextLine.trim()) { // Check if current line is blank\n                            blankLine = true;\n                        }\n                        raw += rawLine + '\\n';\n                        src = src.substring(rawLine.length + 1);\n                        line = nextLineWithoutTabs.slice(indent);\n                    }\n                }\n                if (!list.loose) {\n                    // If the previous item ended with a blank line, the list is loose\n                    if (endsWithBlankLine) {\n                        list.loose = true;\n                    }\n                    else if (/\\n[ \\t]*\\n[ \\t]*$/.test(raw)) {\n                        endsWithBlankLine = true;\n                    }\n                }\n                let istask = null;\n                let ischecked;\n                // Check for task list items\n                if (this.options.gfm) {\n                    istask = /^\\[[ xX]\\] /.exec(itemContents);\n                    if (istask) {\n                        ischecked = istask[0] !== '[ ] ';\n                        itemContents = itemContents.replace(/^\\[[ xX]\\] +/, '');\n                    }\n                }\n                list.items.push({\n                    type: 'list_item',\n                    raw,\n                    task: !!istask,\n                    checked: ischecked,\n                    loose: false,\n                    text: itemContents,\n                    tokens: [],\n                });\n                list.raw += raw;\n            }\n            // Do not consume newlines at end of final item. Alternatively, make itemRegex *start* with any newlines to simplify/speed up endsWithBlankLine logic\n            list.items[list.items.length - 1].raw = list.items[list.items.length - 1].raw.trimEnd();\n            list.items[list.items.length - 1].text = list.items[list.items.length - 1].text.trimEnd();\n            list.raw = list.raw.trimEnd();\n            // Item child tokens handled here at end because we needed to have the final item to trim it first\n            for (let i = 0; i < list.items.length; i++) {\n                this.lexer.state.top = false;\n                list.items[i].tokens = this.lexer.blockTokens(list.items[i].text, []);\n                if (!list.loose) {\n                    // Check if list should be loose\n                    const spacers = list.items[i].tokens.filter(t => t.type === 'space');\n                    const hasMultipleLineBreaks = spacers.length > 0 && spacers.some(t => /\\n.*\\n/.test(t.raw));\n                    list.loose = hasMultipleLineBreaks;\n                }\n            }\n            // Set all items to loose if list is loose\n            if (list.loose) {\n                for (let i = 0; i < list.items.length; i++) {\n                    list.items[i].loose = true;\n                }\n            }\n            return list;\n        }\n    }\n    html(src) {\n        const cap = this.rules.block.html.exec(src);\n        if (cap) {\n            const token = {\n                type: 'html',\n                block: true,\n                raw: cap[0],\n                pre: cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style',\n                text: cap[0],\n            };\n            return token;\n        }\n    }\n    def(src) {\n        const cap = this.rules.block.def.exec(src);\n        if (cap) {\n            const tag = cap[1].toLowerCase().replace(/\\s+/g, ' ');\n            const href = cap[2] ? cap[2].replace(/^<(.*)>$/, '$1').replace(this.rules.inline.anyPunctuation, '$1') : '';\n            const title = cap[3] ? cap[3].substring(1, cap[3].length - 1).replace(this.rules.inline.anyPunctuation, '$1') : cap[3];\n            return {\n                type: 'def',\n                tag,\n                raw: cap[0],\n                href,\n                title,\n            };\n        }\n    }\n    table(src) {\n        const cap = this.rules.block.table.exec(src);\n        if (!cap) {\n            return;\n        }\n        if (!/[:|]/.test(cap[2])) {\n            // delimiter row must have a pipe (|) or colon (:) otherwise it is a setext heading\n            return;\n        }\n        const headers = splitCells(cap[1]);\n        const aligns = cap[2].replace(/^\\||\\| *$/g, '').split('|');\n        const rows = cap[3] && cap[3].trim() ? cap[3].replace(/\\n[ \\t]*$/, '').split('\\n') : [];\n        const item = {\n            type: 'table',\n            raw: cap[0],\n            header: [],\n            align: [],\n            rows: [],\n        };\n        if (headers.length !== aligns.length) {\n            // header and align columns must be equal, rows can be different.\n            return;\n        }\n        for (const align of aligns) {\n            if (/^ *-+: *$/.test(align)) {\n                item.align.push('right');\n            }\n            else if (/^ *:-+: *$/.test(align)) {\n                item.align.push('center');\n            }\n            else if (/^ *:-+ *$/.test(align)) {\n                item.align.push('left');\n            }\n            else {\n                item.align.push(null);\n            }\n        }\n        for (let i = 0; i < headers.length; i++) {\n            item.header.push({\n                text: headers[i],\n                tokens: this.lexer.inline(headers[i]),\n                header: true,\n                align: item.align[i],\n            });\n        }\n        for (const row of rows) {\n            item.rows.push(splitCells(row, item.header.length).map((cell, i) => {\n                return {\n                    text: cell,\n                    tokens: this.lexer.inline(cell),\n                    header: false,\n                    align: item.align[i],\n                };\n            }));\n        }\n        return item;\n    }\n    lheading(src) {\n        const cap = this.rules.block.lheading.exec(src);\n        if (cap) {\n            return {\n                type: 'heading',\n                raw: cap[0],\n                depth: cap[2].charAt(0) === '=' ? 1 : 2,\n                text: cap[1],\n                tokens: this.lexer.inline(cap[1]),\n            };\n        }\n    }\n    paragraph(src) {\n        const cap = this.rules.block.paragraph.exec(src);\n        if (cap) {\n            const text = cap[1].charAt(cap[1].length - 1) === '\\n'\n                ? cap[1].slice(0, -1)\n                : cap[1];\n            return {\n                type: 'paragraph',\n                raw: cap[0],\n                text,\n                tokens: this.lexer.inline(text),\n            };\n        }\n    }\n    text(src) {\n        const cap = this.rules.block.text.exec(src);\n        if (cap) {\n            return {\n                type: 'text',\n                raw: cap[0],\n                text: cap[0],\n                tokens: this.lexer.inline(cap[0]),\n            };\n        }\n    }\n    escape(src) {\n        const cap = this.rules.inline.escape.exec(src);\n        if (cap) {\n            return {\n                type: 'escape',\n                raw: cap[0],\n                text: escape$1(cap[1]),\n            };\n        }\n    }\n    tag(src) {\n        const cap = this.rules.inline.tag.exec(src);\n        if (cap) {\n            if (!this.lexer.state.inLink && /^<a /i.test(cap[0])) {\n                this.lexer.state.inLink = true;\n            }\n            else if (this.lexer.state.inLink && /^<\\/a>/i.test(cap[0])) {\n                this.lexer.state.inLink = false;\n            }\n            if (!this.lexer.state.inRawBlock && /^<(pre|code|kbd|script)(\\s|>)/i.test(cap[0])) {\n                this.lexer.state.inRawBlock = true;\n            }\n            else if (this.lexer.state.inRawBlock && /^<\\/(pre|code|kbd|script)(\\s|>)/i.test(cap[0])) {\n                this.lexer.state.inRawBlock = false;\n            }\n            return {\n                type: 'html',\n                raw: cap[0],\n                inLink: this.lexer.state.inLink,\n                inRawBlock: this.lexer.state.inRawBlock,\n                block: false,\n                text: cap[0],\n            };\n        }\n    }\n    link(src) {\n        const cap = this.rules.inline.link.exec(src);\n        if (cap) {\n            const trimmedUrl = cap[2].trim();\n            if (!this.options.pedantic && /^</.test(trimmedUrl)) {\n                // commonmark requires matching angle brackets\n                if (!(/>$/.test(trimmedUrl))) {\n                    return;\n                }\n                // ending angle bracket cannot be escaped\n                const rtrimSlash = rtrim(trimmedUrl.slice(0, -1), '\\\\');\n                if ((trimmedUrl.length - rtrimSlash.length) % 2 === 0) {\n                    return;\n                }\n            }\n            else {\n                // find closing parenthesis\n                const lastParenIndex = findClosingBracket(cap[2], '()');\n                if (lastParenIndex > -1) {\n                    const start = cap[0].indexOf('!') === 0 ? 5 : 4;\n                    const linkLen = start + cap[1].length + lastParenIndex;\n                    cap[2] = cap[2].substring(0, lastParenIndex);\n                    cap[0] = cap[0].substring(0, linkLen).trim();\n                    cap[3] = '';\n                }\n            }\n            let href = cap[2];\n            let title = '';\n            if (this.options.pedantic) {\n                // split pedantic href and title\n                const link = /^([^'\"]*[^\\s])\\s+(['\"])(.*)\\2/.exec(href);\n                if (link) {\n                    href = link[1];\n                    title = link[3];\n                }\n            }\n            else {\n                title = cap[3] ? cap[3].slice(1, -1) : '';\n            }\n            href = href.trim();\n            if (/^</.test(href)) {\n                if (this.options.pedantic && !(/>$/.test(trimmedUrl))) {\n                    // pedantic allows starting angle bracket without ending angle bracket\n                    href = href.slice(1);\n                }\n                else {\n                    href = href.slice(1, -1);\n                }\n            }\n            return outputLink(cap, {\n                href: href ? href.replace(this.rules.inline.anyPunctuation, '$1') : href,\n                title: title ? title.replace(this.rules.inline.anyPunctuation, '$1') : title,\n            }, cap[0], this.lexer);\n        }\n    }\n    reflink(src, links) {\n        let cap;\n        if ((cap = this.rules.inline.reflink.exec(src))\n            || (cap = this.rules.inline.nolink.exec(src))) {\n            const linkString = (cap[2] || cap[1]).replace(/\\s+/g, ' ');\n            const link = links[linkString.toLowerCase()];\n            if (!link) {\n                const text = cap[0].charAt(0);\n                return {\n                    type: 'text',\n                    raw: text,\n                    text,\n                };\n            }\n            return outputLink(cap, link, cap[0], this.lexer);\n        }\n    }\n    emStrong(src, maskedSrc, prevChar = '') {\n        let match = this.rules.inline.emStrongLDelim.exec(src);\n        if (!match)\n            return;\n        // _ can't be between two alphanumerics. \\p{L}\\p{N} includes non-english alphabet/numbers as well\n        if (match[3] && prevChar.match(/[\\p{L}\\p{N}]/u))\n            return;\n        const nextChar = match[1] || match[2] || '';\n        if (!nextChar || !prevChar || this.rules.inline.punctuation.exec(prevChar)) {\n            // unicode Regex counts emoji as 1 char; spread into array for proper count (used multiple times below)\n            const lLength = [...match[0]].length - 1;\n            let rDelim, rLength, delimTotal = lLength, midDelimTotal = 0;\n            const endReg = match[0][0] === '*' ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd;\n            endReg.lastIndex = 0;\n            // Clip maskedSrc to same section of string as src (move to lexer?)\n            maskedSrc = maskedSrc.slice(-1 * src.length + lLength);\n            while ((match = endReg.exec(maskedSrc)) != null) {\n                rDelim = match[1] || match[2] || match[3] || match[4] || match[5] || match[6];\n                if (!rDelim)\n                    continue; // skip single * in __abc*abc__\n                rLength = [...rDelim].length;\n                if (match[3] || match[4]) { // found another Left Delim\n                    delimTotal += rLength;\n                    continue;\n                }\n                else if (match[5] || match[6]) { // either Left or Right Delim\n                    if (lLength % 3 && !((lLength + rLength) % 3)) {\n                        midDelimTotal += rLength;\n                        continue; // CommonMark Emphasis Rules 9-10\n                    }\n                }\n                delimTotal -= rLength;\n                if (delimTotal > 0)\n                    continue; // Haven't found enough closing delimiters\n                // Remove extra characters. *a*** -> *a*\n                rLength = Math.min(rLength, rLength + delimTotal + midDelimTotal);\n                // char length can be >1 for unicode characters;\n                const lastCharLength = [...match[0]][0].length;\n                const raw = src.slice(0, lLength + match.index + lastCharLength + rLength);\n                // Create `em` if smallest delimiter has odd char count. *a***\n                if (Math.min(lLength, rLength) % 2) {\n                    const text = raw.slice(1, -1);\n                    return {\n                        type: 'em',\n                        raw,\n                        text,\n                        tokens: this.lexer.inlineTokens(text),\n                    };\n                }\n                // Create 'strong' if smallest delimiter has even char count. **a***\n                const text = raw.slice(2, -2);\n                return {\n                    type: 'strong',\n                    raw,\n                    text,\n                    tokens: this.lexer.inlineTokens(text),\n                };\n            }\n        }\n    }\n    codespan(src) {\n        const cap = this.rules.inline.code.exec(src);\n        if (cap) {\n            let text = cap[2].replace(/\\n/g, ' ');\n            const hasNonSpaceChars = /[^ ]/.test(text);\n            const hasSpaceCharsOnBothEnds = /^ /.test(text) && / $/.test(text);\n            if (hasNonSpaceChars && hasSpaceCharsOnBothEnds) {\n                text = text.substring(1, text.length - 1);\n            }\n            text = escape$1(text, true);\n            return {\n                type: 'codespan',\n                raw: cap[0],\n                text,\n            };\n        }\n    }\n    br(src) {\n        const cap = this.rules.inline.br.exec(src);\n        if (cap) {\n            return {\n                type: 'br',\n                raw: cap[0],\n            };\n        }\n    }\n    del(src) {\n        const cap = this.rules.inline.del.exec(src);\n        if (cap) {\n            return {\n                type: 'del',\n                raw: cap[0],\n                text: cap[2],\n                tokens: this.lexer.inlineTokens(cap[2]),\n            };\n        }\n    }\n    autolink(src) {\n        const cap = this.rules.inline.autolink.exec(src);\n        if (cap) {\n            let text, href;\n            if (cap[2] === '@') {\n                text = escape$1(cap[1]);\n                href = 'mailto:' + text;\n            }\n            else {\n                text = escape$1(cap[1]);\n                href = text;\n            }\n            return {\n                type: 'link',\n                raw: cap[0],\n                text,\n                href,\n                tokens: [\n                    {\n                        type: 'text',\n                        raw: text,\n                        text,\n                    },\n                ],\n            };\n        }\n    }\n    url(src) {\n        let cap;\n        if (cap = this.rules.inline.url.exec(src)) {\n            let text, href;\n            if (cap[2] === '@') {\n                text = escape$1(cap[0]);\n                href = 'mailto:' + text;\n            }\n            else {\n                // do extended autolink path validation\n                let prevCapZero;\n                do {\n                    prevCapZero = cap[0];\n                    cap[0] = this.rules.inline._backpedal.exec(cap[0])?.[0] ?? '';\n                } while (prevCapZero !== cap[0]);\n                text = escape$1(cap[0]);\n                if (cap[1] === 'www.') {\n                    href = 'http://' + cap[0];\n                }\n                else {\n                    href = cap[0];\n                }\n            }\n            return {\n                type: 'link',\n                raw: cap[0],\n                text,\n                href,\n                tokens: [\n                    {\n                        type: 'text',\n                        raw: text,\n                        text,\n                    },\n                ],\n            };\n        }\n    }\n    inlineText(src) {\n        const cap = this.rules.inline.text.exec(src);\n        if (cap) {\n            let text;\n            if (this.lexer.state.inRawBlock) {\n                text = cap[0];\n            }\n            else {\n                text = escape$1(cap[0]);\n            }\n            return {\n                type: 'text',\n                raw: cap[0],\n                text,\n            };\n        }\n    }\n}\n\n/**\n * Block-Level Grammar\n */\nconst newline = /^(?:[ \\t]*(?:\\n|$))+/;\nconst blockCode = /^((?: {4}| {0,3}\\t)[^\\n]+(?:\\n(?:[ \\t]*(?:\\n|$))*)?)+/;\nconst fences = /^ {0,3}(`{3,}(?=[^`\\n]*(?:\\n|$))|~{3,})([^\\n]*)(?:\\n|$)(?:|([\\s\\S]*?)(?:\\n|$))(?: {0,3}\\1[~`]* *(?=\\n|$)|$)/;\nconst hr = /^ {0,3}((?:-[\\t ]*){3,}|(?:_[ \\t]*){3,}|(?:\\*[ \\t]*){3,})(?:\\n+|$)/;\nconst heading = /^ {0,3}(#{1,6})(?=\\s|$)(.*)(?:\\n+|$)/;\nconst bullet = /(?:[*+-]|\\d{1,9}[.)])/;\nconst lheading = edit(/^(?!bull |blockCode|fences|blockquote|heading|html)((?:.|\\n(?!\\s*?\\n|bull |blockCode|fences|blockquote|heading|html))+?)\\n {0,3}(=+|-+) *(?:\\n+|$)/)\n    .replace(/bull/g, bullet) // lists can interrupt\n    .replace(/blockCode/g, /(?: {4}| {0,3}\\t)/) // indented code blocks can interrupt\n    .replace(/fences/g, / {0,3}(?:`{3,}|~{3,})/) // fenced code blocks can interrupt\n    .replace(/blockquote/g, / {0,3}>/) // blockquote can interrupt\n    .replace(/heading/g, / {0,3}#{1,6}/) // ATX heading can interrupt\n    .replace(/html/g, / {0,3}<[^\\n>]+>\\n/) // block html can interrupt\n    .getRegex();\nconst _paragraph = /^([^\\n]+(?:\\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\\n)[^\\n]+)*)/;\nconst blockText = /^[^\\n]+/;\nconst _blockLabel = /(?!\\s*\\])(?:\\\\.|[^\\[\\]\\\\])+/;\nconst def = edit(/^ {0,3}\\[(label)\\]: *(?:\\n[ \\t]*)?([^<\\s][^\\s]*|<.*?>)(?:(?: +(?:\\n[ \\t]*)?| *\\n[ \\t]*)(title))? *(?:\\n+|$)/)\n    .replace('label', _blockLabel)\n    .replace('title', /(?:\"(?:\\\\\"?|[^\"\\\\])*\"|'[^'\\n]*(?:\\n[^'\\n]+)*\\n?'|\\([^()]*\\))/)\n    .getRegex();\nconst list = edit(/^( {0,3}bull)([ \\t][^\\n]+?)?(?:\\n|$)/)\n    .replace(/bull/g, bullet)\n    .getRegex();\nconst _tag = 'address|article|aside|base|basefont|blockquote|body|caption'\n    + '|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption'\n    + '|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe'\n    + '|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option'\n    + '|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title'\n    + '|tr|track|ul';\nconst _comment = /<!--(?:-?>|[\\s\\S]*?(?:-->|$))/;\nconst html = edit('^ {0,3}(?:' // optional indentation\n    + '<(script|pre|style|textarea)[\\\\s>][\\\\s\\\\S]*?(?:</\\\\1>[^\\\\n]*\\\\n+|$)' // (1)\n    + '|comment[^\\\\n]*(\\\\n+|$)' // (2)\n    + '|<\\\\?[\\\\s\\\\S]*?(?:\\\\?>\\\\n*|$)' // (3)\n    + '|<![A-Z][\\\\s\\\\S]*?(?:>\\\\n*|$)' // (4)\n    + '|<!\\\\[CDATA\\\\[[\\\\s\\\\S]*?(?:\\\\]\\\\]>\\\\n*|$)' // (5)\n    + '|</?(tag)(?: +|\\\\n|/?>)[\\\\s\\\\S]*?(?:(?:\\\\n[ \\t]*)+\\\\n|$)' // (6)\n    + '|<(?!script|pre|style|textarea)([a-z][\\\\w-]*)(?:attribute)*? */?>(?=[ \\\\t]*(?:\\\\n|$))[\\\\s\\\\S]*?(?:(?:\\\\n[ \\t]*)+\\\\n|$)' // (7) open tag\n    + '|</(?!script|pre|style|textarea)[a-z][\\\\w-]*\\\\s*>(?=[ \\\\t]*(?:\\\\n|$))[\\\\s\\\\S]*?(?:(?:\\\\n[ \\t]*)+\\\\n|$)' // (7) closing tag\n    + ')', 'i')\n    .replace('comment', _comment)\n    .replace('tag', _tag)\n    .replace('attribute', / +[a-zA-Z:_][\\w.:-]*(?: *= *\"[^\"\\n]*\"| *= *'[^'\\n]*'| *= *[^\\s\"'=<>`]+)?/)\n    .getRegex();\nconst paragraph = edit(_paragraph)\n    .replace('hr', hr)\n    .replace('heading', ' {0,3}#{1,6}(?:\\\\s|$)')\n    .replace('|lheading', '') // setext headings don't interrupt commonmark paragraphs\n    .replace('|table', '')\n    .replace('blockquote', ' {0,3}>')\n    .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~{3,})[^\\\\n]*\\\\n')\n    .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt\n    .replace('html', '</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)')\n    .replace('tag', _tag) // pars can be interrupted by type (6) html blocks\n    .getRegex();\nconst blockquote = edit(/^( {0,3}> ?(paragraph|[^\\n]*)(?:\\n|$))+/)\n    .replace('paragraph', paragraph)\n    .getRegex();\n/**\n * Normal Block Grammar\n */\nconst blockNormal = {\n    blockquote,\n    code: blockCode,\n    def,\n    fences,\n    heading,\n    hr,\n    html,\n    lheading,\n    list,\n    newline,\n    paragraph,\n    table: noopTest,\n    text: blockText,\n};\n/**\n * GFM Block Grammar\n */\nconst gfmTable = edit('^ *([^\\\\n ].*)\\\\n' // Header\n    + ' {0,3}((?:\\\\| *)?:?-+:? *(?:\\\\| *:?-+:? *)*(?:\\\\| *)?)' // Align\n    + '(?:\\\\n((?:(?! *\\\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\\\n|$))*)\\\\n*|$)') // Cells\n    .replace('hr', hr)\n    .replace('heading', ' {0,3}#{1,6}(?:\\\\s|$)')\n    .replace('blockquote', ' {0,3}>')\n    .replace('code', '(?: {4}| {0,3}\\t)[^\\\\n]')\n    .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~{3,})[^\\\\n]*\\\\n')\n    .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt\n    .replace('html', '</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)')\n    .replace('tag', _tag) // tables can be interrupted by type (6) html blocks\n    .getRegex();\nconst blockGfm = {\n    ...blockNormal,\n    table: gfmTable,\n    paragraph: edit(_paragraph)\n        .replace('hr', hr)\n        .replace('heading', ' {0,3}#{1,6}(?:\\\\s|$)')\n        .replace('|lheading', '') // setext headings don't interrupt commonmark paragraphs\n        .replace('table', gfmTable) // interrupt paragraphs with table\n        .replace('blockquote', ' {0,3}>')\n        .replace('fences', ' {0,3}(?:`{3,}(?=[^`\\\\n]*\\\\n)|~{3,})[^\\\\n]*\\\\n')\n        .replace('list', ' {0,3}(?:[*+-]|1[.)]) ') // only lists starting from 1 can interrupt\n        .replace('html', '</?(?:tag)(?: +|\\\\n|/?>)|<(?:script|pre|style|textarea|!--)')\n        .replace('tag', _tag) // pars can be interrupted by type (6) html blocks\n        .getRegex(),\n};\n/**\n * Pedantic grammar (original John Gruber's loose markdown specification)\n */\nconst blockPedantic = {\n    ...blockNormal,\n    html: edit('^ *(?:comment *(?:\\\\n|\\\\s*$)'\n        + '|<(tag)[\\\\s\\\\S]+?</\\\\1> *(?:\\\\n{2,}|\\\\s*$)' // closed tag\n        + '|<tag(?:\"[^\"]*\"|\\'[^\\']*\\'|\\\\s[^\\'\"/>\\\\s]*)*?/?> *(?:\\\\n{2,}|\\\\s*$))')\n        .replace('comment', _comment)\n        .replace(/tag/g, '(?!(?:'\n        + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub'\n        + '|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)'\n        + '\\\\b)\\\\w+(?!:|[^\\\\w\\\\s@]*@)\\\\b')\n        .getRegex(),\n    def: /^ *\\[([^\\]]+)\\]: *<?([^\\s>]+)>?(?: +([\"(][^\\n]+[\")]))? *(?:\\n+|$)/,\n    heading: /^(#{1,6})(.*)(?:\\n+|$)/,\n    fences: noopTest, // fences not supported\n    lheading: /^(.+?)\\n {0,3}(=+|-+) *(?:\\n+|$)/,\n    paragraph: edit(_paragraph)\n        .replace('hr', hr)\n        .replace('heading', ' *#{1,6} *[^\\n]')\n        .replace('lheading', lheading)\n        .replace('|table', '')\n        .replace('blockquote', ' {0,3}>')\n        .replace('|fences', '')\n        .replace('|list', '')\n        .replace('|html', '')\n        .replace('|tag', '')\n        .getRegex(),\n};\n/**\n * Inline-Level Grammar\n */\nconst escape = /^\\\\([!\"#$%&'()*+,\\-./:;<=>?@\\[\\]\\\\^_`{|}~])/;\nconst inlineCode = /^(`+)([^`]|[^`][\\s\\S]*?[^`])\\1(?!`)/;\nconst br = /^( {2,}|\\\\)\\n(?!\\s*$)/;\nconst inlineText = /^(`+|[^`])(?:(?= {2,}\\n)|[\\s\\S]*?(?:(?=[\\\\<!\\[`*_]|\\b_|$)|[^ ](?= {2,}\\n)))/;\n// list of unicode punctuation marks, plus any missing characters from CommonMark spec\nconst _punctuation = '\\\\p{P}\\\\p{S}';\nconst punctuation = edit(/^((?![*_])[\\spunctuation])/, 'u')\n    .replace(/punctuation/g, _punctuation).getRegex();\n// sequences em should skip over [title](link), `code`, <html>\nconst blockSkip = /\\[[^[\\]]*?\\]\\((?:\\\\.|[^\\\\\\(\\)]|\\((?:\\\\.|[^\\\\\\(\\)])*\\))*\\)|`[^`]*?`|<[^<>]*?>/g;\nconst emStrongLDelim = edit(/^(?:\\*+(?:((?!\\*)[punct])|[^\\s*]))|^_+(?:((?!_)[punct])|([^\\s_]))/, 'u')\n    .replace(/punct/g, _punctuation)\n    .getRegex();\nconst emStrongRDelimAst = edit('^[^_*]*?__[^_*]*?\\\\*[^_*]*?(?=__)' // Skip orphan inside strong\n    + '|[^*]+(?=[^*])' // Consume to delim\n    + '|(?!\\\\*)[punct](\\\\*+)(?=[\\\\s]|$)' // (1) #*** can only be a Right Delimiter\n    + '|[^punct\\\\s](\\\\*+)(?!\\\\*)(?=[punct\\\\s]|$)' // (2) a***#, a*** can only be a Right Delimiter\n    + '|(?!\\\\*)[punct\\\\s](\\\\*+)(?=[^punct\\\\s])' // (3) #***a, ***a can only be Left Delimiter\n    + '|[\\\\s](\\\\*+)(?!\\\\*)(?=[punct])' // (4) ***# can only be Left Delimiter\n    + '|(?!\\\\*)[punct](\\\\*+)(?!\\\\*)(?=[punct])' // (5) #***# can be either Left or Right Delimiter\n    + '|[^punct\\\\s](\\\\*+)(?=[^punct\\\\s])', 'gu') // (6) a***a can be either Left or Right Delimiter\n    .replace(/punct/g, _punctuation)\n    .getRegex();\n// (6) Not allowed for _\nconst emStrongRDelimUnd = edit('^[^_*]*?\\\\*\\\\*[^_*]*?_[^_*]*?(?=\\\\*\\\\*)' // Skip orphan inside strong\n    + '|[^_]+(?=[^_])' // Consume to delim\n    + '|(?!_)[punct](_+)(?=[\\\\s]|$)' // (1) #___ can only be a Right Delimiter\n    + '|[^punct\\\\s](_+)(?!_)(?=[punct\\\\s]|$)' // (2) a___#, a___ can only be a Right Delimiter\n    + '|(?!_)[punct\\\\s](_+)(?=[^punct\\\\s])' // (3) #___a, ___a can only be Left Delimiter\n    + '|[\\\\s](_+)(?!_)(?=[punct])' // (4) ___# can only be Left Delimiter\n    + '|(?!_)[punct](_+)(?!_)(?=[punct])', 'gu') // (5) #___# can be either Left or Right Delimiter\n    .replace(/punct/g, _punctuation)\n    .getRegex();\nconst anyPunctuation = edit(/\\\\([punct])/, 'gu')\n    .replace(/punct/g, _punctuation)\n    .getRegex();\nconst autolink = edit(/^<(scheme:[^\\s\\x00-\\x1f<>]*|email)>/)\n    .replace('scheme', /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/)\n    .replace('email', /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/)\n    .getRegex();\nconst _inlineComment = edit(_comment).replace('(?:-->|$)', '-->').getRegex();\nconst tag = edit('^comment'\n    + '|^</[a-zA-Z][\\\\w:-]*\\\\s*>' // self-closing tag\n    + '|^<[a-zA-Z][\\\\w-]*(?:attribute)*?\\\\s*/?>' // open tag\n    + '|^<\\\\?[\\\\s\\\\S]*?\\\\?>' // processing instruction, e.g. <?php ?>\n    + '|^<![a-zA-Z]+\\\\s[\\\\s\\\\S]*?>' // declaration, e.g. <!DOCTYPE html>\n    + '|^<!\\\\[CDATA\\\\[[\\\\s\\\\S]*?\\\\]\\\\]>') // CDATA section\n    .replace('comment', _inlineComment)\n    .replace('attribute', /\\s+[a-zA-Z:_][\\w.:-]*(?:\\s*=\\s*\"[^\"]*\"|\\s*=\\s*'[^']*'|\\s*=\\s*[^\\s\"'=<>`]+)?/)\n    .getRegex();\nconst _inlineLabel = /(?:\\[(?:\\\\.|[^\\[\\]\\\\])*\\]|\\\\.|`[^`]*`|[^\\[\\]\\\\`])*?/;\nconst link = edit(/^!?\\[(label)\\]\\(\\s*(href)(?:\\s+(title))?\\s*\\)/)\n    .replace('label', _inlineLabel)\n    .replace('href', /<(?:\\\\.|[^\\n<>\\\\])+>|[^\\s\\x00-\\x1f]*/)\n    .replace('title', /\"(?:\\\\\"?|[^\"\\\\])*\"|'(?:\\\\'?|[^'\\\\])*'|\\((?:\\\\\\)?|[^)\\\\])*\\)/)\n    .getRegex();\nconst reflink = edit(/^!?\\[(label)\\]\\[(ref)\\]/)\n    .replace('label', _inlineLabel)\n    .replace('ref', _blockLabel)\n    .getRegex();\nconst nolink = edit(/^!?\\[(ref)\\](?:\\[\\])?/)\n    .replace('ref', _blockLabel)\n    .getRegex();\nconst reflinkSearch = edit('reflink|nolink(?!\\\\()', 'g')\n    .replace('reflink', reflink)\n    .replace('nolink', nolink)\n    .getRegex();\n/**\n * Normal Inline Grammar\n */\nconst inlineNormal = {\n    _backpedal: noopTest, // only used for GFM url\n    anyPunctuation,\n    autolink,\n    blockSkip,\n    br,\n    code: inlineCode,\n    del: noopTest,\n    emStrongLDelim,\n    emStrongRDelimAst,\n    emStrongRDelimUnd,\n    escape,\n    link,\n    nolink,\n    punctuation,\n    reflink,\n    reflinkSearch,\n    tag,\n    text: inlineText,\n    url: noopTest,\n};\n/**\n * Pedantic Inline Grammar\n */\nconst inlinePedantic = {\n    ...inlineNormal,\n    link: edit(/^!?\\[(label)\\]\\((.*?)\\)/)\n        .replace('label', _inlineLabel)\n        .getRegex(),\n    reflink: edit(/^!?\\[(label)\\]\\s*\\[([^\\]]*)\\]/)\n        .replace('label', _inlineLabel)\n        .getRegex(),\n};\n/**\n * GFM Inline Grammar\n */\nconst inlineGfm = {\n    ...inlineNormal,\n    escape: edit(escape).replace('])', '~|])').getRegex(),\n    url: edit(/^((?:ftp|https?):\\/\\/|www\\.)(?:[a-zA-Z0-9\\-]+\\.?)+[^\\s<]*|^email/, 'i')\n        .replace('email', /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/)\n        .getRegex(),\n    _backpedal: /(?:[^?!.,:;*_'\"~()&]+|\\([^)]*\\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'\"~)]+(?!$))+/,\n    del: /^(~~?)(?=[^\\s~])([\\s\\S]*?[^\\s~])\\1(?=[^~]|$)/,\n    text: /^([`~]+|[^`~])(?:(?= {2,}\\n)|(?=[a-zA-Z0-9.!#$%&'*+\\/=?_`{\\|}~-]+@)|[\\s\\S]*?(?:(?=[\\\\<!\\[`*~_]|\\b_|https?:\\/\\/|ftp:\\/\\/|www\\.|$)|[^ ](?= {2,}\\n)|[^a-zA-Z0-9.!#$%&'*+\\/=?_`{\\|}~-](?=[a-zA-Z0-9.!#$%&'*+\\/=?_`{\\|}~-]+@)))/,\n};\n/**\n * GFM + Line Breaks Inline Grammar\n */\nconst inlineBreaks = {\n    ...inlineGfm,\n    br: edit(br).replace('{2,}', '*').getRegex(),\n    text: edit(inlineGfm.text)\n        .replace('\\\\b_', '\\\\b_| {2,}\\\\n')\n        .replace(/\\{2,\\}/g, '*')\n        .getRegex(),\n};\n/**\n * exports\n */\nconst block = {\n    normal: blockNormal,\n    gfm: blockGfm,\n    pedantic: blockPedantic,\n};\nconst inline = {\n    normal: inlineNormal,\n    gfm: inlineGfm,\n    breaks: inlineBreaks,\n    pedantic: inlinePedantic,\n};\n\n/**\n * Block Lexer\n */\nclass _Lexer {\n    tokens;\n    options;\n    state;\n    tokenizer;\n    inlineQueue;\n    constructor(options) {\n        // TokenList cannot be created in one go\n        this.tokens = [];\n        this.tokens.links = Object.create(null);\n        this.options = options || _defaults;\n        this.options.tokenizer = this.options.tokenizer || new _Tokenizer();\n        this.tokenizer = this.options.tokenizer;\n        this.tokenizer.options = this.options;\n        this.tokenizer.lexer = this;\n        this.inlineQueue = [];\n        this.state = {\n            inLink: false,\n            inRawBlock: false,\n            top: true,\n        };\n        const rules = {\n            block: block.normal,\n            inline: inline.normal,\n        };\n        if (this.options.pedantic) {\n            rules.block = block.pedantic;\n            rules.inline = inline.pedantic;\n        }\n        else if (this.options.gfm) {\n            rules.block = block.gfm;\n            if (this.options.breaks) {\n                rules.inline = inline.breaks;\n            }\n            else {\n                rules.inline = inline.gfm;\n            }\n        }\n        this.tokenizer.rules = rules;\n    }\n    /**\n     * Expose Rules\n     */\n    static get rules() {\n        return {\n            block,\n            inline,\n        };\n    }\n    /**\n     * Static Lex Method\n     */\n    static lex(src, options) {\n        const lexer = new _Lexer(options);\n        return lexer.lex(src);\n    }\n    /**\n     * Static Lex Inline Method\n     */\n    static lexInline(src, options) {\n        const lexer = new _Lexer(options);\n        return lexer.inlineTokens(src);\n    }\n    /**\n     * Preprocessing\n     */\n    lex(src) {\n        src = src\n            .replace(/\\r\\n|\\r/g, '\\n');\n        this.blockTokens(src, this.tokens);\n        for (let i = 0; i < this.inlineQueue.length; i++) {\n            const next = this.inlineQueue[i];\n            this.inlineTokens(next.src, next.tokens);\n        }\n        this.inlineQueue = [];\n        return this.tokens;\n    }\n    blockTokens(src, tokens = [], lastParagraphClipped = false) {\n        if (this.options.pedantic) {\n            src = src.replace(/\\t/g, '    ').replace(/^ +$/gm, '');\n        }\n        let token;\n        let lastToken;\n        let cutSrc;\n        while (src) {\n            if (this.options.extensions\n                && this.options.extensions.block\n                && this.options.extensions.block.some((extTokenizer) => {\n                    if (token = extTokenizer.call({ lexer: this }, src, tokens)) {\n                        src = src.substring(token.raw.length);\n                        tokens.push(token);\n                        return true;\n                    }\n                    return false;\n                })) {\n                continue;\n            }\n            // newline\n            if (token = this.tokenizer.space(src)) {\n                src = src.substring(token.raw.length);\n                if (token.raw.length === 1 && tokens.length > 0) {\n                    // if there's a single \\n as a spacer, it's terminating the last line,\n                    // so move it there so that we don't get unnecessary paragraph tags\n                    tokens[tokens.length - 1].raw += '\\n';\n                }\n                else {\n                    tokens.push(token);\n                }\n                continue;\n            }\n            // code\n            if (token = this.tokenizer.code(src)) {\n                src = src.substring(token.raw.length);\n                lastToken = tokens[tokens.length - 1];\n                // An indented code block cannot interrupt a paragraph.\n                if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {\n                    lastToken.raw += '\\n' + token.raw;\n                    lastToken.text += '\\n' + token.text;\n                    this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;\n                }\n                else {\n                    tokens.push(token);\n                }\n                continue;\n            }\n            // fences\n            if (token = this.tokenizer.fences(src)) {\n                src = src.substring(token.raw.length);\n                tokens.push(token);\n                continue;\n            }\n            // heading\n            if (token = this.tokenizer.heading(src)) {\n                src = src.substring(token.raw.length);\n                tokens.push(token);\n                continue;\n            }\n            // hr\n            if (token = this.tokenizer.hr(src)) {\n                src = src.substring(token.raw.length);\n                tokens.push(token);\n                continue;\n            }\n            // blockquote\n            if (token = this.tokenizer.blockquote(src)) {\n                src = src.substring(token.raw.length);\n                tokens.push(token);\n                continue;\n            }\n            // list\n            if (token = this.tokenizer.list(src)) {\n                src = src.substring(token.raw.length);\n                tokens.push(token);\n                continue;\n            }\n            // html\n            if (token = this.tokenizer.html(src)) {\n                src = src.substring(token.raw.length);\n                tokens.push(token);\n                continue;\n            }\n            // def\n            if (token = this.tokenizer.def(src)) {\n                src = src.substring(token.raw.length);\n                lastToken = tokens[tokens.length - 1];\n                if (lastToken && (lastToken.type === 'paragraph' || lastToken.type === 'text')) {\n                    lastToken.raw += '\\n' + token.raw;\n                    lastToken.text += '\\n' + token.raw;\n                    this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;\n                }\n                else if (!this.tokens.links[token.tag]) {\n                    this.tokens.links[token.tag] = {\n                        href: token.href,\n                        title: token.title,\n                    };\n                }\n                continue;\n            }\n            // table (gfm)\n            if (token = this.tokenizer.table(src)) {\n                src = src.substring(token.raw.length);\n                tokens.push(token);\n                continue;\n            }\n            // lheading\n            if (token = this.tokenizer.lheading(src)) {\n                src = src.substring(token.raw.length);\n                tokens.push(token);\n                continue;\n            }\n            // top-level paragraph\n            // prevent paragraph consuming extensions by clipping 'src' to extension start\n            cutSrc = src;\n            if (this.options.extensions && this.options.extensions.startBlock) {\n                let startIndex = Infinity;\n                const tempSrc = src.slice(1);\n                let tempStart;\n                this.options.extensions.startBlock.forEach((getStartIndex) => {\n                    tempStart = getStartIndex.call({ lexer: this }, tempSrc);\n                    if (typeof tempStart === 'number' && tempStart >= 0) {\n                        startIndex = Math.min(startIndex, tempStart);\n                    }\n                });\n                if (startIndex < Infinity && startIndex >= 0) {\n                    cutSrc = src.substring(0, startIndex + 1);\n                }\n            }\n            if (this.state.top && (token = this.tokenizer.paragraph(cutSrc))) {\n                lastToken = tokens[tokens.length - 1];\n                if (lastParagraphClipped && lastToken?.type === 'paragraph') {\n                    lastToken.raw += '\\n' + token.raw;\n                    lastToken.text += '\\n' + token.text;\n                    this.inlineQueue.pop();\n                    this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;\n                }\n                else {\n                    tokens.push(token);\n                }\n                lastParagraphClipped = (cutSrc.length !== src.length);\n                src = src.substring(token.raw.length);\n                continue;\n            }\n            // text\n            if (token = this.tokenizer.text(src)) {\n                src = src.substring(token.raw.length);\n                lastToken = tokens[tokens.length - 1];\n                if (lastToken && lastToken.type === 'text') {\n                    lastToken.raw += '\\n' + token.raw;\n                    lastToken.text += '\\n' + token.text;\n                    this.inlineQueue.pop();\n                    this.inlineQueue[this.inlineQueue.length - 1].src = lastToken.text;\n                }\n                else {\n                    tokens.push(token);\n                }\n                continue;\n            }\n            if (src) {\n                const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);\n                if (this.options.silent) {\n                    console.error(errMsg);\n                    break;\n                }\n                else {\n                    throw new Error(errMsg);\n                }\n            }\n        }\n        this.state.top = true;\n        return tokens;\n    }\n    inline(src, tokens = []) {\n        this.inlineQueue.push({ src, tokens });\n        return tokens;\n    }\n    /**\n     * Lexing/Compiling\n     */\n    inlineTokens(src, tokens = []) {\n        let token, lastToken, cutSrc;\n        // String with links masked to avoid interference with em and strong\n        let maskedSrc = src;\n        let match;\n        let keepPrevChar, prevChar;\n        // Mask out reflinks\n        if (this.tokens.links) {\n            const links = Object.keys(this.tokens.links);\n            if (links.length > 0) {\n                while ((match = this.tokenizer.rules.inline.reflinkSearch.exec(maskedSrc)) != null) {\n                    if (links.includes(match[0].slice(match[0].lastIndexOf('[') + 1, -1))) {\n                        maskedSrc = maskedSrc.slice(0, match.index) + '[' + 'a'.repeat(match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex);\n                    }\n                }\n            }\n        }\n        // Mask out other blocks\n        while ((match = this.tokenizer.rules.inline.blockSkip.exec(maskedSrc)) != null) {\n            maskedSrc = maskedSrc.slice(0, match.index) + '[' + 'a'.repeat(match[0].length - 2) + ']' + maskedSrc.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);\n        }\n        // Mask out escaped characters\n        while ((match = this.tokenizer.rules.inline.anyPunctuation.exec(maskedSrc)) != null) {\n            maskedSrc = maskedSrc.slice(0, match.index) + '++' + maskedSrc.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);\n        }\n        while (src) {\n            if (!keepPrevChar) {\n                prevChar = '';\n            }\n            keepPrevChar = false;\n            // extensions\n            if (this.options.extensions\n                && this.options.extensions.inline\n                && this.options.extensions.inline.some((extTokenizer) => {\n                    if (token = extTokenizer.call({ lexer: this }, src, tokens)) {\n                        src = src.substring(token.raw.length);\n                        tokens.push(token);\n                        return true;\n                    }\n                    return false;\n                })) {\n                continue;\n            }\n            // escape\n            if (token = this.tokenizer.escape(src)) {\n                src = src.substring(token.raw.length);\n                tokens.push(token);\n                continue;\n            }\n            // tag\n            if (token = this.tokenizer.tag(src)) {\n                src = src.substring(token.raw.length);\n                lastToken = tokens[tokens.length - 1];\n                if (lastToken && token.type === 'text' && lastToken.type === 'text') {\n                    lastToken.raw += token.raw;\n                    lastToken.text += token.text;\n                }\n                else {\n                    tokens.push(token);\n                }\n                continue;\n            }\n            // link\n            if (token = this.tokenizer.link(src)) {\n                src = src.substring(token.raw.length);\n                tokens.push(token);\n                continue;\n            }\n            // reflink, nolink\n            if (token = this.tokenizer.reflink(src, this.tokens.links)) {\n                src = src.substring(token.raw.length);\n                lastToken = tokens[tokens.length - 1];\n                if (lastToken && token.type === 'text' && lastToken.type === 'text') {\n                    lastToken.raw += token.raw;\n                    lastToken.text += token.text;\n                }\n                else {\n                    tokens.push(token);\n                }\n                continue;\n            }\n            // em & strong\n            if (token = this.tokenizer.emStrong(src, maskedSrc, prevChar)) {\n                src = src.substring(token.raw.length);\n                tokens.push(token);\n                continue;\n            }\n            // code\n            if (token = this.tokenizer.codespan(src)) {\n                src = src.substring(token.raw.length);\n                tokens.push(token);\n                continue;\n            }\n            // br\n            if (token = this.tokenizer.br(src)) {\n                src = src.substring(token.raw.length);\n                tokens.push(token);\n                continue;\n            }\n            // del (gfm)\n            if (token = this.tokenizer.del(src)) {\n                src = src.substring(token.raw.length);\n                tokens.push(token);\n                continue;\n            }\n            // autolink\n            if (token = this.tokenizer.autolink(src)) {\n                src = src.substring(token.raw.length);\n                tokens.push(token);\n                continue;\n            }\n            // url (gfm)\n            if (!this.state.inLink && (token = this.tokenizer.url(src))) {\n                src = src.substring(token.raw.length);\n                tokens.push(token);\n                continue;\n            }\n            // text\n            // prevent inlineText consuming extensions by clipping 'src' to extension start\n            cutSrc = src;\n            if (this.options.extensions && this.options.extensions.startInline) {\n                let startIndex = Infinity;\n                const tempSrc = src.slice(1);\n                let tempStart;\n                this.options.extensions.startInline.forEach((getStartIndex) => {\n                    tempStart = getStartIndex.call({ lexer: this }, tempSrc);\n                    if (typeof tempStart === 'number' && tempStart >= 0) {\n                        startIndex = Math.min(startIndex, tempStart);\n                    }\n                });\n                if (startIndex < Infinity && startIndex >= 0) {\n                    cutSrc = src.substring(0, startIndex + 1);\n                }\n            }\n            if (token = this.tokenizer.inlineText(cutSrc)) {\n                src = src.substring(token.raw.length);\n                if (token.raw.slice(-1) !== '_') { // Track prevChar before string of ____ started\n                    prevChar = token.raw.slice(-1);\n                }\n                keepPrevChar = true;\n                lastToken = tokens[tokens.length - 1];\n                if (lastToken && lastToken.type === 'text') {\n                    lastToken.raw += token.raw;\n                    lastToken.text += token.text;\n                }\n                else {\n                    tokens.push(token);\n                }\n                continue;\n            }\n            if (src) {\n                const errMsg = 'Infinite loop on byte: ' + src.charCodeAt(0);\n                if (this.options.silent) {\n                    console.error(errMsg);\n                    break;\n                }\n                else {\n                    throw new Error(errMsg);\n                }\n            }\n        }\n        return tokens;\n    }\n}\n\n/**\n * Renderer\n */\nclass _Renderer {\n    options;\n    parser; // set by the parser\n    constructor(options) {\n        this.options = options || _defaults;\n    }\n    space(token) {\n        return '';\n    }\n    code({ text, lang, escaped }) {\n        const langString = (lang || '').match(/^\\S*/)?.[0];\n        const code = text.replace(/\\n$/, '') + '\\n';\n        if (!langString) {\n            return '<pre><code>'\n                + (escaped ? code : escape$1(code, true))\n                + '</code></pre>\\n';\n        }\n        return '<pre><code class=\"language-'\n            + escape$1(langString)\n            + '\">'\n            + (escaped ? code : escape$1(code, true))\n            + '</code></pre>\\n';\n    }\n    blockquote({ tokens }) {\n        const body = this.parser.parse(tokens);\n        return `<blockquote>\\n${body}</blockquote>\\n`;\n    }\n    html({ text }) {\n        return text;\n    }\n    heading({ tokens, depth }) {\n        return `<h${depth}>${this.parser.parseInline(tokens)}</h${depth}>\\n`;\n    }\n    hr(token) {\n        return '<hr>\\n';\n    }\n    list(token) {\n        const ordered = token.ordered;\n        const start = token.start;\n        let body = '';\n        for (let j = 0; j < token.items.length; j++) {\n            const item = token.items[j];\n            body += this.listitem(item);\n        }\n        const type = ordered ? 'ol' : 'ul';\n        const startAttr = (ordered && start !== 1) ? (' start=\"' + start + '\"') : '';\n        return '<' + type + startAttr + '>\\n' + body + '</' + type + '>\\n';\n    }\n    listitem(item) {\n        let itemBody = '';\n        if (item.task) {\n            const checkbox = this.checkbox({ checked: !!item.checked });\n            if (item.loose) {\n                if (item.tokens.length > 0 && item.tokens[0].type === 'paragraph') {\n                    item.tokens[0].text = checkbox + ' ' + item.tokens[0].text;\n                    if (item.tokens[0].tokens && item.tokens[0].tokens.length > 0 && item.tokens[0].tokens[0].type === 'text') {\n                        item.tokens[0].tokens[0].text = checkbox + ' ' + item.tokens[0].tokens[0].text;\n                    }\n                }\n                else {\n                    item.tokens.unshift({\n                        type: 'text',\n                        raw: checkbox + ' ',\n                        text: checkbox + ' ',\n                    });\n                }\n            }\n            else {\n                itemBody += checkbox + ' ';\n            }\n        }\n        itemBody += this.parser.parse(item.tokens, !!item.loose);\n        return `<li>${itemBody}</li>\\n`;\n    }\n    checkbox({ checked }) {\n        return '<input '\n            + (checked ? 'checked=\"\" ' : '')\n            + 'disabled=\"\" type=\"checkbox\">';\n    }\n    paragraph({ tokens }) {\n        return `<p>${this.parser.parseInline(tokens)}</p>\\n`;\n    }\n    table(token) {\n        let header = '';\n        // header\n        let cell = '';\n        for (let j = 0; j < token.header.length; j++) {\n            cell += this.tablecell(token.header[j]);\n        }\n        header += this.tablerow({ text: cell });\n        let body = '';\n        for (let j = 0; j < token.rows.length; j++) {\n            const row = token.rows[j];\n            cell = '';\n            for (let k = 0; k < row.length; k++) {\n                cell += this.tablecell(row[k]);\n            }\n            body += this.tablerow({ text: cell });\n        }\n        if (body)\n            body = `<tbody>${body}</tbody>`;\n        return '<table>\\n'\n            + '<thead>\\n'\n            + header\n            + '</thead>\\n'\n            + body\n            + '</table>\\n';\n    }\n    tablerow({ text }) {\n        return `<tr>\\n${text}</tr>\\n`;\n    }\n    tablecell(token) {\n        const content = this.parser.parseInline(token.tokens);\n        const type = token.header ? 'th' : 'td';\n        const tag = token.align\n            ? `<${type} align=\"${token.align}\">`\n            : `<${type}>`;\n        return tag + content + `</${type}>\\n`;\n    }\n    /**\n     * span level renderer\n     */\n    strong({ tokens }) {\n        return `<strong>${this.parser.parseInline(tokens)}</strong>`;\n    }\n    em({ tokens }) {\n        return `<em>${this.parser.parseInline(tokens)}</em>`;\n    }\n    codespan({ text }) {\n        return `<code>${text}</code>`;\n    }\n    br(token) {\n        return '<br>';\n    }\n    del({ tokens }) {\n        return `<del>${this.parser.parseInline(tokens)}</del>`;\n    }\n    link({ href, title, tokens }) {\n        const text = this.parser.parseInline(tokens);\n        const cleanHref = cleanUrl(href);\n        if (cleanHref === null) {\n            return text;\n        }\n        href = cleanHref;\n        let out = '<a href=\"' + href + '\"';\n        if (title) {\n            out += ' title=\"' + title + '\"';\n        }\n        out += '>' + text + '</a>';\n        return out;\n    }\n    image({ href, title, text }) {\n        const cleanHref = cleanUrl(href);\n        if (cleanHref === null) {\n            return text;\n        }\n        href = cleanHref;\n        let out = `<img src=\"${href}\" alt=\"${text}\"`;\n        if (title) {\n            out += ` title=\"${title}\"`;\n        }\n        out += '>';\n        return out;\n    }\n    text(token) {\n        return 'tokens' in token && token.tokens ? this.parser.parseInline(token.tokens) : token.text;\n    }\n}\n\n/**\n * TextRenderer\n * returns only the textual part of the token\n */\nclass _TextRenderer {\n    // no need for block level renderers\n    strong({ text }) {\n        return text;\n    }\n    em({ text }) {\n        return text;\n    }\n    codespan({ text }) {\n        return text;\n    }\n    del({ text }) {\n        return text;\n    }\n    html({ text }) {\n        return text;\n    }\n    text({ text }) {\n        return text;\n    }\n    link({ text }) {\n        return '' + text;\n    }\n    image({ text }) {\n        return '' + text;\n    }\n    br() {\n        return '';\n    }\n}\n\n/**\n * Parsing & Compiling\n */\nclass _Parser {\n    options;\n    renderer;\n    textRenderer;\n    constructor(options) {\n        this.options = options || _defaults;\n        this.options.renderer = this.options.renderer || new _Renderer();\n        this.renderer = this.options.renderer;\n        this.renderer.options = this.options;\n        this.renderer.parser = this;\n        this.textRenderer = new _TextRenderer();\n    }\n    /**\n     * Static Parse Method\n     */\n    static parse(tokens, options) {\n        const parser = new _Parser(options);\n        return parser.parse(tokens);\n    }\n    /**\n     * Static Parse Inline Method\n     */\n    static parseInline(tokens, options) {\n        const parser = new _Parser(options);\n        return parser.parseInline(tokens);\n    }\n    /**\n     * Parse Loop\n     */\n    parse(tokens, top = true) {\n        let out = '';\n        for (let i = 0; i < tokens.length; i++) {\n            const anyToken = tokens[i];\n            // Run any renderer extensions\n            if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[anyToken.type]) {\n                const genericToken = anyToken;\n                const ret = this.options.extensions.renderers[genericToken.type].call({ parser: this }, genericToken);\n                if (ret !== false || !['space', 'hr', 'heading', 'code', 'table', 'blockquote', 'list', 'html', 'paragraph', 'text'].includes(genericToken.type)) {\n                    out += ret || '';\n                    continue;\n                }\n            }\n            const token = anyToken;\n            switch (token.type) {\n                case 'space': {\n                    out += this.renderer.space(token);\n                    continue;\n                }\n                case 'hr': {\n                    out += this.renderer.hr(token);\n                    continue;\n                }\n                case 'heading': {\n                    out += this.renderer.heading(token);\n                    continue;\n                }\n                case 'code': {\n                    out += this.renderer.code(token);\n                    continue;\n                }\n                case 'table': {\n                    out += this.renderer.table(token);\n                    continue;\n                }\n                case 'blockquote': {\n                    out += this.renderer.blockquote(token);\n                    continue;\n                }\n                case 'list': {\n                    out += this.renderer.list(token);\n                    continue;\n                }\n                case 'html': {\n                    out += this.renderer.html(token);\n                    continue;\n                }\n                case 'paragraph': {\n                    out += this.renderer.paragraph(token);\n                    continue;\n                }\n                case 'text': {\n                    let textToken = token;\n                    let body = this.renderer.text(textToken);\n                    while (i + 1 < tokens.length && tokens[i + 1].type === 'text') {\n                        textToken = tokens[++i];\n                        body += '\\n' + this.renderer.text(textToken);\n                    }\n                    if (top) {\n                        out += this.renderer.paragraph({\n                            type: 'paragraph',\n                            raw: body,\n                            text: body,\n                            tokens: [{ type: 'text', raw: body, text: body }],\n                        });\n                    }\n                    else {\n                        out += body;\n                    }\n                    continue;\n                }\n                default: {\n                    const errMsg = 'Token with \"' + token.type + '\" type was not found.';\n                    if (this.options.silent) {\n                        console.error(errMsg);\n                        return '';\n                    }\n                    else {\n                        throw new Error(errMsg);\n                    }\n                }\n            }\n        }\n        return out;\n    }\n    /**\n     * Parse Inline Tokens\n     */\n    parseInline(tokens, renderer) {\n        renderer = renderer || this.renderer;\n        let out = '';\n        for (let i = 0; i < tokens.length; i++) {\n            const anyToken = tokens[i];\n            // Run any renderer extensions\n            if (this.options.extensions && this.options.extensions.renderers && this.options.extensions.renderers[anyToken.type]) {\n                const ret = this.options.extensions.renderers[anyToken.type].call({ parser: this }, anyToken);\n                if (ret !== false || !['escape', 'html', 'link', 'image', 'strong', 'em', 'codespan', 'br', 'del', 'text'].includes(anyToken.type)) {\n                    out += ret || '';\n                    continue;\n                }\n            }\n            const token = anyToken;\n            switch (token.type) {\n                case 'escape': {\n                    out += renderer.text(token);\n                    break;\n                }\n                case 'html': {\n                    out += renderer.html(token);\n                    break;\n                }\n                case 'link': {\n                    out += renderer.link(token);\n                    break;\n                }\n                case 'image': {\n                    out += renderer.image(token);\n                    break;\n                }\n                case 'strong': {\n                    out += renderer.strong(token);\n                    break;\n                }\n                case 'em': {\n                    out += renderer.em(token);\n                    break;\n                }\n                case 'codespan': {\n                    out += renderer.codespan(token);\n                    break;\n                }\n                case 'br': {\n                    out += renderer.br(token);\n                    break;\n                }\n                case 'del': {\n                    out += renderer.del(token);\n                    break;\n                }\n                case 'text': {\n                    out += renderer.text(token);\n                    break;\n                }\n                default: {\n                    const errMsg = 'Token with \"' + token.type + '\" type was not found.';\n                    if (this.options.silent) {\n                        console.error(errMsg);\n                        return '';\n                    }\n                    else {\n                        throw new Error(errMsg);\n                    }\n                }\n            }\n        }\n        return out;\n    }\n}\n\nclass _Hooks {\n    options;\n    block;\n    constructor(options) {\n        this.options = options || _defaults;\n    }\n    static passThroughHooks = new Set([\n        'preprocess',\n        'postprocess',\n        'processAllTokens',\n    ]);\n    /**\n     * Process markdown before marked\n     */\n    preprocess(markdown) {\n        return markdown;\n    }\n    /**\n     * Process HTML after marked is finished\n     */\n    postprocess(html) {\n        return html;\n    }\n    /**\n     * Process all tokens before walk tokens\n     */\n    processAllTokens(tokens) {\n        return tokens;\n    }\n    /**\n     * Provide function to tokenize markdown\n     */\n    provideLexer() {\n        return this.block ? _Lexer.lex : _Lexer.lexInline;\n    }\n    /**\n     * Provide function to parse tokens\n     */\n    provideParser() {\n        return this.block ? _Parser.parse : _Parser.parseInline;\n    }\n}\n\nclass Marked {\n    defaults = _getDefaults();\n    options = this.setOptions;\n    parse = this.parseMarkdown(true);\n    parseInline = this.parseMarkdown(false);\n    Parser = _Parser;\n    Renderer = _Renderer;\n    TextRenderer = _TextRenderer;\n    Lexer = _Lexer;\n    Tokenizer = _Tokenizer;\n    Hooks = _Hooks;\n    constructor(...args) {\n        this.use(...args);\n    }\n    /**\n     * Run callback for every token\n     */\n    walkTokens(tokens, callback) {\n        let values = [];\n        for (const token of tokens) {\n            values = values.concat(callback.call(this, token));\n            switch (token.type) {\n                case 'table': {\n                    const tableToken = token;\n                    for (const cell of tableToken.header) {\n                        values = values.concat(this.walkTokens(cell.tokens, callback));\n                    }\n                    for (const row of tableToken.rows) {\n                        for (const cell of row) {\n                            values = values.concat(this.walkTokens(cell.tokens, callback));\n                        }\n                    }\n                    break;\n                }\n                case 'list': {\n                    const listToken = token;\n                    values = values.concat(this.walkTokens(listToken.items, callback));\n                    break;\n                }\n                default: {\n                    const genericToken = token;\n                    if (this.defaults.extensions?.childTokens?.[genericToken.type]) {\n                        this.defaults.extensions.childTokens[genericToken.type].forEach((childTokens) => {\n                            const tokens = genericToken[childTokens].flat(Infinity);\n                            values = values.concat(this.walkTokens(tokens, callback));\n                        });\n                    }\n                    else if (genericToken.tokens) {\n                        values = values.concat(this.walkTokens(genericToken.tokens, callback));\n                    }\n                }\n            }\n        }\n        return values;\n    }\n    use(...args) {\n        const extensions = this.defaults.extensions || { renderers: {}, childTokens: {} };\n        args.forEach((pack) => {\n            // copy options to new object\n            const opts = { ...pack };\n            // set async to true if it was set to true before\n            opts.async = this.defaults.async || opts.async || false;\n            // ==-- Parse \"addon\" extensions --== //\n            if (pack.extensions) {\n                pack.extensions.forEach((ext) => {\n                    if (!ext.name) {\n                        throw new Error('extension name required');\n                    }\n                    if ('renderer' in ext) { // Renderer extensions\n                        const prevRenderer = extensions.renderers[ext.name];\n                        if (prevRenderer) {\n                            // Replace extension with func to run new extension but fall back if false\n                            extensions.renderers[ext.name] = function (...args) {\n                                let ret = ext.renderer.apply(this, args);\n                                if (ret === false) {\n                                    ret = prevRenderer.apply(this, args);\n                                }\n                                return ret;\n                            };\n                        }\n                        else {\n                            extensions.renderers[ext.name] = ext.renderer;\n                        }\n                    }\n                    if ('tokenizer' in ext) { // Tokenizer Extensions\n                        if (!ext.level || (ext.level !== 'block' && ext.level !== 'inline')) {\n                            throw new Error(\"extension level must be 'block' or 'inline'\");\n                        }\n                        const extLevel = extensions[ext.level];\n                        if (extLevel) {\n                            extLevel.unshift(ext.tokenizer);\n                        }\n                        else {\n                            extensions[ext.level] = [ext.tokenizer];\n                        }\n                        if (ext.start) { // Function to check for start of token\n                            if (ext.level === 'block') {\n                                if (extensions.startBlock) {\n                                    extensions.startBlock.push(ext.start);\n                                }\n                                else {\n                                    extensions.startBlock = [ext.start];\n                                }\n                            }\n                            else if (ext.level === 'inline') {\n                                if (extensions.startInline) {\n                                    extensions.startInline.push(ext.start);\n                                }\n                                else {\n                                    extensions.startInline = [ext.start];\n                                }\n                            }\n                        }\n                    }\n                    if ('childTokens' in ext && ext.childTokens) { // Child tokens to be visited by walkTokens\n                        extensions.childTokens[ext.name] = ext.childTokens;\n                    }\n                });\n                opts.extensions = extensions;\n            }\n            // ==-- Parse \"overwrite\" extensions --== //\n            if (pack.renderer) {\n                const renderer = this.defaults.renderer || new _Renderer(this.defaults);\n                for (const prop in pack.renderer) {\n                    if (!(prop in renderer)) {\n                        throw new Error(`renderer '${prop}' does not exist`);\n                    }\n                    if (['options', 'parser'].includes(prop)) {\n                        // ignore options property\n                        continue;\n                    }\n                    const rendererProp = prop;\n                    const rendererFunc = pack.renderer[rendererProp];\n                    const prevRenderer = renderer[rendererProp];\n                    // Replace renderer with func to run extension, but fall back if false\n                    renderer[rendererProp] = (...args) => {\n                        let ret = rendererFunc.apply(renderer, args);\n                        if (ret === false) {\n                            ret = prevRenderer.apply(renderer, args);\n                        }\n                        return ret || '';\n                    };\n                }\n                opts.renderer = renderer;\n            }\n            if (pack.tokenizer) {\n                const tokenizer = this.defaults.tokenizer || new _Tokenizer(this.defaults);\n                for (const prop in pack.tokenizer) {\n                    if (!(prop in tokenizer)) {\n                        throw new Error(`tokenizer '${prop}' does not exist`);\n                    }\n                    if (['options', 'rules', 'lexer'].includes(prop)) {\n                        // ignore options, rules, and lexer properties\n                        continue;\n                    }\n                    const tokenizerProp = prop;\n                    const tokenizerFunc = pack.tokenizer[tokenizerProp];\n                    const prevTokenizer = tokenizer[tokenizerProp];\n                    // Replace tokenizer with func to run extension, but fall back if false\n                    // @ts-expect-error cannot type tokenizer function dynamically\n                    tokenizer[tokenizerProp] = (...args) => {\n                        let ret = tokenizerFunc.apply(tokenizer, args);\n                        if (ret === false) {\n                            ret = prevTokenizer.apply(tokenizer, args);\n                        }\n                        return ret;\n                    };\n                }\n                opts.tokenizer = tokenizer;\n            }\n            // ==-- Parse Hooks extensions --== //\n            if (pack.hooks) {\n                const hooks = this.defaults.hooks || new _Hooks();\n                for (const prop in pack.hooks) {\n                    if (!(prop in hooks)) {\n                        throw new Error(`hook '${prop}' does not exist`);\n                    }\n                    if (['options', 'block'].includes(prop)) {\n                        // ignore options and block properties\n                        continue;\n                    }\n                    const hooksProp = prop;\n                    const hooksFunc = pack.hooks[hooksProp];\n                    const prevHook = hooks[hooksProp];\n                    if (_Hooks.passThroughHooks.has(prop)) {\n                        // @ts-expect-error cannot type hook function dynamically\n                        hooks[hooksProp] = (arg) => {\n                            if (this.defaults.async) {\n                                return Promise.resolve(hooksFunc.call(hooks, arg)).then(ret => {\n                                    return prevHook.call(hooks, ret);\n                                });\n                            }\n                            const ret = hooksFunc.call(hooks, arg);\n                            return prevHook.call(hooks, ret);\n                        };\n                    }\n                    else {\n                        // @ts-expect-error cannot type hook function dynamically\n                        hooks[hooksProp] = (...args) => {\n                            let ret = hooksFunc.apply(hooks, args);\n                            if (ret === false) {\n                                ret = prevHook.apply(hooks, args);\n                            }\n                            return ret;\n                        };\n                    }\n                }\n                opts.hooks = hooks;\n            }\n            // ==-- Parse WalkTokens extensions --== //\n            if (pack.walkTokens) {\n                const walkTokens = this.defaults.walkTokens;\n                const packWalktokens = pack.walkTokens;\n                opts.walkTokens = function (token) {\n                    let values = [];\n                    values.push(packWalktokens.call(this, token));\n                    if (walkTokens) {\n                        values = values.concat(walkTokens.call(this, token));\n                    }\n                    return values;\n                };\n            }\n            this.defaults = { ...this.defaults, ...opts };\n        });\n        return this;\n    }\n    setOptions(opt) {\n        this.defaults = { ...this.defaults, ...opt };\n        return this;\n    }\n    lexer(src, options) {\n        return _Lexer.lex(src, options ?? this.defaults);\n    }\n    parser(tokens, options) {\n        return _Parser.parse(tokens, options ?? this.defaults);\n    }\n    parseMarkdown(blockType) {\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        const parse = (src, options) => {\n            const origOpt = { ...options };\n            const opt = { ...this.defaults, ...origOpt };\n            const throwError = this.onError(!!opt.silent, !!opt.async);\n            // throw error if an extension set async to true but parse was called with async: false\n            if (this.defaults.async === true && origOpt.async === false) {\n                return throwError(new Error('marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise.'));\n            }\n            // throw error in case of non string input\n            if (typeof src === 'undefined' || src === null) {\n                return throwError(new Error('marked(): input parameter is undefined or null'));\n            }\n            if (typeof src !== 'string') {\n                return throwError(new Error('marked(): input parameter is of type '\n                    + Object.prototype.toString.call(src) + ', string expected'));\n            }\n            if (opt.hooks) {\n                opt.hooks.options = opt;\n                opt.hooks.block = blockType;\n            }\n            const lexer = opt.hooks ? opt.hooks.provideLexer() : (blockType ? _Lexer.lex : _Lexer.lexInline);\n            const parser = opt.hooks ? opt.hooks.provideParser() : (blockType ? _Parser.parse : _Parser.parseInline);\n            if (opt.async) {\n                return Promise.resolve(opt.hooks ? opt.hooks.preprocess(src) : src)\n                    .then(src => lexer(src, opt))\n                    .then(tokens => opt.hooks ? opt.hooks.processAllTokens(tokens) : tokens)\n                    .then(tokens => opt.walkTokens ? Promise.all(this.walkTokens(tokens, opt.walkTokens)).then(() => tokens) : tokens)\n                    .then(tokens => parser(tokens, opt))\n                    .then(html => opt.hooks ? opt.hooks.postprocess(html) : html)\n                    .catch(throwError);\n            }\n            try {\n                if (opt.hooks) {\n                    src = opt.hooks.preprocess(src);\n                }\n                let tokens = lexer(src, opt);\n                if (opt.hooks) {\n                    tokens = opt.hooks.processAllTokens(tokens);\n                }\n                if (opt.walkTokens) {\n                    this.walkTokens(tokens, opt.walkTokens);\n                }\n                let html = parser(tokens, opt);\n                if (opt.hooks) {\n                    html = opt.hooks.postprocess(html);\n                }\n                return html;\n            }\n            catch (e) {\n                return throwError(e);\n            }\n        };\n        return parse;\n    }\n    onError(silent, async) {\n        return (e) => {\n            e.message += '\\nPlease report this to https://github.com/markedjs/marked.';\n            if (silent) {\n                const msg = '<p>An error occurred:</p><pre>'\n                    + escape$1(e.message + '', true)\n                    + '</pre>';\n                if (async) {\n                    return Promise.resolve(msg);\n                }\n                return msg;\n            }\n            if (async) {\n                return Promise.reject(e);\n            }\n            throw e;\n        };\n    }\n}\n\nconst markedInstance = new Marked();\nfunction marked(src, opt) {\n    return markedInstance.parse(src, opt);\n}\n/**\n * Sets the default options.\n *\n * @param options Hash of options\n */\nmarked.options =\n    marked.setOptions = function (options) {\n        markedInstance.setOptions(options);\n        marked.defaults = markedInstance.defaults;\n        changeDefaults(marked.defaults);\n        return marked;\n    };\n/**\n * Gets the original marked default options.\n */\nmarked.getDefaults = _getDefaults;\nmarked.defaults = _defaults;\n/**\n * Use Extension\n */\nmarked.use = function (...args) {\n    markedInstance.use(...args);\n    marked.defaults = markedInstance.defaults;\n    changeDefaults(marked.defaults);\n    return marked;\n};\n/**\n * Run callback for every token\n */\nmarked.walkTokens = function (tokens, callback) {\n    return markedInstance.walkTokens(tokens, callback);\n};\n/**\n * Compiles markdown to HTML without enclosing `p` tag.\n *\n * @param src String of markdown source to be compiled\n * @param options Hash of options\n * @return String of compiled HTML\n */\nmarked.parseInline = markedInstance.parseInline;\n/**\n * Expose\n */\nmarked.Parser = _Parser;\nmarked.parser = _Parser.parse;\nmarked.Renderer = _Renderer;\nmarked.TextRenderer = _TextRenderer;\nmarked.Lexer = _Lexer;\nmarked.lexer = _Lexer.lex;\nmarked.Tokenizer = _Tokenizer;\nmarked.Hooks = _Hooks;\nmarked.parse = marked;\nconst options = marked.options;\nconst setOptions = marked.setOptions;\nconst use = marked.use;\nconst walkTokens = marked.walkTokens;\nconst parseInline = marked.parseInline;\nconst parse = marked;\nconst parser = _Parser.parse;\nconst lexer = _Lexer.lex;\n\nexport { _Hooks as Hooks, _Lexer as Lexer, Marked, _Parser as Parser, _Renderer as Renderer, _TextRenderer as TextRenderer, _Tokenizer as Tokenizer, _defaults as defaults, _getDefaults as getDefaults, lexer, marked, options, parse, parseInline, parser, setOptions, use, walkTokens };\n//# sourceMappingURL=marked.esm.js.map\n","'use strict';\n\nvar escapes = {\n  '&': '&amp;',\n  '<': '&lt;',\n  '>': '&gt;',\n  '\"': '&quot;',\n  \"'\": '&#39;'\n};\nvar unescapes = {\n  '&amp;': '&',\n  '&lt;': '<',\n  '&gt;': '>',\n  '&quot;': '\"',\n  '&#39;': \"'\"\n};\nvar rescaped = /(&amp;|&lt;|&gt;|&quot;|&#39;)/g;\nvar runescaped = /[&<>\"']/g;\n\nfunction escapeHtmlChar (match) {\n  return escapes[match];\n}\nfunction unescapeHtmlChar (match) {\n  return unescapes[match];\n}\n\nfunction escapeHtml (text) {\n  return text == null ? '' : String(text).replace(runescaped, escapeHtmlChar);\n}\n\nfunction unescapeHtml (html) {\n  return html == null ? '' : String(html).replace(rescaped, unescapeHtmlChar);\n}\n\nescapeHtml.options = unescapeHtml.options = {};\n\nmodule.exports = {\n  encode: escapeHtml,\n  escape: escapeHtml,\n  decode: unescapeHtml,\n  unescape: unescapeHtml,\n  version: '1.0.0-browser'\n};\n","'use strict';\n\nfunction assignment (result) {\n  var stack = Array.prototype.slice.call(arguments, 1);\n  var item;\n  var key;\n  while (stack.length) {\n    item = stack.shift();\n    for (key in item) {\n      if (item.hasOwnProperty(key)) {\n        if (Object.prototype.toString.call(result[key]) === '[object Object]') {\n          result[key] = assignment(result[key], item[key]);\n        } else {\n          result[key] = item[key];\n        }\n      }\n    }\n  }\n  return result;\n}\n\nmodule.exports = assignment;\n","'use strict';\n\nmodule.exports = function lowercase (string) {\n  return typeof string === 'string' ? string.toLowerCase() : string;\n};\n","'use strict';\n\nfunction toMap (list) {\n  return list.reduce(asKey, {});\n}\n\nfunction asKey (accumulator, item) {\n  accumulator[item] = true;\n  return accumulator;\n}\n\nmodule.exports = toMap;\n","'use strict';\n\nvar toMap = require('./toMap');\nvar uris = ['background', 'base', 'cite', 'href', 'longdesc', 'src', 'usemap'];\n\nmodule.exports = {\n  uris: toMap(uris) // attributes that have an href and hence need to be sanitized\n};\n","'use strict';\n\nvar toMap = require('./toMap');\nvar voids = ['area', 'br', 'col', 'hr', 'img', 'wbr', 'input', 'base', 'basefont', 'link', 'meta'];\n\nmodule.exports = {\n  voids: toMap(voids)\n};\n","'use strict';\n\nvar he = require('he');\nvar lowercase = require('./lowercase');\nvar attributes = require('./attributes');\nvar elements = require('./elements');\nvar rstart = /^<\\s*([\\w:-]+)((?:\\s+[\\w:-]+(?:\\s*=\\s*(?:(?:\"[^\"]*\")|(?:'[^']*')|[^>\\s]+))?)*)\\s*(\\/?)\\s*>/;\nvar rend = /^<\\s*\\/\\s*([\\w:-]+)[^>]*>/;\nvar rattrs = /([\\w:-]+)(?:\\s*=\\s*(?:(?:\"((?:[^\"])*)\")|(?:'((?:[^'])*)')|([^>\\s]+)))?/g;\nvar rtag = /^</;\nvar rtagend = /^<\\s*\\//;\n\nfunction createStack () {\n  var stack = [];\n  stack.lastItem = function lastItem () {\n    return stack[stack.length - 1];\n  };\n  return stack;\n}\n\nfunction parser (html, handler) {\n  var stack = createStack();\n  var last = html;\n  var chars;\n\n  while (html) {\n    parsePart();\n  }\n  parseEndTag(); // clean up any remaining tags\n\n  function parsePart () {\n    chars = true;\n    parseTag();\n\n    var same = html === last;\n    last = html;\n\n    if (same) { // discard, because it's invalid\n      html = '';\n    }\n  }\n\n  function parseTag () {\n    if (html.substr(0, 4) === '<!--') { // comments\n      parseComment();\n    } else if (rtagend.test(html)) {\n      parseEdge(rend, parseEndTag);\n    } else if (rtag.test(html)) {\n      parseEdge(rstart, parseStartTag);\n    }\n    parseTagDecode();\n  }\n\n  function parseEdge (regex, parser) {\n    var match = html.match(regex);\n    if (match) {\n      html = html.substring(match[0].length);\n      match[0].replace(regex, parser);\n      chars = false;\n    }\n  }\n\n  function parseComment () {\n    var index = html.indexOf('-->');\n    if (index >= 0) {\n      if (handler.comment) {\n        handler.comment(html.substring(4, index));\n      }\n      html = html.substring(index + 3);\n      chars = false;\n    }\n  }\n\n  function parseTagDecode () {\n    if (!chars) {\n      return;\n    }\n    var text;\n    var index = html.indexOf('<');\n    if (index >= 0) {\n      text = html.substring(0, index);\n      html = html.substring(index);\n    } else {\n      text = html;\n      html = '';\n    }\n    if (handler.chars) {\n      handler.chars(text);\n    }\n  }\n\n  function parseStartTag (tag, tagName, rest, unary) {\n    var attrs = {};\n    var low = lowercase(tagName);\n    var u = elements.voids[low] || !!unary;\n\n    rest.replace(rattrs, attrReplacer);\n\n    if (!u) {\n      stack.push(low);\n    }\n    if (handler.start) {\n      handler.start(low, attrs, u);\n    }\n\n    function attrReplacer (match, name, doubleQuotedValue, singleQuotedValue, unquotedValue) {\n      if (doubleQuotedValue === void 0 && singleQuotedValue === void 0 && unquotedValue === void 0) {\n        attrs[name] = void 0; // attribute is like <button disabled></button>\n      } else {\n        attrs[name] = he.decode(doubleQuotedValue || singleQuotedValue || unquotedValue || '');\n      }\n    }\n  }\n\n  function parseEndTag (tag, tagName) {\n    var i;\n    var pos = 0;\n    var low = lowercase(tagName);\n    if (low) {\n      for (pos = stack.length - 1; pos >= 0; pos--) {\n        if (stack[pos] === low) {\n          break; // find the closest opened tag of the same type\n        }\n      }\n    }\n    if (pos >= 0) {\n      for (i = stack.length - 1; i >= pos; i--) {\n        if (handler.end) { // close all the open elements, up the stack\n          handler.end(stack[i]);\n        }\n      }\n      stack.length = pos;\n    }\n  }\n}\n\nmodule.exports = parser;\n","'use strict';\n\nvar he = require('he');\nvar lowercase = require('./lowercase');\nvar attributes = require('./attributes');\nvar elements = require('./elements');\n\nfunction sanitizer (buffer, options) {\n  var last;\n  var context;\n  var o = options || {};\n\n  reset();\n\n  return {\n    start: start,\n    end: end,\n    chars: chars\n  };\n\n  function out (value) {\n    buffer.push(value);\n  }\n\n  function start (tag, attrs, unary) {\n    var low = lowercase(tag);\n\n    if (context.ignoring) {\n      ignore(low); return;\n    }\n    if ((o.allowedTags || []).indexOf(low) === -1) {\n      ignore(low); return;\n    }\n    if (o.filter && !o.filter({ tag: low, attrs: attrs })) {\n      ignore(low); return;\n    }\n\n    out('<');\n    out(low);\n    Object.keys(attrs).forEach(parse);\n    out(unary ? '/>' : '>');\n\n    function parse (key) {\n      var value = attrs[key];\n      var classesOk = (o.allowedClasses || {})[low] || [];\n      var attrsOk = (o.allowedAttributes || {})[low] || [];\n      var valid;\n      var lkey = lowercase(key);\n      if (lkey === 'class' && attrsOk.indexOf(lkey) === -1) {\n        value = value.split(' ').filter(isValidClass).join(' ').trim();\n        valid = value.length;\n      } else {\n        valid = attrsOk.indexOf(lkey) !== -1 && (attributes.uris[lkey] !== true || testUrl(value));\n      }\n      if (valid) {\n        out(' ');\n        out(key);\n        if (typeof value === 'string') {\n          out('=\"');\n          out(he.encode(value));\n          out('\"');\n        }\n      }\n      function isValidClass (className) {\n        return classesOk && classesOk.indexOf(className) !== -1;\n      }\n    }\n  }\n\n  function end (tag) {\n    var low = lowercase(tag);\n    var allowed = (o.allowedTags || []).indexOf(low) !== -1;\n    if (allowed) {\n      if (context.ignoring === false) {\n        out('</');\n        out(low);\n        out('>');\n      } else {\n        unignore(low);\n      }\n    } else {\n      unignore(low);\n    }\n  }\n\n  function testUrl (text) {\n    var start = text[0];\n    if (start === '#' || start === '/') {\n      return true;\n    }\n    var colon = text.indexOf(':');\n    if (colon === -1) {\n      return true;\n    }\n    var questionmark = text.indexOf('?');\n    if (questionmark !== -1 && colon > questionmark) {\n      return true;\n    }\n    var hash = text.indexOf('#');\n    if (hash !== -1 && colon > hash) {\n      return true;\n    }\n    return o.allowedSchemes.some(matches);\n\n    function matches (scheme) {\n      return text.indexOf(scheme + ':') === 0;\n    }\n  }\n\n  function chars (text) {\n    if (context.ignoring === false) {\n      out(o.transformText ? o.transformText(text) : text);\n    }\n  }\n\n  function ignore (tag) {\n    if (elements.voids[tag]) {\n      return;\n    }\n    if (context.ignoring === false) {\n      context = { ignoring: tag, depth: 1 };\n    } else if (context.ignoring === tag) {\n      context.depth++;\n    }\n  }\n\n  function unignore (tag) {\n    if (context.ignoring === tag) {\n      if (--context.depth <= 0) {\n        reset();\n      }\n    }\n  }\n\n  function reset () {\n    context = { ignoring: false, depth: 0 };\n  }\n}\n\nmodule.exports = sanitizer;\n","'use strict';\n\nvar he = require('he');\nvar assign = require('assignment');\nvar parser = require('./parser');\nvar sanitizer = require('./sanitizer');\nvar defaults = require('./defaults');\n\nfunction insane (html, options, strict) {\n  var buffer = [];\n  var configuration = strict === true ? options : assign({}, defaults, options);\n  var handler = sanitizer(buffer, configuration);\n\n  parser(html, handler);\n\n  return buffer.join('');\n}\n\ninsane.defaults = defaults;\nmodule.exports = insane;\n","'use strict';\n\nvar defaults = {\n  allowedAttributes: {\n    a: ['href', 'name', 'target', 'title', 'aria-label'],\n    iframe: ['allowfullscreen', 'frameborder', 'src'],\n    img: ['src', 'alt', 'title', 'aria-label']\n  },\n  allowedClasses: {},\n  allowedSchemes: ['http', 'https', 'mailto'],\n  allowedTags: [\n    'a', 'abbr', 'article', 'b', 'blockquote', 'br', 'caption', 'code', 'del', 'details', 'div', 'em',\n    'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'ins', 'kbd', 'li', 'main', 'mark',\n    'ol', 'p', 'pre', 'section', 'span', 'strike', 'strong', 'sub', 'summary', 'sup', 'table',\n    'tbody', 'td', 'th', 'thead', 'tr', 'u', 'ul'\n  ],\n  filter: null\n};\n\nmodule.exports = defaults;\n","import insane from 'insane'\n\nconst insaneOptions = {\n  allowedClasses: {},\n  // @refer CVE-2018-8495\n  // @link https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-8495\n  // @link https://leucosite.com/Microsoft-Edge-RCE/\n  // @link https://medium.com/@knownsec404team/analysis-of-the-security-issues-of-url-scheme-in-pc-from-cve-2018-8495-934478a36756\n  allowedSchemes: [\n    'http',\n    'https',\n    'mailto',\n    'data', // for support base64 encoded image (安全性有待考虑)\n  ],\n  allowedTags: [\n    'a',\n    'abbr',\n    'article',\n    'b',\n    'blockquote',\n    'br',\n    'caption',\n    'code',\n    'del',\n    'details',\n    'div',\n    'em',\n    'h1',\n    'h2',\n    'h3',\n    'h4',\n    'h5',\n    'h6',\n    'hr',\n    'i',\n    'img',\n    'ins',\n    'kbd',\n    'li',\n    'main',\n    'mark',\n    'ol',\n    'p',\n    'pre',\n    'section',\n    'span',\n    'strike',\n    'strong',\n    'sub',\n    'summary',\n    'sup',\n    'table',\n    'tbody',\n    'td',\n    'th',\n    'thead',\n    'tr',\n    'u',\n    'ul',\n  ],\n  allowedAttributes: {\n    '*': ['title', 'accesskey'],\n    a: ['href', 'name', 'target', 'aria-label', 'rel'],\n    img: ['src', 'alt', 'title', 'atk-emoticon', 'aria-label', 'data-src', 'class', 'loading'],\n    // for code highlight\n    code: ['class'],\n    span: ['class', 'style'],\n  },\n  filter: (node) => {\n    // class whitelist\n    const allowed = [\n      ['code', /^hljs\\W+language-(.*)$/],\n      ['span', /^(hljs-.*)$/],\n      ['img', /^lazyload$/],\n    ]\n    allowed.forEach(([tag, reg]) => {\n      if (node.tag === tag && !!node.attrs.class && !(reg as RegExp).test(node.attrs.class)) {\n        delete node.attrs.class\n      }\n    })\n\n    // allow <span> set color sty\n    if (\n      node.tag === 'span' &&\n      !!node.attrs.style &&\n      !/^color:(\\W+)?#[0-9a-f]{3,6};?$/i.test(node.attrs.style)\n    ) {\n      delete node.attrs.style\n    }\n\n    return true\n  },\n}\n\nexport function sanitize(content: string): string {\n  // @link https://github.com/markedjs/marked/discussions/1232\n  // @link https://gist.github.com/lionel-rowe/bb384465ba4e4c81a9c8dada84167225\n  return insane(content, insaneOptions)\n}\n","(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n  typeof define === 'function' && define.amd ? define(factory) :\n  (global.hanabi = factory());\n}(this, (function () { 'use strict';\n\nfunction createCommonjsModule(fn, module) {\n\treturn module = { exports: {} }, fn(module, module.exports), module.exports;\n}\n\nvar index$1 = createCommonjsModule(function (module) {\n'use strict';\n\nvar comment = module.exports = function () {\n\treturn new RegExp('(?:' + comment.line().source + ')|(?:' + comment.block().source + ')', 'gm');\n};\n\ncomment.line = function () {\n\treturn /(?:^|\\s)\\/\\/(.+?)$/gm;\n};\n\ncomment.block = function () {\n\treturn /\\/\\*([\\S\\s]*?)\\*\\//gm;\n};\n});\n\nvar defaultColors = ['23AC69', '91C132', 'F19726', 'E8552D', '1AAB8E', 'E1147F', '2980C1', '1BA1E6', '9FA0A0', 'F19726', 'E30B20', 'E30B20', 'A3338B'];\n\nvar index = function (input, ref) {\n  if ( ref === void 0 ) ref = {};\n  var colors = ref.colors; if ( colors === void 0 ) colors = defaultColors;\n\n  var index = 0;\n  var cache = {};\n  var wordRe = /[\\u4E00-\\u9FFF\\u3400-\\u4dbf\\uf900-\\ufaff\\u3040-\\u309f\\uac00-\\ud7af\\u0400-\\u04FF]+|\\w+/;\n  var leftAngleRe = /</;\n\n  var re = new RegExp((\"(\" + (wordRe.source) + \"|\" + (leftAngleRe.source) + \")|(\" + (index$1().source) + \")\"), 'gmi');\n  return input\n  .replace(re, function (m, word, cm) {\n    if (cm) {\n      return toComment(cm)\n    }\n\n    if (word === '<') {\n      return '&lt;'\n    }\n    var color;\n    if (cache[word]) {\n      color = cache[word];\n    } else {\n      color = colors[index];\n      cache[word] = color;\n    }\n\n    var out = \"<span style=\\\"color: #\" + color + \"\\\">\" + word + \"</span>\";\n    index = ++index % colors.length;\n    return out\n  })\n};\n\nfunction toComment(cm) {\n  return (\"<span style=\\\"color: slategray\\\">\" + cm + \"</span>\")\n}\n\nreturn index;\n\n})));\n","import hanabi from 'hanabi'\n\nexport function renderCode(code: string) {\n  return hanabi(code)\n}\n","import { marked, Tokens } from 'marked'\nimport { renderCode } from './highlight'\nimport type { Config } from '@/types'\n\nexport interface RendererOptions {\n  imgLazyLoad: Config['imgLazyLoad']\n}\n\nexport function getRenderer(options: RendererOptions) {\n  const renderer = new marked.Renderer()\n  renderer.link = markedLinkRenderer(renderer, renderer.link)\n  renderer.code = markedCodeRenderer()\n  renderer.image = markedImageRenderer(renderer, renderer.image, options)\n  return renderer\n}\n\nconst markedLinkRenderer =\n  (renderer: any, orgLinkRenderer: (args: Tokens.Link) => string) => (args: Tokens.Link) => {\n    const getLinkOrigin = (link: string) => {\n      try {\n        return new URL(link).origin\n      } catch {\n        return ''\n      }\n    }\n    const isSameOriginLink = getLinkOrigin(args.href) === window.location.origin\n    const html = orgLinkRenderer.call(renderer, args)\n    return html.replace(\n      /^<a /,\n      `<a target=\"_blank\" ${!isSameOriginLink ? `rel=\"noreferrer noopener nofollow\"` : ''} `,\n    )\n  }\n\nconst markedCodeRenderer =\n  () =>\n  ({ lang, text }: Tokens.Code): string => {\n    // Colorize the block only if the language is known to highlight.js\n    const realLang = !lang ? 'plaintext' : lang\n    let colorized = text\n    if ((window as any).hljs) {\n      if (realLang && (window as any).hljs.getLanguage(realLang)) {\n        colorized = (window as any).hljs.highlight(realLang, text).value\n      }\n    } else {\n      colorized = renderCode(text)\n    }\n\n    return (\n      `<pre rel=\"${realLang}\">\\n` +\n      `<code class=\"hljs language-${realLang}\">${colorized.replace(/&amp;/g, '&')}</code>\\n` +\n      `</pre>`\n    )\n  }\n\nconst markedImageRenderer =\n  (\n    renderer: any,\n    orgImageRenderer: (args: Tokens.Image) => string,\n    { imgLazyLoad }: RendererOptions,\n  ) =>\n  (args: Tokens.Image): string => {\n    const html = orgImageRenderer.call(renderer, args)\n    if (!imgLazyLoad) return html\n    if (imgLazyLoad === 'native' || (imgLazyLoad as any) === true)\n      return html.replace(/^<img /, '<img class=\"lazyload\" loading=\"lazy\" ')\n    if (imgLazyLoad === 'data-src')\n      return html.replace(/^<img /, '<img class=\"lazyload\" ').replace('src=', 'data-src=')\n    return html\n  }\n","import { Marked } from 'marked'\nimport type { MarkedOptions } from 'marked'\n\nimport { sanitize } from './sanitizer'\nimport { renderCode } from './highlight'\nimport { getRenderer } from './marked-renderer'\nimport type { Config } from '@/types'\n\ntype Replacer = (raw: string) => string\n\nlet instance: Marked | undefined\nlet replacers: Replacer[] = []\n\nconst markedOptions: MarkedOptions = {\n  gfm: true,\n  breaks: true,\n  async: false,\n}\n\n/** Get Marked instance */\nexport function getInstance() {\n  return instance\n}\n\nexport function setReplacers(arr: Replacer[]) {\n  replacers = arr\n}\n\nexport interface MarkedInitOptions {\n  markedOptions: Config['markedOptions']\n  imgLazyLoad: Config['imgLazyLoad']\n}\n\n/** 初始化 marked */\nexport function initMarked(options: MarkedInitOptions) {\n  try {\n    if (!Marked.name) return\n  } catch {\n    return\n  }\n\n  // @see https://github.com/markedjs/marked/blob/4afb228d956a415624c4e5554bb8f25d047676fe/src/Tokenizer.js#L329\n  const marked = new Marked()\n  marked.setOptions({\n    renderer: getRenderer({\n      imgLazyLoad: options.imgLazyLoad,\n    }),\n    ...markedOptions,\n    ...options.markedOptions,\n  })\n\n  instance = marked\n}\n\n/** 解析 markdown */\nexport default function marked(src: string): string {\n  let markedContent = getInstance()?.parse(src) as string\n  if (!markedContent) {\n    // 无 Markdown 模式简单处理\n    markedContent = simpleMarked(src)\n  }\n\n  let dest = sanitize(markedContent)\n\n  // 内容替换器\n  replacers.forEach((replacer) => {\n    if (typeof replacer === 'function') dest = replacer(dest)\n  })\n\n  return dest\n}\n\nfunction simpleMarked(src: string) {\n  return (\n    src\n      // .replace(/\\*\\*(.*?)\\*\\*/g, '<strong>$1</strong>')\n      .replace(\n        /```\\s*([^]+?.*?[^]+?[^]+?)```/g,\n        (_, code) => `<pre><code>${renderCode(code)}</code></pre>`,\n      )\n      // .replace(/`([^`]+?)`/g, '<code>$1</code>')\n      .replace(/!\\[(.*?)\\]\\((.*?)\\)/g, (_, alt, imgSrc) => `<img src=\"${imgSrc}\" alt=\"${alt}\" />`)\n      .replace(\n        /\\[(.*?)\\]\\((.*?)\\)/g,\n        (_, text, link) => `<a href=\"${link}\" target=\"_blank\">${text}</a>`,\n      )\n      .replace(/\\n/g, '<br>')\n  )\n}\n","import type {\n  Config,\n  ConfigPartial,\n  CommentData,\n  ListFetchParams,\n  Context as IContext,\n  SidebarShowPayload,\n  Services,\n} from './types'\nimport * as I18n from './i18n'\nimport * as marked from './lib/marked'\nimport { createInjectionContainer } from './lib/injection'\nimport type { CheckerCaptchaPayload, CheckerPayload } from './components/checker'\n\n/**\n * Artalk Context\n */\nclass Context implements IContext {\n  private _deps = createInjectionContainer<Services>()\n\n  constructor(private _$root: HTMLElement) {}\n\n  getEl(): HTMLElement {\n    return this._$root\n  }\n\n  destroy(): void {\n    this.trigger('unmounted')\n    while (this._$root.firstChild) {\n      this._$root.removeChild(this._$root.firstChild)\n    }\n  }\n\n  // -------------------------------------------------------------------\n  //  Dependency Injection\n  // -------------------------------------------------------------------\n  provide: IContext['provide'] = (key, impl, deps, opts) => {\n    this._deps.provide(key, impl, deps, opts)\n  }\n\n  inject: IContext['inject'] = (key) => {\n    return this._deps.inject(key)\n  }\n  get = this.inject\n\n  // -------------------------------------------------------------------\n  //  Event Manager\n  // -------------------------------------------------------------------\n  on: IContext['on'] = (name, handler) => {\n    this.inject('events').on(name, handler)\n  }\n\n  off: IContext['off'] = (name, handler) => {\n    this.inject('events').off(name, handler)\n  }\n\n  trigger: IContext['trigger'] = (name, payload) => {\n    this.inject('events').trigger(name, payload)\n  }\n\n  // -------------------------------------------------------------------\n  //  Configurations\n  // -------------------------------------------------------------------\n  getConf(): Config {\n    return this.inject('config').get()\n  }\n\n  updateConf(conf: ConfigPartial): void {\n    this.inject('config').update(conf)\n  }\n\n  watchConf<T extends (keyof Config)[]>(\n    keys: T,\n    effect: (conf: Pick<Config, T[number]>) => void,\n  ): void {\n    this.inject('config').watchConf(keys, effect)\n  }\n\n  getMarked() {\n    return marked.getInstance()\n  }\n\n  setDarkMode(darkMode: boolean | 'auto'): void {\n    this.updateConf({ darkMode })\n  }\n\n  get conf() {\n    return this.getConf()\n  }\n  set conf(val) {\n    console.error('Cannot set config directly, please call updateConf()')\n  }\n  get $root() {\n    return this.getEl()\n  }\n  set $root(val) {\n    console.error('set $root is prohibited')\n  }\n\n  // -------------------------------------------------------------------\n  //  I18n: Internationalization\n  // -------------------------------------------------------------------\n  $t(key: I18n.I18nKeys, args: { [key: string]: string } = {}): string {\n    return I18n.t(key, args)\n  }\n\n  // -------------------------------------------------------------------\n  //  HTTP API Client\n  // -------------------------------------------------------------------\n  getApi() {\n    return this.inject('api')\n  }\n\n  getApiHandlers() {\n    return this.inject('apiHandlers')\n  }\n\n  // -------------------------------------------------------------------\n  //  User Manager\n  // -------------------------------------------------------------------\n  getUser() {\n    return this.inject('user')\n  }\n\n  // -------------------------------------------------------------------\n  //  Data Manager\n  // -------------------------------------------------------------------\n  getData() {\n    return this.inject('data')\n  }\n\n  fetch(params: Partial<ListFetchParams>): void {\n    this.getData().fetchComments(params)\n  }\n\n  reload(): void {\n    this.getData().fetchComments({ offset: 0 })\n  }\n\n  // -------------------------------------------------------------------\n  //  List\n  // -------------------------------------------------------------------\n  listGotoFirst(): void {\n    this.trigger('list-goto-first')\n  }\n\n  getCommentList = this.getCommentNodes\n  getCommentNodes() {\n    return this.inject('list').getCommentNodes()\n  }\n\n  getCommentDataList = this.getComments\n  getComments() {\n    return this.getData().getComments()\n  }\n\n  // -------------------------------------------------------------------\n  //  Editor\n  // -------------------------------------------------------------------\n  replyComment(commentData: CommentData, $comment: HTMLElement): void {\n    this.inject('editor').setReplyComment(commentData, $comment)\n  }\n\n  editComment(commentData: CommentData, $comment: HTMLElement): void {\n    this.inject('editor').setEditComment(commentData, $comment)\n  }\n\n  editorShowLoading(): void {\n    this.inject('editor').showLoading()\n  }\n\n  editorHideLoading(): void {\n    this.inject('editor').hideLoading()\n  }\n\n  editorShowNotify(msg, type): void {\n    this.inject('editor').showNotify(msg, type)\n  }\n\n  editorResetState(): void {\n    this.inject('editor').resetState()\n  }\n\n  // -------------------------------------------------------------------\n  //  Sidebar\n  // -------------------------------------------------------------------\n  showSidebar(payload?: SidebarShowPayload): void {\n    this.inject('sidebar').show(payload)\n  }\n\n  hideSidebar(): void {\n    this.inject('sidebar').hide()\n  }\n\n  // -------------------------------------------------------------------\n  //  Checker\n  // -------------------------------------------------------------------\n  checkAdmin(payload: CheckerPayload): Promise<void> {\n    return this.inject('checkers').checkAdmin(payload)\n  }\n\n  checkCaptcha(payload: CheckerCaptchaPayload): Promise<void> {\n    return this.inject('checkers').checkCaptcha(payload)\n  }\n}\n\nexport default Context\n","type PrimitiveKey = string | number | symbol\ntype Services = { [key: PrimitiveKey]: any }\n\nexport type Constructor<T, S = Services, D extends readonly (keyof S)[] = any> = (\n  ...args: { [K in keyof D]: D[K] extends keyof S ? S[D[K]] : never }\n) => T\n\nexport type Lifecycle = 'transient' | 'singleton'\n\nexport interface Provider<T, S = Services> {\n  /** Implementation constructor */\n  impl: Constructor<T>\n\n  /** Dependency constructors */\n  deps: readonly (keyof S)[]\n\n  /** Lifecycle */\n  lifecycle: Lifecycle\n}\n\nexport interface ProvideFuncOptions {\n  /** Lifecycle (default: 'singleton') */\n  lifecycle?: Lifecycle\n}\n\nexport interface DependencyContainer<S = Services> {\n  provide<K extends keyof S, T extends S[K] = any, D extends readonly (keyof S)[] = any>(\n    key: K,\n    impl: Constructor<T, S, D>,\n    deps?: D,\n    opts?: ProvideFuncOptions,\n  ): void\n\n  inject<T = undefined, K extends keyof S = any>(key: K): T extends undefined ? S[K] : T\n}\n\nexport function createInjectionContainer<S = Services>(): DependencyContainer<S> {\n  const providers = new Map<PrimitiveKey, Provider<any, S>>()\n  const initializedDeps = new Map<PrimitiveKey, any>()\n\n  const provide: DependencyContainer<S>['provide'] = (key, impl, deps, opts = {}) => {\n    providers.set(key, { impl, deps: deps || [], lifecycle: opts.lifecycle || 'singleton' })\n  }\n\n  const inject: DependencyContainer<S>['inject'] = (key) => {\n    const provider = providers.get(key)\n    if (!provider) {\n      throw new Error(`No provide for ${String(key)}`)\n    }\n\n    if (provider.lifecycle === 'singleton' && initializedDeps.has(key)) {\n      return initializedDeps.get(key)\n    }\n\n    const { impl, deps } = provider\n    const params = deps.map((d) => inject(d))\n    const resolved = impl(...params)\n\n    initializedDeps.set(key, resolved)\n\n    return resolved\n  }\n\n  return { provide, inject }\n}\n","/**\n * Performs a deep merge of objects and returns new object.\n * Does not modify objects (immutable) and merges arrays via concatenation.\n *\n * @param objects - Objects to merge\n * @returns New object with merged key/values\n */\nexport function mergeDeep<T>(...objects: any[]): T {\n  const isObject = (obj: any) => obj && typeof obj === 'object' && obj.constructor === Object\n\n  return objects.reduce((prev, obj) => {\n    Object.keys(obj ?? {}).forEach((key) => {\n      // Avoid prototype pollution\n      if (key === '__proto__' || key === 'constructor' || key === 'prototype') {\n        return\n      }\n\n      const pVal = prev[key]\n      const oVal = obj[key]\n\n      if (Array.isArray(pVal) && Array.isArray(oVal)) {\n        prev[key] = pVal.concat(...oVal)\n      } else if (isObject(pVal) && isObject(oVal)) {\n        prev[key] = mergeDeep(pVal, oVal)\n      } else {\n        prev[key] = oVal\n      }\n    })\n\n    return prev\n  }, {})\n}\n","import type { Config } from '@/types'\n\nexport const Defaults: Readonly<RequiredExcept<Config, ExcludedKeys>> = {\n  el: '',\n  pageKey: '',\n  pageTitle: '',\n  server: '',\n  site: '',\n\n  placeholder: '',\n  noComment: '',\n  sendBtn: '',\n  darkMode: false,\n  editorTravel: true,\n\n  flatMode: 'auto',\n  nestMax: 2,\n  nestSort: 'DATE_ASC',\n\n  emoticons: ARTALK_LITE\n    ? false\n    : 'https://cdn.jsdelivr.net/gh/ArtalkJS/Emoticons/grps/default.json',\n\n  pageVote: true,\n\n  vote: ARTALK_LITE ? false : true,\n  voteDown: false,\n  uaBadge: ARTALK_LITE ? false : true,\n  listSort: true,\n  preview: ARTALK_LITE ? false : true,\n  countEl: '.artalk-comment-count',\n  pvEl: '.artalk-pv-count',\n  statPageKeyAttr: 'data-page-key',\n\n  gravatar: {\n    mirror: 'https://www.gravatar.com/avatar/',\n    params: 'sha256=1&d=mp&s=240',\n  },\n\n  pagination: {\n    pageSize: 20,\n    readMore: true,\n    autoLoad: true,\n  },\n\n  heightLimit: {\n    content: 300,\n    children: 400,\n    scrollable: false,\n  },\n\n  imgUpload: true,\n  imgLazyLoad: false,\n  reqTimeout: 15000,\n  versionCheck: true,\n  useBackendConf: true,\n  preferRemoteConf: false,\n  listUnreadHighlight: false,\n  pvAdd: true,\n  fetchCommentsOnInit: true,\n\n  locale: 'en',\n  apiVersion: '',\n  pluginURLs: [],\n  markedReplacers: [],\n  markedOptions: {},\n}\n\ntype RequiredExcept<T, K extends keyof T> = Required<Omit<T, K>> & Pick<T, K>\ntype FunctionKeys<T> = Exclude<\n  { [K in keyof T]: NonNullable<T[K]> extends (...args: any[]) => any ? K : never }[keyof T],\n  undefined\n>\ntype ExcludedKeys = FunctionKeys<Config>\n","import type { ApiOptions } from './api/options'\nimport { mergeDeep } from './lib/merge-deep'\nimport type { ApiHandlers } from './api'\nimport { Defaults } from './defaults'\nimport type { Config, ConfigPartial, UserManager } from '@/types'\n\n/**\n * Handle the custom config which is provided by the user\n *\n * @param customConf - The custom config object which is provided by the user\n * @param full - If `full` is `true`, the return value will be the complete config for Artalk instance creation\n * @returns The config for Artalk instance creation\n */\nexport function handelCustomConf(customConf: ConfigPartial, full: true): Config\nexport function handelCustomConf(customConf: ConfigPartial, full?: false): ConfigPartial\nexport function handelCustomConf(customConf: ConfigPartial, full = false) {\n  // Merge default config\n  const conf: ConfigPartial = full ? mergeDeep(Defaults, customConf) : customConf\n\n  // Default pageKey\n  if (conf.pageKey === '') conf.pageKey = `${window.location.pathname}` // @see http://bl.ocks.org/abernier/3070589\n\n  // Default pageTitle\n  if (conf.pageTitle === '') conf.pageTitle = `${document.title}`\n\n  // Server\n  if (conf.server) conf.server = conf.server.replace(/\\/$/, '').replace(/\\/api\\/?$/, '')\n\n  // Language auto-detection\n  if (conf.locale === 'auto') conf.locale = navigator.language\n\n  // Flat mode auto-detection\n  if (conf.flatMode === 'auto') conf.flatMode = window.matchMedia('(max-width: 768px)').matches\n\n  // Change flatMode by nestMax\n  if (typeof conf.nestMax === 'number' && Number(conf.nestMax) <= 1) conf.flatMode = true\n\n  return conf\n}\n\n/**\n * Handle the config which is provided by the server\n *\n * @param conf - The Server response config for control the frontend of Artalk remotely\n * @returns The config for Artalk instance creation\n */\nexport function handleConfFormServer(conf: ConfigPartial): ConfigPartial {\n  const ExcludedKeys: (keyof Config)[] = [\n    'el',\n    'pageKey',\n    'pageTitle',\n    'server',\n    'site',\n    'pvEl',\n    'countEl',\n    'statPageKeyAttr',\n    'pageVote',\n  ]\n  Object.keys(conf).forEach((k) => {\n    if (ExcludedKeys.includes(k as any)) delete conf[k]\n    if (k === 'darkMode' && conf[k] !== 'auto') delete conf[k]\n  })\n\n  // Patch: `emoticons` config string to json\n  if (conf.emoticons && typeof conf.emoticons === 'string') {\n    conf.emoticons = conf.emoticons.trim()\n    if (conf.emoticons.startsWith('[') || conf.emoticons.startsWith('{')) {\n      conf.emoticons = JSON.parse(conf.emoticons) // parse json\n    } else if (conf.emoticons === 'false') {\n      conf.emoticons = false\n    }\n  }\n\n  return conf\n}\n\n/**\n * Get the root element of Artalk\n *\n * @param conf - Artalk config\n * @returns The root element of Artalk\n */\nexport function getRootEl(conf: ConfigPartial): HTMLElement {\n  let $root: HTMLElement\n  if (typeof conf.el === 'string') {\n    const el = document.querySelector<HTMLElement>(conf.el)\n    if (!el) throw new Error(`Element \"${conf.el}\" not found.`)\n    $root = el\n  } else if (conf.el instanceof HTMLElement) {\n    $root = conf.el\n  } else {\n    throw new Error('Please provide a valid `el` config for Artalk.')\n  }\n  return $root\n}\n\n/**\n * Convert Artalk Config to ApiOptions for Api client\n *\n * @param conf - Artalk config\n * @param ctx - If `ctx` not provided, `checkAdmin` and `checkCaptcha` will be disabled\n * @returns ApiOptions for Api client instance creation\n */\nexport function convertApiOptions(\n  conf: ConfigPartial,\n  user?: UserManager,\n  handlers?: ApiHandlers,\n): ApiOptions {\n  return {\n    baseURL: `${conf.server}/api/v2`,\n    siteName: conf.site || '',\n    pageKey: conf.pageKey || '',\n    pageTitle: conf.pageTitle || '',\n    timeout: conf.reqTimeout,\n    getApiToken: () => user?.getData().token,\n    userInfo: user?.checkHasBasicUserInfo()\n      ? {\n          name: user?.getData().name,\n          email: user?.getData().email,\n        }\n      : undefined,\n    handlers,\n  }\n}\n","import type { Context, ArtalkPlugin } from '@/types'\nimport { Api } from '@/api'\n\ntype CountCache = { [pageKey: string]: number }\n\nexport interface CountOptions {\n  getApi(): Api\n\n  siteName: string\n  pageKey?: string\n  pageTitle?: string\n  countEl: string\n  pvEl: string\n  pageKeyAttr: string\n\n  /** Whether to add PV count when initializing */\n  pvAdd?: boolean\n}\n\nexport const PvCountWidget: ArtalkPlugin = (ctx: Context) => {\n  ctx.watchConf(\n    ['site', 'pageKey', 'pageTitle', 'countEl', 'pvEl', 'statPageKeyAttr', 'pvAdd'],\n    (conf) => {\n      initCountWidget({\n        getApi: () => ctx.getApi(),\n        siteName: conf.site,\n        pageKey: conf.pageKey,\n        pageTitle: conf.pageTitle,\n        countEl: conf.countEl,\n        pvEl: conf.pvEl,\n        pageKeyAttr: conf.statPageKeyAttr,\n        pvAdd: conf.pvAdd,\n      })\n    },\n  )\n}\n\n/** Initialize count widgets */\nexport async function initCountWidget(opt: CountOptions) {\n  // Load comment count\n  await loadCommentCount(opt)\n\n  // Increment PV count\n  const cacheData = await incrementPvCount(opt)\n\n  // Load PV count\n  await loadPvCount(opt, cacheData)\n}\n\n/** Increment PV count and get cache data that contains PV count */\nasync function incrementPvCount(opt: CountOptions) {\n  if (!opt.pvAdd || !opt.pageKey) return undefined\n\n  const pvCount = (\n    await opt.getApi().pages.logPv({\n      page_key: opt.pageKey,\n      page_title: opt.pageTitle,\n      site_name: opt.siteName,\n    })\n  ).data.pv // pv+1 and get pv count\n\n  return {\n    [opt.pageKey]: pvCount,\n  }\n}\n\n/** Load comment count */\nasync function loadCommentCount(opt: CountOptions) {\n  await loadStatCount({ opt, query: 'page_comment', containers: [opt.countEl, '#ArtalkCount'] })\n}\n\n/** Load PV count */\nasync function loadPvCount(opt: CountOptions, cache?: CountCache) {\n  await loadStatCount({ opt, query: 'page_pv', containers: [opt.pvEl, '#ArtalkPV'], cache })\n}\n\nasync function loadStatCount(args: {\n  opt: CountOptions\n  query: 'page_pv' | 'page_comment'\n  containers: string[]\n  cache?: CountCache\n}) {\n  const { opt } = args\n  let cache: CountCache = args.cache || {}\n\n  // Retrieve elements\n  const els = retrieveElements(args.containers)\n\n  // Get page keys which will be queried\n  const pageKeys = getPageKeys(els, opt.pageKeyAttr, opt.pageKey, cache)\n\n  // Fetch count data from server\n  if (pageKeys.length > 0) {\n    const res = (\n      await opt.getApi().stats.getStats(args.query, {\n        page_keys: pageKeys.join(','),\n        site_name: opt.siteName,\n      })\n    ).data.data as CountCache\n    cache = { ...cache, ...res }\n  }\n\n  updateElementsText(els, cache, opt.pageKey)\n}\n\n/** Retrieve elements based on selectors */\nfunction retrieveElements(containers: string[]): Set<HTMLElement> {\n  const els = new Set<HTMLElement>()\n  new Set(containers).forEach((selector) => {\n    document.querySelectorAll<HTMLElement>(selector).forEach((el) => els.add(el))\n  })\n  return els\n}\n\n/** Get page keys to be queried */\nfunction getPageKeys(\n  els: Set<HTMLElement>,\n  pageKeyAttr: string,\n  pageKey: string | undefined,\n  cache: CountCache,\n): string[] {\n  const pageKeys = Array.from(els)\n    .map((el) => el.getAttribute(pageKeyAttr) || pageKey)\n    .filter((key) => key && typeof cache[key] !== 'number') // filter out keys that already have data\n\n  return [...new Set(pageKeys as string[])] // deduplicate\n}\n\n/** Update elements text content with the count data */\nfunction updateElementsText(els: Set<HTMLElement>, data: CountCache, defaultPageKey?: string) {\n  els.forEach((el) => {\n    const pageKey = el.getAttribute('data-page-key')\n    const count = (pageKey && data[pageKey]) || (defaultPageKey && data[defaultPageKey]) || 0 // if pageKey is not set, use defaultCount\n    el.innerText = `${Number(count)}`\n  })\n}\n\nexport const exportedForTesting = {\n  incrementPvCount,\n  loadCommentCount,\n  loadPvCount,\n  retrieveElements,\n  getPageKeys,\n  updateElementsText,\n}\n","/* eslint-disable */\n/* tslint:disable */\n/*\n * ---------------------------------------------------------------\n * ## THIS FILE WAS GENERATED VIA SWAGGER-TYPESCRIPT-API        ##\n * ##                                                           ##\n * ## AUTHOR: acacode                                           ##\n * ## SOURCE: https://github.com/acacode/swagger-typescript-api ##\n * ---------------------------------------------------------------\n */\n\nexport interface AuthAuthProviderInfo {\n  icon: string\n  label: string\n  name: string\n  path?: string\n}\n\nexport interface CommonApiVersionData {\n  app: string\n  commit_hash: string\n  version: string\n}\n\nexport interface CommonConfData {\n  frontend_conf: CommonMap\n  version: CommonApiVersionData\n}\n\nexport interface CommonJSONResult {\n  /** Data */\n  data: any\n  /** Message */\n  msg: string\n}\n\nexport type CommonMap = Record<string, any>\n\nexport interface EntityCookedComment {\n  badge_color: string\n  badge_name: string\n  content: string\n  content_marked: string\n  date: string\n  email_encrypted: string\n  id: number\n  ip_region: string\n  is_allow_reply: boolean\n  is_collapsed: boolean\n  is_pending: boolean\n  is_pinned: boolean\n  is_verified: boolean\n  link: string\n  nick: string\n  page_key: string\n  page_url: string\n  rid: number\n  site_name: string\n  ua: string\n  user_id: number\n  visible: boolean\n  vote_down: number\n  vote_up: number\n}\n\nexport interface EntityCookedNotify {\n  comment_id: number\n  id: number\n  is_emailed: boolean\n  is_read: boolean\n  read_link: string\n  user_id: number\n}\n\nexport interface EntityCookedPage {\n  admin_only: boolean\n  date: string\n  id: number\n  key: string\n  pv: number\n  site_name: string\n  title: string\n  url: string\n  vote_down: number\n  vote_up: number\n}\n\nexport interface EntityCookedSite {\n  first_url: string\n  id: number\n  name: string\n  urls: string[]\n  urls_raw: string\n}\n\nexport interface EntityCookedUser {\n  badge_color: string\n  badge_name: string\n  email: string\n  id: number\n  is_admin: boolean\n  link: string\n  name: string\n  receive_email: boolean\n}\n\nexport interface EntityCookedUserForAdmin {\n  badge_color: string\n  badge_name: string\n  comment_count: number\n  email: string\n  id: number\n  is_admin: boolean\n  is_in_conf: boolean\n  last_ip: string\n  last_ua: string\n  link: string\n  name: string\n  receive_email: boolean\n}\n\nexport type HandlerMap = Record<string, any>\n\nexport interface HandlerParamsCaptchaVerify {\n  /** The captcha value to check */\n  value: string\n}\n\nexport interface HandlerParamsCommentCreate {\n  /** The comment content */\n  content: string\n  /** The comment email */\n  email: string\n  /** The comment link */\n  link?: string\n  /** The comment name */\n  name: string\n  /** The comment page_key */\n  page_key: string\n  /** The comment page_title */\n  page_title?: string\n  /** The comment rid */\n  rid?: number\n  /** The site name of your content scope */\n  site_name: string\n  /** The comment ua */\n  ua?: string\n}\n\nexport interface HandlerParamsCommentUpdate {\n  /** The comment content */\n  content: string\n  /** The comment email */\n  email?: string\n  /** The comment ip */\n  ip?: string\n  /** The comment is_collapsed */\n  is_collapsed: boolean\n  /** The comment is_pending */\n  is_pending: boolean\n  /** The comment is_pinned */\n  is_pinned: boolean\n  /** The comment link */\n  link?: string\n  /** The comment nick */\n  nick?: string\n  /** The comment page_key */\n  page_key: string\n  /** The comment rid */\n  rid: number\n  /** The site name of your content scope */\n  site_name: string\n  /** The comment ua */\n  ua?: string\n}\n\nexport interface HandlerParamsEmailSend {\n  /** The body of email */\n  body: string\n  /** The subject of email */\n  subject: string\n  /** The email address of the receiver */\n  to_addr: string\n}\n\nexport interface HandlerParamsNotifyReadAll {\n  /** The user email */\n  email: string\n  /** The username */\n  name: string\n}\n\nexport interface HandlerParamsPageFetchAll {\n  /** If not empty, only fetch pages of this site */\n  site_name?: string\n}\n\nexport interface HandlerParamsPagePV {\n  /** The page key */\n  page_key: string\n  /** The page title */\n  page_title?: string\n  /** The site name of your content scope */\n  site_name?: string\n}\n\nexport interface HandlerParamsPageUpdate {\n  /** Updated page admin_only option */\n  admin_only: boolean\n  /** Updated page key */\n  key: string\n  /** The site name of your content scope */\n  site_name: string\n  /** Updated page title */\n  title: string\n}\n\nexport interface HandlerParamsSettingApply {\n  /** The content of the config file in YAML format */\n  yaml: string\n}\n\nexport interface HandlerParamsSiteCreate {\n  /** The site name */\n  name: string\n  /** The site urls */\n  urls: string[]\n}\n\nexport interface HandlerParamsSiteUpdate {\n  /** Updated site name */\n  name: string\n  /** Updated site urls */\n  urls: string[]\n}\n\nexport interface HandlerParamsTransferImport {\n  /** Automatically answer yes for all questions */\n  assumeyes?: boolean\n  /** The JSON data */\n  json_data?: string\n  /** The JSON file path */\n  json_file?: string\n  /** The target site name */\n  target_site_name?: string\n  /** The target site url */\n  target_site_url?: string\n  /** Keep domain */\n  url_keep_domain?: boolean\n  /** Enable URL resolver */\n  url_resolver?: boolean\n}\n\nexport interface HandlerParamsUserCreate {\n  /** The user badge color (hex format) */\n  badge_color?: string\n  /** The user badge name */\n  badge_name?: string\n  /** The user email */\n  email: string\n  /** The user is an admin */\n  is_admin: boolean\n  /** The user link */\n  link?: string\n  /** The user name */\n  name: string\n  /** The user password */\n  password?: string\n  /** The user receive email */\n  receive_email: boolean\n}\n\nexport interface HandlerParamsUserLogin {\n  /** The user email */\n  email: string\n  /** The username */\n  name?: string\n  /** The user password */\n  password: string\n}\n\nexport interface HandlerParamsUserUpdate {\n  /** The user badge color (hex format) */\n  badge_color?: string\n  /** The user badge name */\n  badge_name?: string\n  /** The user email */\n  email: string\n  /** The user is an admin */\n  is_admin: boolean\n  /** The user link */\n  link?: string\n  /** The user name */\n  name: string\n  /** The user password */\n  password?: string\n  /** The user receive email */\n  receive_email: boolean\n}\n\nexport interface HandlerParamsVoteCreate {\n  /** The user email */\n  email?: string\n  /** The username */\n  name?: string\n}\n\nexport interface HandlerRequestAuthDataMergeApply {\n  user_name: string\n}\n\nexport interface HandlerRequestAuthEmailLogin {\n  code?: string\n  email: string\n  password?: string\n}\n\nexport interface HandlerRequestAuthEmailRegister {\n  code: string\n  email: string\n  link?: string\n  name?: string\n  password: string\n}\n\nexport interface HandlerRequestAuthEmailSend {\n  email: string\n}\n\nexport interface HandlerRequestUserInfoUpdate {\n  code?: string\n  email: string\n  link?: string\n  name: string\n}\n\nexport interface HandlerResponseAdminUserList {\n  count: number\n  users: EntityCookedUserForAdmin[]\n}\n\nexport interface HandlerResponseAuthDataMergeApply {\n  deleted_user_count: number\n  update_comments_count: number\n  update_notifies_count: number\n  update_votes_count: number\n  /** Empty if login user is target user no need to re-login */\n  user_token: string\n}\n\nexport interface HandlerResponseAuthDataMergeCheck {\n  need_merge: boolean\n  user_names: string[]\n}\n\nexport interface HandlerResponseCaptchaGet {\n  img_data: string\n}\n\nexport interface HandlerResponseCaptchaStatus {\n  is_pass: boolean\n}\n\nexport interface HandlerResponseCommentCreate {\n  badge_color: string\n  badge_name: string\n  content: string\n  content_marked: string\n  date: string\n  email_encrypted: string\n  id: number\n  ip_region: string\n  is_allow_reply: boolean\n  is_collapsed: boolean\n  is_pending: boolean\n  is_pinned: boolean\n  is_verified: boolean\n  link: string\n  nick: string\n  page_key: string\n  page_url: string\n  rid: number\n  site_name: string\n  ua: string\n  user_id: number\n  visible: boolean\n  vote_down: number\n  vote_up: number\n}\n\nexport interface HandlerResponseCommentGet {\n  /** The comment detail */\n  comment: EntityCookedComment\n  /** The reply comment if exists (like reply) */\n  reply_comment: EntityCookedComment\n}\n\nexport interface HandlerResponseCommentList {\n  comments: EntityCookedComment[]\n  count: number\n  page: EntityCookedPage\n  roots_count: number\n}\n\nexport interface HandlerResponseCommentUpdate {\n  badge_color: string\n  badge_name: string\n  content: string\n  content_marked: string\n  date: string\n  email_encrypted: string\n  id: number\n  ip_region: string\n  is_allow_reply: boolean\n  is_collapsed: boolean\n  is_pending: boolean\n  is_pinned: boolean\n  is_verified: boolean\n  link: string\n  nick: string\n  page_key: string\n  page_url: string\n  rid: number\n  site_name: string\n  ua: string\n  user_id: number\n  visible: boolean\n  vote_down: number\n  vote_up: number\n}\n\nexport interface HandlerResponseConfAuthProviders {\n  anonymous: boolean\n  providers: AuthAuthProviderInfo[]\n}\n\nexport interface HandlerResponseConfDomain {\n  /** Is the domain trusted */\n  is_trusted: boolean\n  /** The origin of the domain */\n  origin: string\n}\n\nexport interface HandlerResponseNotifyList {\n  count: number\n  notifies: EntityCookedNotify[]\n}\n\nexport interface HandlerResponsePageFetch {\n  admin_only: boolean\n  date: string\n  id: number\n  key: string\n  pv: number\n  site_name: string\n  title: string\n  url: string\n  vote_down: number\n  vote_up: number\n}\n\nexport interface HandlerResponsePageFetchStatus {\n  /** The number of pages that have been fetched */\n  done: number\n  /** If the task is in progress */\n  is_progress: boolean\n  /** The message of the task status */\n  msg: string\n  /** The total number of pages */\n  total: number\n}\n\nexport interface HandlerResponsePageList {\n  count: number\n  pages: EntityCookedPage[]\n}\n\nexport interface HandlerResponsePagePV {\n  pv: number\n}\n\nexport interface HandlerResponsePageUpdate {\n  admin_only: boolean\n  date: string\n  id: number\n  key: string\n  pv: number\n  site_name: string\n  title: string\n  url: string\n  vote_down: number\n  vote_up: number\n}\n\nexport interface HandlerResponseSettingGet {\n  envs: string[]\n  yaml: string\n}\n\nexport interface HandlerResponseSettingTemplate {\n  yaml: string\n}\n\nexport interface HandlerResponseSiteCreate {\n  first_url: string\n  id: number\n  name: string\n  urls: string[]\n  urls_raw: string\n}\n\nexport interface HandlerResponseSiteList {\n  count: number\n  sites: EntityCookedSite[]\n}\n\nexport interface HandlerResponseSiteUpdate {\n  first_url: string\n  id: number\n  name: string\n  urls: string[]\n  urls_raw: string\n}\n\nexport interface HandlerResponseTransferExport {\n  /** The exported data which is a JSON string */\n  artrans: string\n}\n\nexport interface HandlerResponseTransferUpload {\n  /** The uploaded file name which can be used to import */\n  filename: string\n}\n\nexport interface HandlerResponseUpload {\n  file_name: string\n  file_type: string\n  public_url: string\n}\n\nexport interface HandlerResponseUserCreate {\n  badge_color: string\n  badge_name: string\n  comment_count: number\n  email: string\n  id: number\n  is_admin: boolean\n  is_in_conf: boolean\n  last_ip: string\n  last_ua: string\n  link: string\n  name: string\n  receive_email: boolean\n}\n\nexport interface HandlerResponseUserInfo {\n  is_login: boolean\n  notifies: EntityCookedNotify[]\n  notifies_count: number\n  user: EntityCookedUser\n}\n\nexport interface HandlerResponseUserInfoUpdate {\n  user: EntityCookedUser\n}\n\nexport interface HandlerResponseUserLogin {\n  token: string\n  user: EntityCookedUser\n}\n\nexport interface HandlerResponseUserStatus {\n  is_admin: boolean\n  is_login: boolean\n}\n\nexport interface HandlerResponseUserUpdate {\n  badge_color: string\n  badge_name: string\n  comment_count: number\n  email: string\n  id: number\n  is_admin: boolean\n  is_in_conf: boolean\n  last_ip: string\n  last_ua: string\n  link: string\n  name: string\n  receive_email: boolean\n}\n\nexport interface HandlerResponseVote {\n  down: number\n  is_down: boolean\n  is_up: boolean\n  up: number\n}\n\nexport type QueryParamsType = Record<string | number, any>\nexport type ResponseFormat = keyof Omit<Body, 'body' | 'bodyUsed'>\n\nexport interface FullRequestParams extends Omit<RequestInit, 'body'> {\n  /** set parameter to `true` for call `securityWorker` for this request */\n  secure?: boolean\n  /** request path */\n  path: string\n  /** content type of request body */\n  type?: ContentType\n  /** query params */\n  query?: QueryParamsType\n  /** format of response (i.e. response.json() -> format: \"json\") */\n  format?: ResponseFormat\n  /** request body */\n  body?: unknown\n  /** base url */\n  baseUrl?: string\n  /** request cancellation token */\n  cancelToken?: CancelToken\n}\n\nexport type RequestParams = Omit<FullRequestParams, 'body' | 'method' | 'query' | 'path'>\n\nexport interface ApiConfig<SecurityDataType = unknown> {\n  baseUrl?: string\n  baseApiParams?: Omit<RequestParams, 'baseUrl' | 'cancelToken' | 'signal'>\n  securityWorker?: (\n    securityData: SecurityDataType | null,\n  ) => Promise<RequestParams | void> | RequestParams | void\n  customFetch?: typeof fetch\n}\n\nexport interface HttpResponse<D extends unknown, E extends unknown = unknown> extends Response {\n  data: D\n  error: E\n}\n\ntype CancelToken = Symbol | string | number\n\nexport enum ContentType {\n  Json = 'application/json',\n  FormData = 'multipart/form-data',\n  UrlEncoded = 'application/x-www-form-urlencoded',\n  Text = 'text/plain',\n}\n\nexport class HttpClient<SecurityDataType = unknown> {\n  public baseUrl: string = '/api/v2'\n  private securityData: SecurityDataType | null = null\n  private securityWorker?: ApiConfig<SecurityDataType>['securityWorker']\n  private abortControllers = new Map<CancelToken, AbortController>()\n  private customFetch = (...fetchParams: Parameters<typeof fetch>) => fetch(...fetchParams)\n\n  private baseApiParams: RequestParams = {\n    credentials: 'same-origin',\n    headers: {},\n    redirect: 'follow',\n    referrerPolicy: 'no-referrer',\n  }\n\n  constructor(apiConfig: ApiConfig<SecurityDataType> = {}) {\n    Object.assign(this, apiConfig)\n  }\n\n  public setSecurityData = (data: SecurityDataType | null) => {\n    this.securityData = data\n  }\n\n  protected encodeQueryParam(key: string, value: any) {\n    const encodedKey = encodeURIComponent(key)\n    return `${encodedKey}=${encodeURIComponent(typeof value === 'number' ? value : `${value}`)}`\n  }\n\n  protected addQueryParam(query: QueryParamsType, key: string) {\n    return this.encodeQueryParam(key, query[key])\n  }\n\n  protected addArrayQueryParam(query: QueryParamsType, key: string) {\n    const value = query[key]\n    return value.map((v: any) => this.encodeQueryParam(key, v)).join('&')\n  }\n\n  protected toQueryString(rawQuery?: QueryParamsType): string {\n    const query = rawQuery || {}\n    const keys = Object.keys(query).filter((key) => 'undefined' !== typeof query[key])\n    return keys\n      .map((key) =>\n        Array.isArray(query[key])\n          ? this.addArrayQueryParam(query, key)\n          : this.addQueryParam(query, key),\n      )\n      .join('&')\n  }\n\n  protected addQueryParams(rawQuery?: QueryParamsType): string {\n    const queryString = this.toQueryString(rawQuery)\n    return queryString ? `?${queryString}` : ''\n  }\n\n  private contentFormatters: Record<ContentType, (input: any) => any> = {\n    [ContentType.Json]: (input: any) =>\n      input !== null && (typeof input === 'object' || typeof input === 'string')\n        ? JSON.stringify(input)\n        : input,\n    [ContentType.Text]: (input: any) =>\n      input !== null && typeof input !== 'string' ? JSON.stringify(input) : input,\n    [ContentType.FormData]: (input: any) =>\n      Object.keys(input || {}).reduce((formData, key) => {\n        const property = input[key]\n        formData.append(\n          key,\n          property instanceof Blob\n            ? property\n            : typeof property === 'object' && property !== null\n              ? JSON.stringify(property)\n              : `${property}`,\n        )\n        return formData\n      }, new FormData()),\n    [ContentType.UrlEncoded]: (input: any) => this.toQueryString(input),\n  }\n\n  protected mergeRequestParams(params1: RequestParams, params2?: RequestParams): RequestParams {\n    return {\n      ...this.baseApiParams,\n      ...params1,\n      ...(params2 || {}),\n      headers: {\n        ...(this.baseApiParams.headers || {}),\n        ...(params1.headers || {}),\n        ...((params2 && params2.headers) || {}),\n      },\n    }\n  }\n\n  protected createAbortSignal = (cancelToken: CancelToken): AbortSignal | undefined => {\n    if (this.abortControllers.has(cancelToken)) {\n      const abortController = this.abortControllers.get(cancelToken)\n      if (abortController) {\n        return abortController.signal\n      }\n      return void 0\n    }\n\n    const abortController = new AbortController()\n    this.abortControllers.set(cancelToken, abortController)\n    return abortController.signal\n  }\n\n  public abortRequest = (cancelToken: CancelToken) => {\n    const abortController = this.abortControllers.get(cancelToken)\n\n    if (abortController) {\n      abortController.abort()\n      this.abortControllers.delete(cancelToken)\n    }\n  }\n\n  public request = async <T = any, E = any>({\n    body,\n    secure,\n    path,\n    type,\n    query,\n    format,\n    baseUrl,\n    cancelToken,\n    ...params\n  }: FullRequestParams): Promise<HttpResponse<T, E>> => {\n    const secureParams =\n      ((typeof secure === 'boolean' ? secure : this.baseApiParams.secure) &&\n        this.securityWorker &&\n        (await this.securityWorker(this.securityData))) ||\n      {}\n    const requestParams = this.mergeRequestParams(params, secureParams)\n    const queryString = query && this.toQueryString(query)\n    const payloadFormatter = this.contentFormatters[type || ContentType.Json]\n    const responseFormat = format || requestParams.format\n\n    return this.customFetch(\n      `${baseUrl || this.baseUrl || ''}${path}${queryString ? `?${queryString}` : ''}`,\n      {\n        ...requestParams,\n        headers: {\n          ...(requestParams.headers || {}),\n          ...(type && type !== ContentType.FormData ? { 'Content-Type': type } : {}),\n        },\n        signal: (cancelToken ? this.createAbortSignal(cancelToken) : requestParams.signal) || null,\n        body: typeof body === 'undefined' || body === null ? null : payloadFormatter(body),\n      },\n    ).then(async (response) => {\n      const r = response.clone() as HttpResponse<T, E>\n      r.data = null as unknown as T\n      r.error = null as unknown as E\n\n      const data = !responseFormat\n        ? r\n        : await response[responseFormat]()\n            .then((data) => {\n              if (r.ok) {\n                r.data = data\n              } else {\n                r.error = data\n              }\n              return r\n            })\n            .catch((e) => {\n              r.error = e\n              return r\n            })\n\n      if (cancelToken) {\n        this.abortControllers.delete(cancelToken)\n      }\n\n      if (!response.ok) throw data\n      return data\n    })\n  }\n}\n\n/**\n * @title Artalk API\n * @version 2.0\n * @license MIT (https://github.com/ArtalkJS/Artalk/blob/master/LICENSE)\n * @baseUrl /api/v2\n * @contact API Support <artalkjs@gmail.com> (https://artalk.js.org)\n *\n * Artalk is a modern comment system based on Golang.\n */\nexport class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDataType> {\n  auth = {\n    /**\n * @description Login by email with verify code (Need send email verify code first) or password\n *\n * @tags Auth\n * @name LoginByEmail\n * @summary Login by email\n * @request POST:/auth/email/login\n * @response `200` `HandlerResponseUserLogin` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    loginByEmail: (data: HandlerRequestAuthEmailLogin, params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseUserLogin,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/auth/email/login`,\n        method: 'POST',\n        body: data,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Register by email and verify code (if user exists, will update user, like forget or change password. Need send email verify code first)\n *\n * @tags Auth\n * @name RegisterByEmail\n * @summary Register by email\n * @request POST:/auth/email/register\n * @response `200` `HandlerResponseUserLogin` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    registerByEmail: (data: HandlerRequestAuthEmailRegister, params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseUserLogin,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/auth/email/register`,\n        method: 'POST',\n        body: data,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Send email including verify code to user\n *\n * @tags Auth\n * @name SendVerifyEmail\n * @summary Send verify email\n * @request POST:/auth/email/send\n * @response `200` `(HandlerMap & {\n    msg?: string,\n\n})` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    sendVerifyEmail: (data: HandlerRequestAuthEmailSend, params: RequestParams = {}) =>\n      this.request<\n        HandlerMap & {\n          msg?: string\n        },\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/auth/email/send`,\n        method: 'POST',\n        body: data,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Get all users with same email, if there are more than one user with same email, need merge\n *\n * @tags Auth\n * @name CheckDataMerge\n * @summary Check data merge\n * @request GET:/auth/merge\n * @secure\n * @response `200` `HandlerResponseAuthDataMergeCheck` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    checkDataMerge: (params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseAuthDataMergeCheck,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/auth/merge`,\n        method: 'GET',\n        secure: true,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description This function is to solve the problem of multiple users with the same email address, should be called after user login and then check, and perform data merge.\n *\n * @tags Auth\n * @name ApplyDataMerge\n * @summary Apply data merge\n * @request POST:/auth/merge\n * @secure\n * @response `200` `HandlerResponseAuthDataMergeApply` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    applyDataMerge: (data: HandlerRequestAuthDataMergeApply, params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseAuthDataMergeApply,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/auth/merge`,\n        method: 'POST',\n        body: data,\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n  }\n  cache = {\n    /**\n * @description Flush all cache on the server\n *\n * @tags Cache\n * @name FlushCache\n * @summary Flush Cache\n * @request POST:/cache/flush\n * @secure\n * @response `200` `(HandlerMap & {\n    msg?: string,\n\n})` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n */\n    flushCache: (params: RequestParams = {}) =>\n      this.request<\n        HandlerMap & {\n          msg?: string\n        },\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/cache/flush`,\n        method: 'POST',\n        secure: true,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Cache warming helps you to pre-load the cache to improve the performance of the first request\n *\n * @tags Cache\n * @name WarmUpCache\n * @summary Warm-Up Cache\n * @request POST:/cache/warm_up\n * @secure\n * @response `200` `(HandlerMap & {\n    msg?: string,\n\n})` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n */\n    warmUpCache: (params: RequestParams = {}) =>\n      this.request<\n        HandlerMap & {\n          msg?: string\n        },\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/cache/warm_up`,\n        method: 'POST',\n        secure: true,\n        format: 'json',\n        ...params,\n      }),\n  }\n  captcha = {\n    /**\n * @description Get a base64 encoded captcha image or a HTML page to verify for user\n *\n * @tags Captcha\n * @name GetCaptcha\n * @summary Get Captcha\n * @request GET:/captcha\n * @response `200` `HandlerResponseCaptchaGet` OK\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    getCaptcha: (params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseCaptchaGet,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/captcha`,\n        method: 'GET',\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n     * @description Get the status of the user's captcha verification\n     *\n     * @tags Captcha\n     * @name GetCaptchaStatus\n     * @summary Get Captcha Status\n     * @request GET:/captcha/status\n     * @response `200` `HandlerResponseCaptchaStatus` OK\n     */\n    getCaptchaStatus: (params: RequestParams = {}) =>\n      this.request<HandlerResponseCaptchaStatus, any>({\n        path: `/captcha/status`,\n        method: 'GET',\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Verify user enters correct captcha code\n *\n * @tags Captcha\n * @name VerifyCaptcha\n * @summary Verify Captcha\n * @request POST:/captcha/verify\n * @response `200` `HandlerMap` OK\n * @response `403` `(HandlerMap & {\n    img_data?: string,\n\n})` Forbidden\n */\n    verifyCaptcha: (data: HandlerParamsCaptchaVerify, params: RequestParams = {}) =>\n      this.request<\n        HandlerMap,\n        HandlerMap & {\n          img_data?: string\n        }\n      >({\n        path: `/captcha/verify`,\n        method: 'POST',\n        body: data,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n  }\n  comments = {\n    /**\n * @description Get a list of comments by some conditions\n *\n * @tags Comment\n * @name GetComments\n * @summary Get Comment List\n * @request GET:/comments\n * @secure\n * @response `200` `HandlerResponseCommentList` OK\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    getComments: (\n      query: {\n        /** The user email */\n        email?: string\n        /** Enable flat_mode */\n        flat_mode?: boolean\n        /** The limit for pagination */\n        limit?: number\n        /** The username */\n        name?: string\n        /** The offset for pagination */\n        offset?: number\n        /** The comment page_key */\n        page_key: string\n        /** The scope of comments */\n        scope?: 'page' | 'user' | 'site'\n        /** Search keywords */\n        search?: string\n        /** The site name of your content scope */\n        site_name?: string\n        /** Sort by condition */\n        sort_by?: 'date_asc' | 'date_desc' | 'vote'\n        /** Message center show type */\n        type?: 'all' | 'mentions' | 'mine' | 'pending'\n        /** Only show comments by admin */\n        view_only_admin?: boolean\n      },\n      params: RequestParams = {},\n    ) =>\n      this.request<\n        HandlerResponseCommentList,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/comments`,\n        method: 'GET',\n        query: query,\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Create a new comment\n *\n * @tags Comment\n * @name CreateComment\n * @summary Create Comment\n * @request POST:/comments\n * @secure\n * @response `200` `HandlerResponseCommentCreate` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    createComment: (comment: HandlerParamsCommentCreate, params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseCommentCreate,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/comments`,\n        method: 'POST',\n        body: comment,\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Get the detail of a comment by comment id\n *\n * @tags Comment\n * @name GetComment\n * @summary Get a comment\n * @request GET:/comments/{id}\n * @response `200` `HandlerResponseCommentGet` OK\n * @response `404` `(HandlerMap & {\n    msg?: string,\n\n})` Not Found\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    getComment: (id: number, params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseCommentGet,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/comments/${id}`,\n        method: 'GET',\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Update a specific comment\n *\n * @tags Comment\n * @name UpdateComment\n * @summary Update Comment\n * @request PUT:/comments/{id}\n * @secure\n * @response `200` `HandlerResponseCommentUpdate` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `404` `(HandlerMap & {\n    msg?: string,\n\n})` Not Found\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    updateComment: (id: number, comment: HandlerParamsCommentUpdate, params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseCommentUpdate,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/comments/${id}`,\n        method: 'PUT',\n        body: comment,\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Delete a specific comment\n *\n * @tags Comment\n * @name DeleteComment\n * @summary Delete Comment\n * @request DELETE:/comments/{id}\n * @secure\n * @response `200` `HandlerMap` OK\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `404` `(HandlerMap & {\n    msg?: string,\n\n})` Not Found\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    deleteComment: (id: number, params: RequestParams = {}) =>\n      this.request<\n        HandlerMap,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/comments/${id}`,\n        method: 'DELETE',\n        secure: true,\n        format: 'json',\n        ...params,\n      }),\n  }\n  conf = {\n    /**\n     * @description Get System Configs for UI\n     *\n     * @tags System\n     * @name Conf\n     * @summary Get System Configs\n     * @request GET:/conf\n     * @response `200` `CommonConfData` OK\n     */\n    conf: (params: RequestParams = {}) =>\n      this.request<CommonConfData, any>({\n        path: `/conf`,\n        method: 'GET',\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Get social login providers\n *\n * @tags System\n * @name GetSocialLoginProviders\n * @summary Get Social Login Providers\n * @request GET:/conf/auth/providers\n * @response `200` `HandlerResponseConfAuthProviders` OK\n * @response `404` `(HandlerMap & {\n    msg?: string,\n\n})` Not Found\n */\n    getSocialLoginProviders: (params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseConfAuthProviders,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/conf/auth/providers`,\n        method: 'GET',\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n     * @description Get Domain Info\n     *\n     * @tags System\n     * @name GetDomain\n     * @summary Get Domain Info\n     * @request GET:/conf/domain\n     * @response `200` `HandlerResponseConfDomain` OK\n     */\n    getDomain: (\n      query?: {\n        /** Domain URL */\n        url?: string\n      },\n      params: RequestParams = {},\n    ) =>\n      this.request<HandlerResponseConfDomain, any>({\n        path: `/conf/domain`,\n        method: 'GET',\n        query: query,\n        format: 'json',\n        ...params,\n      }),\n  }\n  notifies = {\n    /**\n * @description Get a list of notifies for user\n *\n * @tags Notify\n * @name GetNotifies\n * @summary Get Notifies\n * @request GET:/notifies\n * @response `200` `HandlerResponseNotifyList` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    getNotifies: (\n      query: {\n        /** The user email */\n        email: string\n        /** The user name */\n        name: string\n      },\n      params: RequestParams = {},\n    ) =>\n      this.request<\n        HandlerResponseNotifyList,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/notifies`,\n        method: 'GET',\n        query: query,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Mark all notifies as read for user\n *\n * @tags Notify\n * @name MarkAllNotifyRead\n * @summary Mark All Notifies as Read\n * @request POST:/notifies/read\n * @response `200` `HandlerMap` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    markAllNotifyRead: (options: HandlerParamsNotifyReadAll, params: RequestParams = {}) =>\n      this.request<\n        HandlerMap,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/notifies/read`,\n        method: 'POST',\n        body: options,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Mark specific notification as read for user\n *\n * @tags Notify\n * @name MarkNotifyRead\n * @summary Mark Notify as Read\n * @request POST:/notifies/{comment_id}/{notify_key}\n * @response `200` `HandlerMap` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `404` `(HandlerMap & {\n    msg?: string,\n\n})` Not Found\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    markNotifyRead: (commentId: number, notifyKey: string, params: RequestParams = {}) =>\n      this.request<\n        HandlerMap,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/notifies/${commentId}/${notifyKey}`,\n        method: 'POST',\n        format: 'json',\n        ...params,\n      }),\n  }\n  pages = {\n    /**\n * @description Get a list of pages by some conditions\n *\n * @tags Page\n * @name GetPages\n * @summary Get Page List\n * @request GET:/pages\n * @secure\n * @response `200` `HandlerResponsePageList` OK\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n */\n    getPages: (\n      query?: {\n        /** The limit for pagination */\n        limit?: number\n        /** The offset for pagination */\n        offset?: number\n        /** Search keywords */\n        search?: string\n        /** The site name of your content scope */\n        site_name?: string\n      },\n      params: RequestParams = {},\n    ) =>\n      this.request<\n        HandlerResponsePageList,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/pages`,\n        method: 'GET',\n        query: query,\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Fetch the data of all pages\n *\n * @tags Page\n * @name FetchAllPages\n * @summary Fetch All Pages Data\n * @request POST:/pages/fetch\n * @secure\n * @response `200` `HandlerMap` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    fetchAllPages: (options: HandlerParamsPageFetchAll, params: RequestParams = {}) =>\n      this.request<\n        HandlerMap,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/pages/fetch`,\n        method: 'POST',\n        body: options,\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n     * @description Get the status of the task of fetching all pages\n     *\n     * @tags Page\n     * @name GetPageFetchStatus\n     * @summary Get Pages Fetch Status\n     * @request GET:/pages/fetch/status\n     * @secure\n     * @response `200` `HandlerResponsePageFetchStatus` OK\n     */\n    getPageFetchStatus: (params: RequestParams = {}) =>\n      this.request<HandlerResponsePageFetchStatus, any>({\n        path: `/pages/fetch/status`,\n        method: 'GET',\n        secure: true,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n     * @description Increase and get the number of page views\n     *\n     * @tags Page\n     * @name LogPv\n     * @summary Increase Page Views (PV)\n     * @request POST:/pages/pv\n     * @response `200` `HandlerResponsePagePV` OK\n     */\n    logPv: (page: HandlerParamsPagePV, params: RequestParams = {}) =>\n      this.request<HandlerResponsePagePV, any>({\n        path: `/pages/pv`,\n        method: 'POST',\n        body: page,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Update a specific page\n *\n * @tags Page\n * @name UpdatePage\n * @summary Update Page\n * @request PUT:/pages/{id}\n * @secure\n * @response `200` `HandlerResponsePageUpdate` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `404` `(HandlerMap & {\n    msg?: string,\n\n})` Not Found\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    updatePage: (id: number, page: HandlerParamsPageUpdate, params: RequestParams = {}) =>\n      this.request<\n        HandlerResponsePageUpdate,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/pages/${id}`,\n        method: 'PUT',\n        body: page,\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Delete a specific page\n *\n * @tags Page\n * @name DeletePage\n * @summary Delete Page\n * @request DELETE:/pages/{id}\n * @secure\n * @response `200` `HandlerMap` OK\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `404` `(HandlerMap & {\n    msg?: string,\n\n})` Not Found\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    deletePage: (id: number, params: RequestParams = {}) =>\n      this.request<\n        HandlerMap,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/pages/${id}`,\n        method: 'DELETE',\n        secure: true,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Fetch the data of a specific page\n *\n * @tags Page\n * @name FetchPage\n * @summary Fetch Page Data\n * @request POST:/pages/{id}/fetch\n * @secure\n * @response `200` `HandlerResponsePageFetch` OK\n * @response `404` `(HandlerMap & {\n    msg?: string,\n\n})` Not Found\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    fetchPage: (id: number, params: RequestParams = {}) =>\n      this.request<\n        HandlerResponsePageFetch,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/pages/${id}/fetch`,\n        method: 'POST',\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n  }\n  sendEmail = {\n    /**\n * @description Send an email to test the email sender\n *\n * @tags System\n * @name SendEmail\n * @summary Send Email\n * @request POST:/send_email\n * @secure\n * @response `200` `HandlerMap` OK\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `500` `HandlerMap` Internal Server Error\n */\n    sendEmail: (email: HandlerParamsEmailSend, params: RequestParams = {}) =>\n      this.request<\n        HandlerMap,\n        | (HandlerMap & {\n            msg?: string\n          })\n        | HandlerMap\n      >({\n        path: `/send_email`,\n        method: 'POST',\n        body: email,\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n  }\n  settings = {\n    /**\n * @description Get settings from app config file\n *\n * @tags System\n * @name GetSettings\n * @summary Get Settings\n * @request GET:/settings\n * @secure\n * @response `200` `HandlerResponseSettingGet` OK\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    getSettings: (params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseSettingGet,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/settings`,\n        method: 'GET',\n        secure: true,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Apply settings and restart the server\n *\n * @tags System\n * @name ApplySettings\n * @summary Save and apply Settings\n * @request PUT:/settings\n * @secure\n * @response `200` `HandlerMap` OK\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    applySettings: (settings: HandlerParamsSettingApply, params: RequestParams = {}) =>\n      this.request<\n        HandlerMap,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/settings`,\n        method: 'PUT',\n        body: settings,\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n     * @description Get config templates in different languages for rendering the settings page in the frontend\n     *\n     * @tags System\n     * @name GetSettingsTemplate\n     * @summary Get Settings Template\n     * @request GET:/settings/template/{locale}\n     * @secure\n     * @response `200` `HandlerResponseSettingTemplate` OK\n     */\n    getSettingsTemplate: (locale: string, params: RequestParams = {}) =>\n      this.request<HandlerResponseSettingTemplate, any>({\n        path: `/settings/template/${locale}`,\n        method: 'GET',\n        secure: true,\n        format: 'json',\n        ...params,\n      }),\n  }\n  sites = {\n    /**\n     * @description Get a list of sites by some conditions\n     *\n     * @tags Site\n     * @name GetSites\n     * @summary Get Site List\n     * @request GET:/sites\n     * @secure\n     * @response `200` `HandlerResponseSiteList` OK\n     */\n    getSites: (params: RequestParams = {}) =>\n      this.request<HandlerResponseSiteList, any>({\n        path: `/sites`,\n        method: 'GET',\n        secure: true,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Create a new site\n *\n * @tags Site\n * @name CreateSite\n * @summary Create Site\n * @request POST:/sites\n * @secure\n * @response `200` `HandlerResponseSiteCreate` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    createSite: (site: HandlerParamsSiteCreate, params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseSiteCreate,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/sites`,\n        method: 'POST',\n        body: site,\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n     * @description Update a specific site\n     *\n     * @tags Site\n     * @name UpdateSite\n     * @summary Update Site\n     * @request PUT:/sites/{id}\n     * @secure\n     * @response `200` `HandlerResponseSiteUpdate` OK\n     */\n    updateSite: (id: number, site: HandlerParamsSiteUpdate, params: RequestParams = {}) =>\n      this.request<HandlerResponseSiteUpdate, any>({\n        path: `/sites/${id}`,\n        method: 'PUT',\n        body: site,\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Delete a specific site\n *\n * @tags Site\n * @name DeleteSite\n * @summary Site Delete\n * @request DELETE:/sites/{id}\n * @secure\n * @response `200` `HandlerMap` OK\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `404` `(HandlerMap & {\n    msg?: string,\n\n})` Not Found\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    deleteSite: (id: number, params: RequestParams = {}) =>\n      this.request<\n        HandlerMap,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/sites/${id}`,\n        method: 'DELETE',\n        secure: true,\n        format: 'json',\n        ...params,\n      }),\n  }\n  stats = {\n    /**\n * @description Get the statistics of various data analysis\n *\n * @tags Statistic\n * @name GetStats\n * @summary Statistic\n * @request GET:/stats/{type}\n * @response `200` `CommonJSONResult` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `404` `(HandlerMap & {\n    msg?: string,\n\n})` Not Found\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    getStats: (\n      type:\n        | 'latest_comments'\n        | 'latest_pages'\n        | 'pv_most_pages'\n        | 'comment_most_pages'\n        | 'page_pv'\n        | 'site_pv'\n        | 'page_comment'\n        | 'site_comment'\n        | 'rand_comments'\n        | 'rand_pages',\n      query?: {\n        /** The limit for pagination */\n        limit?: number\n        /** multiple page keys separated by commas */\n        page_keys?: string\n        /** The site name of your content scope */\n        site_name?: string\n      },\n      params: RequestParams = {},\n    ) =>\n      this.request<\n        CommonJSONResult,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/stats/${type}`,\n        method: 'GET',\n        query: query,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n  }\n  transfer = {\n    /**\n * @description Export data from Artalk\n *\n * @tags Transfer\n * @name ExportArtrans\n * @summary Export Artrans\n * @request GET:/transfer/export\n * @secure\n * @response `200` `HandlerResponseTransferExport` OK\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    exportArtrans: (params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseTransferExport,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/transfer/export`,\n        method: 'GET',\n        secure: true,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n     * @description Import data to Artalk\n     *\n     * @tags Transfer\n     * @name ImportArtrans\n     * @summary Import Artrans\n     * @request POST:/transfer/import\n     * @secure\n     * @response `200` `string` OK\n     */\n    importArtrans: (data: HandlerParamsTransferImport, params: RequestParams = {}) =>\n      this.request<string, any>({\n        path: `/transfer/import`,\n        method: 'POST',\n        body: data,\n        secure: true,\n        type: ContentType.Json,\n        ...params,\n      }),\n\n    /**\n * @description Upload a file to prepare to import\n *\n * @tags Transfer\n * @name UploadArtrans\n * @summary Upload Artrans\n * @request POST:/transfer/upload\n * @secure\n * @response `200` `(HandlerResponseTransferUpload & {\n    filename?: string,\n\n})` OK\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    uploadArtrans: (\n      data: {\n        /**\n         * Upload file in preparation for import task\n         * @format binary\n         */\n        file: File\n      },\n      params: RequestParams = {},\n    ) =>\n      this.request<\n        HandlerResponseTransferUpload & {\n          filename?: string\n        },\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/transfer/upload`,\n        method: 'POST',\n        body: data,\n        secure: true,\n        type: ContentType.FormData,\n        format: 'json',\n        ...params,\n      }),\n  }\n  upload = {\n    /**\n * @description Upload file from this endpoint\n *\n * @tags Upload\n * @name Upload\n * @summary Upload\n * @request POST:/upload\n * @secure\n * @response `200` `HandlerResponseUpload` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    upload: (\n      data: {\n        /**\n         * Upload file\n         * @format binary\n         */\n        file: File\n      },\n      params: RequestParams = {},\n    ) =>\n      this.request<\n        HandlerResponseUpload,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/upload`,\n        method: 'POST',\n        body: data,\n        secure: true,\n        type: ContentType.FormData,\n        format: 'json',\n        ...params,\n      }),\n  }\n  user = {\n    /**\n * @description Get user info to prepare for login or check current user status\n *\n * @tags Auth\n * @name GetUser\n * @summary Get User Info\n * @request GET:/user\n * @secure\n * @response `200` `HandlerResponseUserInfo` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n */\n    getUser: (\n      query?: {\n        /** The user email */\n        email?: string\n        /** The username */\n        name?: string\n      },\n      params: RequestParams = {},\n    ) =>\n      this.request<\n        HandlerResponseUserInfo,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/user`,\n        method: 'GET',\n        query: query,\n        secure: true,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Update user profile when user is logged in\n *\n * @tags Auth\n * @name UpdateProfile\n * @summary Update user profile\n * @request POST:/user\n * @secure\n * @response `200` `HandlerResponseUserInfoUpdate` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    updateProfile: (data: HandlerRequestUserInfoUpdate, params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseUserInfoUpdate,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/user`,\n        method: 'POST',\n        body: data,\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Login user by name or email\n *\n * @tags Auth\n * @name Login\n * @summary Get Access Token\n * @request POST:/user/access_token\n * @response `200` `HandlerResponseUserLogin` OK\n * @response `400` `(HandlerMap & {\n    data?: {\n    need_name_select?: (string)[],\n\n},\n    msg?: string,\n\n})` Multiple users with the same email address are matched\n * @response `401` `(HandlerMap & {\n    msg?: string,\n\n})` Unauthorized\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    login: (user: HandlerParamsUserLogin, params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseUserLogin,\n        | (HandlerMap & {\n            data?: {\n              need_name_select?: string[]\n            }\n            msg?: string\n          })\n        | (HandlerMap & {\n            msg?: string\n          })\n      >({\n        path: `/user/access_token`,\n        method: 'POST',\n        body: user,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n     * @description Get user login status by header Authorization\n     *\n     * @tags Auth\n     * @name GetUserStatus\n     * @summary Get Login Status\n     * @request GET:/user/status\n     * @secure\n     * @response `200` `HandlerResponseUserStatus` OK\n     */\n    getUserStatus: (\n      query?: {\n        /** The user email */\n        email?: string\n        /** The username */\n        name?: string\n      },\n      params: RequestParams = {},\n    ) =>\n      this.request<HandlerResponseUserStatus, any>({\n        path: `/user/status`,\n        method: 'GET',\n        query: query,\n        secure: true,\n        format: 'json',\n        ...params,\n      }),\n  }\n  users = {\n    /**\n * @description Create a new user\n *\n * @tags User\n * @name CreateUser\n * @summary Create User\n * @request POST:/users\n * @secure\n * @response `200` `HandlerResponseUserCreate` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    createUser: (user: HandlerParamsUserCreate, params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseUserCreate,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/users`,\n        method: 'POST',\n        body: user,\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Update a specific user\n *\n * @tags User\n * @name UpdateUser\n * @summary Update User\n * @request PUT:/users/{id}\n * @secure\n * @response `200` `HandlerResponseUserUpdate` OK\n * @response `400` `(HandlerMap & {\n    msg?: string,\n\n})` Bad Request\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `404` `(HandlerMap & {\n    msg?: string,\n\n})` Not Found\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    updateUser: (id: number, user: HandlerParamsUserUpdate, params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseUserUpdate,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/users/${id}`,\n        method: 'PUT',\n        body: user,\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Delete a specific user\n *\n * @tags User\n * @name DeleteUser\n * @summary Delete User\n * @request DELETE:/users/{id}\n * @secure\n * @response `200` `HandlerMap` OK\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `404` `(HandlerMap & {\n    msg?: string,\n\n})` Not Found\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    deleteUser: (id: number, params: RequestParams = {}) =>\n      this.request<\n        HandlerMap,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/users/${id}`,\n        method: 'DELETE',\n        secure: true,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Get a list of users by some conditions\n *\n * @tags User\n * @name GetUsers\n * @summary Get User List\n * @request GET:/users/{type}\n * @secure\n * @response `200` `HandlerResponseAdminUserList` OK\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n */\n    getUsers: (\n      type?: 'all' | 'admin' | 'in_conf',\n      query?: {\n        /** The limit for pagination */\n        limit?: number\n        /** The offset for pagination */\n        offset?: number\n        /** Search keywords */\n        search?: string\n      },\n      params: RequestParams = {},\n    ) =>\n      this.request<\n        HandlerResponseAdminUserList,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/users/${type}`,\n        method: 'GET',\n        query: query,\n        secure: true,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n  }\n  version = {\n    /**\n     * @description Get the version of Artalk\n     *\n     * @tags System\n     * @name GetVersion\n     * @summary Get Version Info\n     * @request GET:/version\n     * @response `200` `CommonApiVersionData` OK\n     */\n    getVersion: (params: RequestParams = {}) =>\n      this.request<CommonApiVersionData, any>({\n        path: `/version`,\n        method: 'GET',\n        format: 'json',\n        ...params,\n      }),\n  }\n  votes = {\n    /**\n * @description Sync the number of votes in the `comments` or `pages` data tables to keep them the same as the `votes` table\n *\n * @tags Vote\n * @name SyncVotes\n * @summary Sync Vote Data\n * @request POST:/votes/sync\n * @secure\n * @response `200` `HandlerMap` OK\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n */\n    syncVotes: (params: RequestParams = {}) =>\n      this.request<\n        HandlerMap,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/votes/sync`,\n        method: 'POST',\n        secure: true,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Get vote status for a specific comment or page\n *\n * @tags Vote\n * @name GetVote\n * @summary Get Vote Status\n * @request GET:/votes/{target_name}/{target_id}\n * @response `200` `HandlerResponseVote` OK\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `404` `(HandlerMap & {\n    msg?: string,\n\n})` Not Found\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    getVote: (targetName: 'comment' | 'page', targetId: number, params: RequestParams = {}) =>\n      this.request<\n        HandlerResponseVote,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/votes/${targetName}/${targetId}`,\n        method: 'GET',\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n\n    /**\n * @description Create a new vote for a specific comment or page\n *\n * @tags Vote\n * @name CreateVote\n * @summary Create Vote\n * @request POST:/votes/{target_name}/{target_id}/{choice}\n * @response `200` `HandlerResponseVote` OK\n * @response `403` `(HandlerMap & {\n    msg?: string,\n\n})` Forbidden\n * @response `404` `(HandlerMap & {\n    msg?: string,\n\n})` Not Found\n * @response `500` `(HandlerMap & {\n    msg?: string,\n\n})` Internal Server Error\n */\n    createVote: (\n      targetName: 'comment' | 'page',\n      targetId: number,\n      choice: 'up' | 'down',\n      vote: HandlerParamsVoteCreate,\n      params: RequestParams = {},\n    ) =>\n      this.request<\n        HandlerResponseVote,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/votes/${targetName}/${targetId}/${choice}`,\n        method: 'POST',\n        body: vote,\n        type: ContentType.Json,\n        format: 'json',\n        ...params,\n      }),\n  }\n}\n","import { ApiOptions } from './options'\nimport { FetchError } from '@/types'\n\nexport const Fetch = async (\n  opts: ApiOptions,\n  input: string | URL | Request,\n  init?: RequestInit,\n) => {\n  const apiToken = opts.getApiToken && opts.getApiToken()\n\n  const headers = new Headers({\n    Authorization: apiToken ? `Bearer ${apiToken}` : '',\n    ...init?.headers,\n  })\n\n  if (!headers.get('Authorization')) headers.delete('Authorization')\n\n  // 请求操作\n  const resp = await fetch(input, {\n    ...init,\n    headers,\n  })\n\n  if (!resp.ok) {\n    // Deserialize response body (if it is JSON, otherwise returns `{}`)\n    const json: any = (await resp.json().catch(() => {})) || {}\n\n    let retry = false\n    opts.handlers &&\n      (await opts.handlers.get().reduce(async (promise, item) => {\n        await promise\n        if (json[item.action] === true) {\n          await item.handler(json)\n          retry = true\n        }\n      }, Promise.resolve()))\n\n    if (retry) return Fetch(opts, input, init)\n    throw createError(resp.status, json)\n  }\n\n  return resp\n}\n\nexport class FetchException extends Error implements FetchError {\n  code: number = 0\n  message: string = 'fetch error'\n  data?: any\n}\n\nfunction createError(code: number, data: any): FetchException {\n  const err = new FetchException()\n  err.message = data.msg || data.message || 'fetch error'\n  err.code = code\n  err.data = data\n  console.error(err)\n  return err\n}\n","import { ApiOptions } from './options'\nimport { Api as ApiV2 } from './v2'\nimport { Fetch } from './fetch'\n\nexport * from './options'\nexport * from './handler'\n\nexport class Api extends ApiV2<void> {\n  private _opts: ApiOptions\n\n  constructor(opts: ApiOptions) {\n    super({\n      baseUrl: opts.baseURL,\n      customFetch: (input, init) => Fetch(opts, input, init),\n    })\n\n    this._opts = opts\n  }\n\n  /**\n   * Get user info as params for request\n   *\n   * @returns Request params with user info\n   */\n  getUserFields() {\n    const user = this._opts.userInfo\n    if (!user?.name || !user?.email) return undefined\n    return { name: user.name, email: user.email }\n  }\n}\n","import type PlugKit from './_kit'\nimport type { CommentData, EditorState } from '@/types'\nimport * as Utils from '@/lib/utils'\n\n/**\n * Editor 插件\n */\nexport class EditorPlugin {\n  $btn?: HTMLElement\n  $panel?: HTMLElement\n  contentTransformer?(rawContent: string): string\n  editorStateEffectWhen?: EditorState\n  editorStateEffect?(comment: CommentData): () => void\n\n  constructor(protected kit: PlugKit) {}\n\n  /** Use plug btn will add a btn on the bottom of editor */\n  useBtn(html: string = '<div></div>') {\n    this.$btn = Utils.createElement(`<span class=\"atk-plug-btn\">${html}</span>`)\n    return this.$btn\n  }\n\n  /** Use plug panel will show the panel when btn is clicked */\n  usePanel(html: string = '<div></div>') {\n    this.$panel = Utils.createElement(html)\n    return this.$panel\n  }\n\n  /** Use the content transformer to handle the content of the last submit by the editor */\n  useContentTransformer(func: (raw: string) => string) {\n    this.contentTransformer = func\n  }\n\n  /** Listen the event of panel show */\n  usePanelShow(func: () => void) {\n    this.kit.useEvents().on('panel-show', (aPlug) => {\n      if (aPlug === this) func()\n    })\n  }\n\n  /** Listen the event of panel hide */\n  usePanelHide(func: () => void) {\n    this.kit.useEvents().on('panel-hide', (aPlug) => {\n      if (aPlug === this) func()\n    })\n  }\n\n  /** Use editor state modifier */\n  useEditorStateEffect(stateName: EditorState, effectFn: (comment: CommentData) => () => void) {\n    this.editorStateEffectWhen = stateName\n    this.editorStateEffect = effectFn\n  }\n}\n\nexport default EditorPlugin\n","import type PlugKit from './_kit'\nimport EditorPlugin from './_plug'\nimport $t from '@/i18n'\n\nconst LocalStorageKey = 'ArtalkContent'\n\nexport default class LocalStorage extends EditorPlugin {\n  constructor(kit: PlugKit) {\n    super(kit)\n\n    const onContentUpdated = () => {\n      this.save()\n    }\n\n    this.kit.useMounted(() => {\n      // load editor content from localStorage when init\n      const localContent = window.localStorage.getItem(LocalStorageKey) || ''\n      if (localContent.trim() !== '') {\n        this.kit.useEditor().showNotify($t('restoredMsg'), 'i')\n        this.kit.useEditor().setContent(localContent)\n      }\n\n      // bind event\n      this.kit.useEvents().on('content-updated', onContentUpdated)\n    })\n\n    this.kit.useUnmounted(() => {\n      this.kit.useEvents().off('content-updated', onContentUpdated)\n    })\n  }\n\n  // Save editor content to localStorage\n  public save() {\n    window.localStorage.setItem(LocalStorageKey, this.kit.useEditor().getContentRaw().trim())\n  }\n}\n","import type PlugKit from './_kit'\nimport type { CommentData } from '@/types'\nimport * as Utils from '@/lib/utils'\n\nexport default class SubmitAddPreset {\n  constructor(private kit: PlugKit) {}\n\n  async reqAdd() {\n    const nComment = (\n      await this.kit.useApi().comments.createComment({\n        ...(await this.getSubmitAddParams()),\n      })\n    ).data\n    return nComment\n  }\n\n  async getSubmitAddParams() {\n    const { name, email, link } = this.kit.useUser().getData()\n    const conf = this.kit.useConf()\n\n    return {\n      content: this.kit.useEditor().getContentFinal(),\n      name,\n      email,\n      link,\n      rid: 0,\n      page_key: conf.pageKey,\n      page_title: conf.pageTitle,\n      site_name: conf.site,\n      ua: await Utils.getCorrectUserAgent(), // Get the corrected UA\n    }\n  }\n\n  postSubmitAdd(commentNew: CommentData) {\n    // insert the new comment to list\n    this.kit.useData().insertComment(commentNew)\n  }\n}\n","import EditorPlugin from './_plug'\nimport type PlugKit from './_kit'\nimport SubmitAddPreset from './submit-add'\nimport $t from '@/i18n'\nimport type { CommentData } from '@/types'\n\ninterface CustomSubmit {\n  activeCond: () => void\n  pre?: () => void\n  req?: () => Promise<CommentData>\n  /** The `post` method is called after the comment is successfully submitted */\n  post?: (nComment: CommentData) => void\n}\n\nexport default class Submit extends EditorPlugin {\n  private customs: CustomSubmit[] = []\n  private defaultPreset: SubmitAddPreset\n\n  constructor(kit: PlugKit) {\n    super(kit)\n\n    this.defaultPreset = new SubmitAddPreset(this.kit)\n\n    const onEditorSubmit = () => this.do()\n\n    this.kit.useMounted(() => {\n      // invoke `do()` when event `editor-submit` is triggered\n      this.kit.useEvents().on('editor-submit', onEditorSubmit)\n    })\n    this.kit.useUnmounted(() => {\n      this.kit.useEvents().off('editor-submit', onEditorSubmit)\n    })\n  }\n\n  registerCustom(c: CustomSubmit) {\n    this.customs.push(c)\n  }\n\n  private async do() {\n    if (this.kit.useEditor().getContentFinal().trim() === '') {\n      this.kit.useEditor().focus()\n      return\n    }\n\n    const custom = this.customs.find((o) => o.activeCond())\n\n    this.kit.useEditor().showLoading()\n\n    try {\n      // pre submit\n      if (custom?.pre) custom.pre()\n\n      let nComment: CommentData\n\n      // submit request\n      if (custom?.req) nComment = await custom.req()\n      else nComment = await this.defaultPreset.reqAdd()\n\n      // post submit\n      if (custom?.post) custom.post(nComment)\n      else this.defaultPreset.postSubmitAdd(nComment)\n    } catch (err: any) {\n      // submit error\n      console.error(err)\n      this.kit.useEditor().showNotify(`${$t('commentFail')}: ${err.message || String(err)}`, 'e')\n      return\n    } finally {\n      this.kit.useEditor().hideLoading()\n    }\n\n    this.kit.useEditor().reset() // 复原编辑器\n    this.kit.useEvents().trigger('editor-submitted')\n  }\n}\n","import EditorPlugin from './_plug'\nimport * as Utils from '@/lib/utils'\n\nexport default class Mover extends EditorPlugin {\n  private isMoved = false\n\n  move(afterEl: HTMLElement) {\n    if (this.isMoved) return\n    this.isMoved = true\n\n    const editorEl = this.kit.useUI().$el\n\n    editorEl.after(Utils.createElement('<div class=\"atk-editor-travel-placeholder\"></div>'))\n\n    const $travelPlace = Utils.createElement('<div></div>')\n    afterEl.after($travelPlace)\n    $travelPlace.replaceWith(editorEl)\n\n    editorEl.classList.add('atk-fade-in') // 添加渐入动画\n    editorEl.classList.add('editor-traveling')\n  }\n\n  back() {\n    if (!this.isMoved) return\n    this.isMoved = false\n    this.kit\n      .useArtalkRootEl()\n      .querySelector('.atk-editor-travel-placeholder')\n      ?.replaceWith(this.kit.useUI().$el)\n    this.kit.useUI().$el.classList.remove('editor-traveling')\n  }\n}\n","import * as Utils from './utils'\nimport type { NotifyLevel } from '@/types'\n\n/** 显示加载 */\nexport function showLoading(parentElem: HTMLElement, conf?: { transparentBg?: boolean }) {\n  // Use :scope https://developer.mozilla.org/en-US/docs/Web/CSS/:scope\n  let $loading = parentElem.querySelector<HTMLElement>(':scope > .atk-loading')\n  if (!$loading) {\n    $loading = Utils.createElement(\n      `<div class=\"atk-loading\" style=\"display: none;\">\n      <div class=\"atk-loading-spinner\">\n        <svg viewBox=\"25 25 50 50\"><circle cx=\"50\" cy=\"50\" r=\"20\" fill=\"none\" stroke-width=\"2\" stroke-miterlimit=\"10\"></circle></svg>\n      </div>\n    </div>`,\n    )\n    if (conf?.transparentBg) $loading.style.background = 'transparent'\n    parentElem.appendChild($loading)\n  }\n  $loading.style.display = ''\n\n  // spinner 延迟显示，若加载等待时间太短，没必要显示（闪一下即可）\n  const $spinner = $loading.querySelector<HTMLElement>('.atk-loading-spinner')\n  if ($spinner) {\n    $spinner.style.display = 'none'\n    window.setTimeout(() => {\n      if ($spinner.isConnected) $spinner.style.display = ''\n    }, 500)\n  }\n}\n\n/** 隐藏加载 */\nexport function hideLoading(parentElem: HTMLElement) {\n  const $loading = parentElem.querySelector<HTMLElement>(':scope > .atk-loading')\n  if ($loading) $loading.style.display = 'none'\n}\n\n/** 元素加载动画 */\nexport function setLoading(val: boolean, parentElem: HTMLElement) {\n  if (val) showLoading(parentElem)\n  else hideLoading(parentElem)\n}\n\n/** 元素是否用户可见 */\nexport function isVisible(el: HTMLElement, viewport: HTMLElement = document.documentElement) {\n  const viewportHeight = viewport.clientHeight\n\n  const docViewTop = viewport.scrollTop\n  const docViewBottom = docViewTop + viewportHeight\n\n  const rect = el.getBoundingClientRect()\n  const elemTop = rect.top + docViewTop\n  const elemBottom = elemTop + rect.height\n\n  return elemBottom <= docViewBottom //&& (elemTop >= docViewTop) 注释因为假如 el 比 viewport 还高就会失效\n}\n\n/** 滚动到元素中心 */\nexport function scrollIntoView(\n  elem: HTMLElement,\n  enableAnim: boolean = true,\n  relativeTo?: HTMLElement,\n) {\n  let top: number\n\n  if (relativeTo) {\n    const containerRect = relativeTo.getBoundingClientRect()\n    const elementRect = elem.getBoundingClientRect()\n    top =\n      elementRect.top -\n      containerRect.top +\n      relativeTo.scrollTop -\n      relativeTo.clientHeight / 2 +\n      elem.clientHeight / 2\n  } else {\n    const rect = elem.getBoundingClientRect()\n    const elemTop = rect.top + window.scrollY\n    top = elemTop - (window.innerHeight / 2 - rect.height / 2)\n  }\n\n  const scrollOptions: ScrollToOptions = {\n    top,\n    left: 0,\n    // behavior: enableAnim ? 'smooth' : 'instant',\n    behavior: 'instant',\n  }\n\n  if (relativeTo) relativeTo.scroll(scrollOptions)\n  else window.scroll(scrollOptions)\n}\n\n/** 显示消息 */\nexport function showNotify(wrapElem: HTMLElement, msg: string, type: NotifyLevel) {\n  const colors = { s: '#57d59f', e: '#ff6f6c', w: '#ffc721', i: '#2ebcfc' }\n  const timeout = 3000 // 持续显示时间 ms\n\n  const notifyElem = Utils.createElement(\n    `<div class=\"atk-notify atk-fade-in\" style=\"background-color: ${colors[type]}\"><span class=\"atk-notify-content\"></span></div>`,\n  )\n  const notifyContentEl = notifyElem.querySelector<HTMLElement>('.atk-notify-content')!\n  notifyContentEl.innerHTML = Utils.htmlEncode(msg).replace('\\n', '<br/>')\n\n  wrapElem.appendChild(notifyElem)\n\n  const notifyRemove = () => {\n    notifyElem.classList.add('atk-fade-out')\n    setTimeout(() => {\n      notifyElem.remove()\n    }, 200)\n  }\n\n  let timeoutFn: number\n  if (timeout > 0) {\n    timeoutFn = window.setTimeout(() => {\n      notifyRemove()\n    }, timeout)\n  }\n\n  notifyElem.addEventListener('click', () => {\n    notifyRemove()\n    window.clearTimeout(timeoutFn)\n  })\n}\n\n/** fade 动画 */\nexport function playFadeAnim(elem: HTMLElement, after?: () => void, type: 'in' | 'out' = 'in') {\n  elem.classList.add(`atk-fade-${type}`)\n  // 动画结束清除 class\n  const onAnimEnded = () => {\n    elem.classList.remove(`atk-fade-${type}`)\n    elem.removeEventListener('animationend', onAnimEnded)\n    if (after) after()\n  }\n  elem.addEventListener('animationend', onAnimEnded)\n}\n\n/** 渐入动画 */\nexport function playFadeInAnim(elem: HTMLElement, after?: () => void) {\n  playFadeAnim(elem, after, 'in')\n}\n\n/** 渐出动画 */\nexport function playFadeOutAnim(elem: HTMLElement, after?: () => void) {\n  playFadeAnim(elem, after, 'out')\n}\n\n/** 设置全局错误 */\nexport function setError(\n  parentElem: HTMLElement,\n  html: string | HTMLElement | null,\n  title: string = '<span class=\"atk-error-title\">Artalk Error</span>',\n) {\n  let elem = parentElem.querySelector<HTMLElement>('.atk-error-layer')\n  if (html === null) {\n    if (elem !== null) elem.remove()\n    return\n  }\n  if (!elem) {\n    elem = Utils.createElement(\n      `<div class=\"atk-error-layer\">${title}<span class=\"atk-error-text\"></span></div>`,\n    )\n    parentElem.appendChild(elem)\n  }\n\n  const errorTextEl = elem.querySelector<HTMLElement>('.atk-error-text')!\n  errorTextEl.innerHTML = ''\n  if (html === null) return\n\n  if (html instanceof HTMLElement) {\n    errorTextEl.appendChild(html)\n  } else {\n    errorTextEl.innerText = html\n  }\n}\n\nexport function getScrollBarWidth() {\n  const inner = document.createElement('p')\n  inner.style.width = '100%'\n  inner.style.height = '200px'\n\n  const outer = document.createElement('div')\n  outer.style.position = 'absolute'\n  outer.style.top = '0px'\n  outer.style.left = '0px'\n  outer.style.visibility = 'hidden'\n  outer.style.width = '200px'\n  outer.style.height = '150px'\n  outer.style.overflow = 'hidden'\n  outer.appendChild(inner)\n\n  document.body.appendChild(outer)\n  const w1 = inner.offsetWidth\n  outer.style.overflow = 'scroll'\n  let w2 = inner.offsetWidth\n  if (w1 === w2) w2 = outer.clientWidth\n\n  document.body.removeChild(outer)\n\n  return w1 - w2\n}\n","import './emoticons.scss'\n\nimport EditorPlugin from './_plug'\nimport type PlugKit from './_kit'\nimport type { EmoticonListData, EmoticonGrpData } from '@/types'\nimport * as Utils from '@/lib/utils'\nimport * as Ui from '@/lib/ui'\nimport $t from '@/i18n'\n\ntype OwOFormatType = {\n  [key: string]: {\n    type: 'emoticon' | 'emoji' | 'image'\n    container: { icon: string; text: string }[]\n  }\n}\n\nexport default class Emoticons extends EditorPlugin {\n  private emoticons: EmoticonListData = []\n  private loadingTask: Promise<void> | null = null\n\n  private $grpWrap!: HTMLElement\n  private $grpSwitcher!: HTMLElement\n\n  constructor(kit: PlugKit) {\n    super(kit)\n\n    this.kit.useMounted(() => {\n      this.usePanel(`<div class=\"atk-editor-plug-emoticons\"></div>`)\n      this.useBtn(\n        `<i aria-label=\"${$t('emoticon')}\"><svg fill=\"currentColor\" aria-hidden=\"true\" height=\"14\" viewBox=\"0 0 14 14\" width=\"14\"><path d=\"m4.26829 5.29294c0-.94317.45893-1.7074 1.02439-1.7074.56547 0 1.02439.76423 1.02439 1.7074s-.45892 1.7074-1.02439 1.7074c-.56546 0-1.02439-.76423-1.02439-1.7074zm4.43903 1.7074c.56546 0 1.02439-.76423 1.02439-1.7074s-.45893-1.7074-1.02439-1.7074c-.56547 0-1.02439.76423-1.02439 1.7074s.45892 1.7074 1.02439 1.7074zm-1.70732 2.73184c-1.51883 0-2.06312-1.52095-2.08361-1.58173l-1.29551.43231c.03414.10244.868 2.51604 3.3798 2.51604 2.51181 0 3.34502-2.41291 3.37982-2.51604l-1.29484-.43573c-.02254.06488-.56683 1.58583-2.08498 1.58583zm7-2.73252c0 3.86004-3.1401 7.00034-7 7.00034s-7-3.1396-7-6.99966c0-3.86009 3.1401-7.00034 7-7.00034s7 3.14025 7 7.00034zm-1.3659 0c0-3.10679-2.5275-5.63442-5.6341-5.63442-3.10663 0-5.63415 2.52832-5.63415 5.6351 0 3.10676 2.52752 5.63446 5.63415 5.63446 3.1066 0 5.6341-2.5277 5.6341-5.63446z\"/></svg></i>`,\n      )\n    })\n    this.kit.useUnmounted(() => {})\n\n    this.useContentTransformer((raw) => this.transEmoticonImageText(raw))\n    this.usePanelShow(() => {\n      ;(async () => {\n        await this.loadEmoticonsData()\n\n        // 初始化元素\n        if (!this.isImgLoaded) {\n          this.initEmoticonsList()\n          this.isImgLoaded = true\n        }\n\n        // 延迟执行，防止无法读取高度\n        setTimeout(() => {\n          this.changeListHeight()\n        }, 30)\n      })()\n    })\n    this.usePanelHide(() => {\n      this.$panel!.parentElement!.style.height = ''\n    })\n\n    // 表情包预加载\n    window.setTimeout(() => {\n      this.loadEmoticonsData()\n    }, 1000) // 延迟 1s 加载\n  }\n\n  private isListLoaded = false\n  private isImgLoaded = false\n\n  public async loadEmoticonsData() {\n    if (this.isListLoaded) return\n    if (this.loadingTask !== null) {\n      await this.loadingTask\n      return\n    }\n\n    // 数据处理\n    this.loadingTask = (async () => {\n      Ui.showLoading(this.$panel!)\n      this.emoticons = await this.handleData(this.kit.useConf().emoticons)\n      Ui.hideLoading(this.$panel!)\n      this.loadingTask = null\n      this.isListLoaded = true\n    })()\n    await this.loadingTask\n  }\n\n  private async handleData(data: any): Promise<any[]> {\n    if (!Array.isArray(data) && ['object', 'string'].includes(typeof data)) {\n      data = [data]\n    }\n\n    if (!Array.isArray(data)) {\n      Ui.setError(this.$panel!, `[${$t('emoticon')}] Data must be of Array/Object/String type`)\n      Ui.hideLoading(this.$panel!)\n      return []\n    }\n\n    const pushGrp = (grp: EmoticonGrpData) => {\n      if (typeof grp !== 'object') return\n      if (grp.name && data.find((o) => o.name === grp.name)) return\n      data.push(grp)\n    }\n\n    // 加载子内容\n    const remoteLoad = async (d: any[]) => {\n      await Promise.all(\n        d.map(async (grp, index) => {\n          if (typeof grp === 'object' && !Array.isArray(grp)) {\n            pushGrp(grp)\n          } else if (Array.isArray(grp)) {\n            await remoteLoad(grp)\n          } else if (typeof grp === 'string') {\n            const grpData = await this.remoteLoad(grp)\n\n            if (Array.isArray(grpData)) await remoteLoad(grpData)\n            else if (typeof grpData === 'object') pushGrp(grpData)\n          }\n        }),\n      )\n    }\n    await remoteLoad(data)\n\n    // 处理数组数据\n    data.forEach((item: any) => {\n      if (this.isOwOFormat(item)) {\n        const c = this.convertOwO(item)\n        c.forEach((grp) => {\n          pushGrp(grp)\n        })\n      } else if (Array.isArray(item)) {\n        item.forEach((grp) => {\n          pushGrp(grp)\n        })\n      }\n    })\n\n    // 剔除非法数据\n    data = data.filter(\n      (item: any) => typeof item === 'object' && !Array.isArray(item) && !!item && !!item.name,\n    )\n\n    // console.log(data)\n\n    this.solveNullKey(data)\n    this.solveSameKey(data)\n\n    return data\n  }\n\n  /** 远程加载 */\n  private async remoteLoad(url: string): Promise<any> {\n    if (!url) return []\n\n    try {\n      const resp = await fetch(url)\n      const json = await resp.json()\n      return json\n    } catch (err) {\n      Ui.hideLoading(this.$panel!)\n      console.error('[Emoticons] Load Failed:', err)\n      Ui.setError(this.$panel!, `[${$t('emoticon')}] ${$t('loadFail')}: ${String(err)}`)\n      return []\n    }\n  }\n\n  /** 避免表情 item.key 为 null 的情况 */\n  private solveNullKey(data: EmoticonGrpData[]) {\n    data.forEach((grp) => {\n      grp.items.forEach((item, index) => {\n        if (!item.key) item.key = `${grp.name} ${index + 1}`\n      })\n    })\n  }\n\n  /** 避免相同 item.key */\n  private solveSameKey(data: EmoticonGrpData[]) {\n    const tmp: { [key: string]: number } = {}\n    data.forEach((grp) => {\n      grp.items.forEach((item) => {\n        if (!item.key || String(item.key).trim() === '') return\n        if (!tmp[item.key]) tmp[item.key] = 1\n        else tmp[item.key]++\n\n        if (tmp[item.key] > 1) item.key = `${item.key} ${tmp[item.key]}`\n      })\n    })\n  }\n\n  /** 判断是否为 OwO 格式 */\n  private isOwOFormat(data: any) {\n    try {\n      return (\n        typeof data === 'object' &&\n        !!Object.values(data).length &&\n        Array.isArray(Object.keys(Object.values<any>(data)[0].container)) &&\n        Object.keys(Object.values<any>(data)[0].container[0]).includes('icon')\n      )\n    } catch {\n      return false\n    }\n  }\n\n  /** 转换 OwO 格式数据 */\n  private convertOwO(owoData: OwOFormatType): EmoticonListData {\n    const dest: EmoticonListData = []\n    Object.entries(owoData).forEach(([grpName, grp]) => {\n      const nGrp: EmoticonGrpData = { name: grpName, type: grp.type, items: [] }\n      grp.container.forEach((item, index) => {\n        // 图片标签提取 src 属性值\n        const iconStr = item.icon\n        if (/<(img|IMG)/.test(iconStr)) {\n          const find = /src=[\"'](.*?)[\"']/.exec(iconStr)\n          if (find && find.length > 1) item.icon = find[1]\n        }\n        nGrp.items.push({\n          key: item.text || `${grpName} ${index + 1}`,\n          val: item.icon,\n        })\n      })\n      dest.push(nGrp)\n    })\n    return dest\n  }\n\n  /** 初始化表情列表界面 */\n  private initEmoticonsList() {\n    // 表情列表\n    this.$grpWrap = Utils.createElement(`<div class=\"atk-grp-wrap\"></div>`)\n    this.$panel!.append(this.$grpWrap)\n\n    this.emoticons.forEach((grp, index) => {\n      const $grp = Utils.createElement(`<div class=\"atk-grp\" style=\"display: none;\"></div>`)\n      this.$grpWrap.append($grp)\n      $grp.setAttribute('data-index', String(index))\n      $grp.setAttribute('data-grp-name', grp.name)\n      $grp.setAttribute('data-type', grp.type)\n      grp.items.forEach((item) => {\n        const $item = Utils.createElement(`<span class=\"atk-item\"></span>`)\n        $grp.append($item)\n\n        if (!!item.key && !new RegExp(`^(${grp.name})?\\\\s?[0-9]+$`).test(item.key))\n          $item.setAttribute('title', item.key)\n\n        if (grp.type === 'image') {\n          const imgEl = document.createElement('img')\n          imgEl.src = item.val\n          imgEl.alt = item.key\n          $item.append(imgEl)\n        } else {\n          $item.innerText = item.val\n        }\n\n        $item.onclick = () => {\n          if (grp.type === 'image') {\n            this.kit.useEditor().insertContent(`:[${item.key}]`)\n          } else {\n            this.kit.useEditor().insertContent(item.val || '')\n          }\n        }\n      })\n    })\n\n    // 表情分类切换 bar\n    if (this.emoticons.length > 1) {\n      this.$grpSwitcher = Utils.createElement(`<div class=\"atk-grp-switcher\"></div>`)\n      this.$panel!.append(this.$grpSwitcher)\n      this.emoticons.forEach((grp, index) => {\n        const $item = Utils.createElement('<span />')\n        $item.innerText = grp.name\n        $item.setAttribute('data-index', String(index))\n        $item.onclick = () => this.openGrp(index)\n        this.$grpSwitcher.append($item)\n      })\n    }\n\n    // 默认打开第一个分类\n    if (this.emoticons.length > 0) this.openGrp(0)\n  }\n\n  /** 打开一个表情组 */\n  public openGrp(index: number) {\n    Array.from(this.$grpWrap.children).forEach((item) => {\n      const el = item as HTMLElement\n      if (el.getAttribute('data-index') !== String(index)) {\n        el.style.display = 'none'\n      } else {\n        el.style.display = ''\n      }\n    })\n\n    this.$grpSwitcher\n      ?.querySelectorAll('span.active')\n      .forEach((item) => item.classList.remove('active'))\n    this.$grpSwitcher?.querySelector(`span[data-index=\"${index}\"]`)?.classList.add('active')\n\n    this.changeListHeight()\n  }\n\n  private changeListHeight() {\n    /* const listWrapHeight = Utils.getHeight(this.$grpWrapem)\n    this.editor.plugWrapEl.style.height = `${listWrapHeight > 150 ? listWrapHeight : 150}px` */\n  }\n\n  /** 处理评论 content 中的表情内容 */\n  public transEmoticonImageText(text: string) {\n    if (!this.emoticons || !Array.isArray(this.emoticons)) return text\n\n    this.emoticons.forEach((grp) => {\n      if (grp.type !== 'image') return\n      Object.entries(grp.items).forEach(([index, item]) => {\n        text = text\n          .split(`:[${item.key}]`)\n          .join(`<img src=\"${item.val}\" atk-emoticon=\"${item.key}\">`) // replaceAll(...)\n      })\n    })\n\n    return text\n  }\n}\n","import type PlugKit from './_kit'\nimport EditorPlugin from './_plug'\nimport * as Utils from '@/lib/utils'\nimport $t from '@/i18n'\n\n/** 允许的图片格式 */\nconst AllowImgExts = ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'svg', 'webp']\n\nexport default class Upload extends EditorPlugin {\n  private $imgUploadInput?: HTMLInputElement\n\n  constructor(kit: PlugKit) {\n    super(kit)\n\n    this.kit.useMounted(() => this.init())\n\n    this.initDragImg()\n  }\n\n  private init() {\n    this.$imgUploadInput = document.createElement('input')\n    this.$imgUploadInput.type = 'file'\n    this.$imgUploadInput.style.display = 'none'\n    this.$imgUploadInput.accept = AllowImgExts.map((o) => `.${o}`).join(',')\n\n    // TODO: Use btn cannot refresh when mounted event is triggered\n    const $btn = this.useBtn(\n      `<i aria-label=\"${$t('uploadImage')}\"><svg fill=\"currentColor\" aria-hidden=\"true\" height=\"14\" viewBox=\"0 0 14 14\" width=\"14\"><path d=\"m0 1.94444c0-1.074107.870333-1.94444 1.94444-1.94444h10.11116c1.0741 0 1.9444.870333 1.9444 1.94444v10.11116c0 1.0741-.8703 1.9444-1.9444 1.9444h-10.11116c-1.074107 0-1.94444-.8703-1.94444-1.9444zm1.94444-.38888c-.21466 0-.38888.17422-.38888.38888v7.06689l2.33333-2.33333 2.33333 2.33333 3.88888-3.88889 2.3333 2.33334v-5.51134c0-.21466-.1742-.38888-.3888-.38888zm10.49996 8.09977-2.3333-2.33333-3.88888 3.8889-2.33333-2.33334-2.33333 2.33334v.8447c0 .2146.17422.3888.38888.3888h10.11116c.2146 0 .3888-.1742.3888-.3888zm-7.1944-6.54422c-.75133 0-1.36111.60978-1.36111 1.36111 0 .75134.60978 1.36111 1.36111 1.36111s1.36111-.60977 1.36111-1.36111c0-.75133-.60978-1.36111-1.36111-1.36111z\"/></svg></i>`,\n    )\n    $btn.after(this.$imgUploadInput)\n    $btn.onclick = () => {\n      // 选择图片\n      const $input = this.$imgUploadInput!\n      $input.onchange = () => {\n        ;(async () => {\n          // 解决阻塞 UI 问题\n          if (!$input.files || $input.files.length === 0) return\n          const file = $input.files[0]\n          this.uploadImg(file)\n        })()\n      }\n      $input.click() // 显示选择图片对话框\n    }\n\n    if (!this.kit.useConf().imgUpload) {\n      this.$btn!.setAttribute('atk-only-admin-show', '')\n    }\n  }\n\n  private initDragImg() {\n    // 统一从 FileList 获取文件并上传图片方法\n    const uploadFromFileList = (files?: FileList) => {\n      if (!files) return\n\n      for (let i = 0; i < files.length; i++) {\n        const file = files[i]\n        this.uploadImg(file)\n      }\n    }\n\n    // 拖拽图片\n    // @link https://developer.mozilla.org/zh-CN/docs/Web/API/HTML_Drag_and_Drop_API/File_drag_and_drop\n    // 阻止浏览器的默认释放行为\n    const onDragover = (evt: Event) => {\n      evt.stopPropagation()\n      evt.preventDefault()\n    }\n\n    const onDrop = (evt: DragEvent) => {\n      const files = evt.dataTransfer?.files\n      if (files?.length) {\n        evt.preventDefault()\n        uploadFromFileList(files)\n      }\n    }\n\n    // 粘贴图片\n    const onPaste = (evt: ClipboardEvent) => {\n      const files = evt.clipboardData?.files\n      if (files?.length) {\n        evt.preventDefault()\n        uploadFromFileList(files)\n      }\n    }\n\n    this.kit.useMounted(() => {\n      this.kit.useUI().$textarea.addEventListener('dragover', onDragover)\n      this.kit.useUI().$textarea.addEventListener('drop', onDrop)\n      this.kit.useUI().$textarea.addEventListener('paste', onPaste)\n    })\n    this.kit.useUnmounted(() => {\n      this.kit.useUI().$textarea.removeEventListener('dragover', onDragover)\n      this.kit.useUI().$textarea.removeEventListener('drop', onDrop)\n      this.kit.useUI().$textarea.removeEventListener('paste', onPaste)\n    })\n  }\n\n  async uploadImg(file: File) {\n    const fileExt = /[^.]+$/.exec(file.name)\n    if (!fileExt || !AllowImgExts.includes(String(fileExt[0]).toLowerCase())) return\n\n    // 未登录提示\n    if (!this.kit.useUser().checkHasBasicUserInfo()) {\n      this.kit.useEditor().showNotify($t('uploadLoginMsg'), 'w')\n      return\n    }\n\n    // 插入图片前换一行\n    let insertPrefix = '\\n'\n    if (this.kit.useUI().$textarea.value.trim() === '') insertPrefix = ''\n\n    // 插入占位加载文字\n    const uploadPlaceholderTxt = `${insertPrefix}![](Uploading ${file.name}...)`\n    this.kit.useEditor().insertContent(uploadPlaceholderTxt)\n\n    // 上传图片\n    let resp: { public_url: string } | undefined\n    try {\n      const customUploaderFn = this.kit.useConf().imgUploader\n      if (!customUploaderFn) {\n        // 使用 Artalk 进行图片上传\n        resp = (await this.kit.useApi().upload.upload({ file })).data\n      } else {\n        // 使用自定义的图片上传器\n        resp = { public_url: await customUploaderFn(file) }\n      }\n    } catch (err: any) {\n      console.error(err)\n      this.kit.useEditor().showNotify(`${$t('uploadFail')}: ${err.message}`, 'e')\n    }\n    if (!!resp && resp.public_url) {\n      let imgURL = resp.public_url as string\n\n      // 若为相对路径，加上 artalk server\n      if (!Utils.isValidURL(imgURL))\n        imgURL = Utils.getURLBasedOnApi({\n          base: this.kit.useConf().server,\n          path: imgURL,\n        })\n\n      // 上传成功插入图片\n      this.kit\n        .useEditor()\n        .setContent(\n          this.kit\n            .useUI()\n            .$textarea.value.replace(uploadPlaceholderTxt, `${insertPrefix}![](${imgURL})`),\n        )\n    } else {\n      // 上传失败删除加载文字\n      this.kit\n        .useEditor()\n        .setContent(this.kit.useUI().$textarea.value.replace(uploadPlaceholderTxt, ''))\n    }\n  }\n}\n","import './preview.scss'\n\nimport EditorPlugin from './_plug'\nimport type PlugKit from './_kit'\nimport $t from '@/i18n'\n\nexport default class Preview extends EditorPlugin {\n  private isPlugPanelShow = false\n\n  constructor(kit: PlugKit) {\n    super(kit)\n\n    this.kit.useMounted(() => {\n      this.usePanel(`<div class=\"atk-editor-plug-preview\"></div>`)\n\n      // initialize plug button\n      this.useBtn(\n        `<i aria-label=\"${$t('preview')}\"><svg fill=\"currentColor\" aria-hidden=\"true\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\"><path fill-rule=\"evenodd\" d=\"M14.85 3H1.15C.52 3 0 3.52 0 4.15v7.69C0 12.48.52 13 1.15 13h13.69c.64 0 1.15-.52 1.15-1.15v-7.7C16 3.52 15.48 3 14.85 3zM9 11H7V8L5.5 9.92 4 8v3H2V5h2l1.5 2L7 5h2v6zm2.99.5L9.5 8H11V5h2v3h1.5l-2.51 3.5z\"></path></svg></i>`,\n      )\n    })\n    this.kit.useUnmounted(() => {})\n\n    // function to update content\n    this.kit.useEvents().on('content-updated', (content) => {\n      this.isPlugPanelShow && this.updateContent()\n    })\n\n    this.usePanelShow(() => {\n      this.isPlugPanelShow = true\n      this.updateContent()\n    })\n    this.usePanelHide(() => {\n      this.isPlugPanelShow = false\n    })\n  }\n\n  updateContent() {\n    this.$panel!.innerHTML = this.kit.useEditor().getContentMarked()\n  }\n}\n","import type EditorPlugin from './_plug'\nimport LocalStorage from './local-storage'\nimport Textarea from './textarea'\nimport SubmitBtn from './submit-btn'\nimport Submit from './submit'\nimport StateReply from './state-reply'\nimport StateEdit from './state-edit'\nimport Closable from './closable'\nimport HeaderEvent from './header-event'\nimport HeaderUser from './header-user'\nimport HeaderLink from './header-link'\nimport Mover from './mover'\nimport Emoticons from './emoticons'\nimport Upload from './upload'\nimport Preview from './preview'\nimport type { Config } from '@/types'\n\n/** The default enabled plugs */\nconst EDITOR_PLUGS: (typeof EditorPlugin)[] = [\n  // Core\n  LocalStorage,\n  HeaderEvent,\n  HeaderUser,\n  HeaderLink,\n  Textarea,\n  Submit,\n  SubmitBtn,\n  Mover,\n  StateReply,\n  StateEdit,\n  Closable,\n\n  // Extensions\n  Emoticons,\n  Upload,\n  Preview,\n]\n\n/**\n * Get the enabled plugs by config\n */\nexport function getEnabledPlugs(\n  conf: Pick<Config, 'imgUpload' | 'emoticons' | 'preview' | 'editorTravel'>,\n): (typeof EditorPlugin)[] {\n  // The reference map of config and plugs\n  // (for check if the plug is enabled)\n  const confRefs = new Map<typeof EditorPlugin, any>()\n  confRefs.set(Upload, conf.imgUpload)\n  confRefs.set(Emoticons, conf.emoticons)\n  confRefs.set(Preview, conf.preview)\n  confRefs.set(Mover, conf.editorTravel)\n\n  return EDITOR_PLUGS.filter((p) => !confRefs.has(p) || !!confRefs.get(p))\n}\n","import EditorPlugin from './_plug'\nimport type PlugKit from './_kit'\n\nexport default class HeaderEvent extends EditorPlugin {\n  private get $inputs() {\n    return this.kit.useEditor().getHeaderInputEls()\n  }\n\n  constructor(kit: PlugKit) {\n    super(kit)\n\n    const inputEventFns: { [name: string]: () => void } = {}\n    const changeEventFns: { [name: string]: () => void } = {}\n\n    const trigger =\n      (evt: 'header-input' | 'header-change', $input: HTMLInputElement, field: string) => () => {\n        this.kit.useEvents().trigger(evt, { field, $input })\n      }\n\n    this.kit.useMounted(() => {\n      // batch bind the events\n      Object.entries(this.$inputs).forEach(([key, $input]) => {\n        $input.addEventListener(\n          'input',\n          (inputEventFns[key] = trigger('header-input', $input, key)),\n        )\n        $input.addEventListener(\n          'change',\n          (changeEventFns[key] = trigger('header-change', $input, key)),\n        )\n      })\n    })\n\n    this.kit.useUnmounted(() => {\n      // unmount the event\n      Object.entries(this.$inputs).forEach(([key, $input]) => {\n        $input.removeEventListener('input', inputEventFns[key])\n        $input.removeEventListener('change', changeEventFns[key])\n      })\n    })\n  }\n}\n","import EditorPlugin from './_plug'\nimport type PlugKit from './_kit'\nimport $t from '@/i18n'\nimport type { UserInfoApiResponseData } from '@/types'\n\nexport default class HeaderUser extends EditorPlugin {\n  constructor(kit: PlugKit) {\n    super(kit)\n\n    const onInput = ({ $input, field }: { $input: HTMLInputElement; field: string }) => {\n      if (this.kit.useEditor().getState() === 'edit') return // TODO: prevent execute when editing, since update comment.user not support\n\n      // update user data\n      this.kit.useUser().update({ [field]: $input.value.trim() })\n\n      // remote fetch user info\n      if (field === 'name' || field === 'email') this.fetchUserInfo() // must after update user data, since fetchUserInfo() will use User.data\n    }\n\n    const placeholders = {\n      name: $t('nick'),\n      email: $t('email'),\n      link: $t('link'),\n    }\n\n    this.kit.useMounted(() => {\n      Object.entries(this.kit.useEditor().getHeaderInputEls()).forEach(([key, $input]) => {\n        // set placeholder\n        $input.placeholder = placeholders[key]\n\n        // sync header values from User.data\n        $input.value = this.kit.useUser().getData()[key] || ''\n      })\n\n      // bind events\n      this.kit.useEvents().on('header-input', onInput)\n    })\n\n    this.kit.useUnmounted(() => {\n      this.kit.useEvents().off('header-input', onInput)\n    })\n  }\n\n  private query = {\n    timer: <number | null>null,\n    abortFn: <(() => void) | null>null,\n  }\n\n  /**\n   * Fetch user info from server\n   */\n  private fetchUserInfo() {\n    this.kit.useUser().logout() // clear login status\n\n    if (this.query.timer) window.clearTimeout(this.query.timer) // clear the not executed timeout task\n    if (this.query.abortFn) this.query.abortFn() // abort the last request (if request is pending not finished)\n\n    this.query.timer = window.setTimeout(() => {\n      this.query.timer = null // clear the timer (clarify the timer is executing)\n\n      const api = this.kit.useApi()\n      const CANCEL_TOKEN = 'getUserCancelToken'\n      this.query.abortFn = () => api.abortRequest(CANCEL_TOKEN)\n\n      api.user\n        .getUser(\n          { ...api.getUserFields() },\n          {\n            cancelToken: CANCEL_TOKEN,\n          },\n        )\n        .then((res) => this.onUserInfoFetched(res.data))\n        .catch((err) => {})\n        .finally(() => {\n          this.query.abortFn = null // clear the abort function (clarify the request is finished)\n        })\n    }, 400) // delay to reduce request\n  }\n\n  /**\n   * Function called when user info fetched\n   *\n   * @param data The response data from server\n   */\n  private onUserInfoFetched(data: UserInfoApiResponseData) {\n    // If api response is not login, logout\n    if (!data.is_login) this.kit.useUser().logout()\n\n    // Update unread notifies\n    this.kit.useData().updateNotifies(data.notifies)\n\n    // If user is admin and not login,\n    if (this.kit.useUser().checkHasBasicUserInfo() && !data.is_login && data.user?.is_admin) {\n      // then show login window\n      this.kit.useCheckers().checkAdmin({\n        onSuccess: () => {},\n      })\n    }\n\n    // Auto fill user link from server\n    if (data.user && data.user.link) {\n      this.kit.useUI().$link.value = data.user.link\n      this.kit.useUser().update({ link: data.user.link })\n    }\n  }\n}\n","import EditorPlugin from './_plug'\nimport type PlugKit from './_kit'\n\nexport default class HeaderLink extends EditorPlugin {\n  constructor(kit: PlugKit) {\n    super(kit)\n\n    const onLinkChange = ({ field }: { field: string }) => {\n      if (field === 'link') this.onLinkInputChange()\n    }\n\n    // bind events\n    this.kit.useMounted(() => {\n      this.kit.useEvents().on('header-change', onLinkChange)\n    })\n\n    this.kit.useUnmounted(() => {\n      this.kit.useEvents().off('header-change', onLinkChange)\n    })\n  }\n\n  private onLinkInputChange() {\n    // auto and force add protocol prefix for user input link\n    const link = this.kit.useUI().$link.value.trim()\n    if (!!link && !/^(http|https):\\/\\//.test(link)) {\n      this.kit.useUI().$link.value = `https://${link}`\n      this.kit.useUser().update({ link: this.kit.useUI().$link.value })\n    }\n  }\n}\n","import EditorPlugin from './_plug'\nimport type PlugKit from './_kit'\nimport $t from '@/i18n'\n\nexport default class Textarea extends EditorPlugin {\n  constructor(kit: PlugKit) {\n    super(kit)\n\n    const onKeydown = (e: KeyboardEvent) => this.onKeydown(e)\n    const onInput = () => this.onInput()\n\n    this.kit.useMounted(() => {\n      // 占位符\n      this.kit.useUI().$textarea.placeholder = this.kit.useConf().placeholder || $t('placeholder')\n\n      // bind the event\n      this.kit.useUI().$textarea.addEventListener('keydown', onKeydown)\n      this.kit.useUI().$textarea.addEventListener('input', onInput)\n    })\n\n    this.kit.useUnmounted(() => {\n      // unmount the event\n      this.kit.useUI().$textarea.removeEventListener('keydown', onKeydown)\n      this.kit.useUI().$textarea.removeEventListener('input', onInput)\n    })\n\n    this.kit.useEvents().on('content-updated', () => {\n      // delay 80ms to prevent invalid execution\n      window.setTimeout(() => {\n        this.adaptiveHeightByContent()\n      }, 80)\n    })\n  }\n\n  // 按下 Tab 输入内容，而不是失去焦距\n  private onKeydown(e: KeyboardEvent) {\n    const keyCode = e.keyCode || e.which\n\n    if (keyCode === 9) {\n      e.preventDefault()\n      this.kit.useEditor().insertContent('\\t')\n    }\n  }\n\n  private onInput() {\n    this.kit.useEvents().trigger('content-updated', this.kit.useEditor().getContentRaw())\n  }\n\n  // Resize the textarea height by content\n  public adaptiveHeightByContent() {\n    const diff = this.kit.useUI().$textarea.offsetHeight - this.kit.useUI().$textarea.clientHeight\n    this.kit.useUI().$textarea.style.height = '0px' // it's a magic. 若不加此行，内容减少，高度回不去\n    this.kit.useUI().$textarea.style.height = `${this.kit.useUI().$textarea.scrollHeight + diff}px`\n  }\n}\n","import EditorPlugin from './_plug'\nimport type PlugKit from './_kit'\nimport $t from '@/i18n'\n\nexport default class SubmitBtn extends EditorPlugin {\n  constructor(kit: PlugKit) {\n    super(kit)\n\n    const onClick = () => {\n      this.kit.useEditor().submit()\n    }\n\n    this.kit.useMounted(() => {\n      // apply the submit button text from user custom config\n      this.kit.useUI().$submitBtn.innerText = this.kit.useConf().sendBtn || $t('send')\n\n      // bind the event when click the submit button\n      this.kit.useUI().$submitBtn.addEventListener('click', onClick)\n    })\n\n    this.kit.useUnmounted(() => {\n      this.kit.useUI().$submitBtn.removeEventListener('click', onClick)\n    })\n  }\n}\n","import EditorPlugin from './_plug'\nimport type PlugKit from './_kit'\nimport Submit from './submit'\nimport SubmitAddPreset from './submit-add'\nimport type { CommentData } from '@/types'\nimport * as Utils from '@/lib/utils'\nimport $t from '@/i18n'\n\nexport default class StateReply extends EditorPlugin {\n  private comment?: CommentData\n\n  constructor(kit: PlugKit) {\n    super(kit)\n\n    // add effect when state switch to `reply`\n    this.useEditorStateEffect('reply', (commentData) => {\n      this.setReply(commentData)\n\n      return () => {\n        this.cancelReply()\n      }\n    })\n\n    // register submit preset\n    this.kit.useEvents().on('mounted', () => {\n      const submitPlug = this.kit.useDeps(Submit)\n      if (!submitPlug) throw Error('SubmitPlug not initialized')\n\n      const defaultPreset = new SubmitAddPreset(this.kit)\n\n      submitPlug.registerCustom({\n        activeCond: () => !!this.comment, // active this custom submit when reply mode\n        req: async () => {\n          if (!this.comment) throw new Error('reply comment cannot be empty')\n\n          const nComment = (\n            await this.kit.useApi().comments.createComment({\n              ...(await defaultPreset.getSubmitAddParams()),\n              rid: this.comment.id,\n              page_key: this.comment.page_key,\n              page_title: undefined,\n              site_name: this.comment.site_name,\n            })\n          ).data\n\n          return nComment\n        },\n        post: (nComment: CommentData) => {\n          // open another page when reply comment is not the same pageKey\n          const conf = this.kit.useConf()\n          if (nComment.page_key !== conf.pageKey) {\n            window.open(`${nComment.page_url}#atk-comment-${nComment.id}`)\n          }\n\n          defaultPreset.postSubmitAdd(nComment)\n        },\n      })\n    })\n  }\n\n  private setReply(commentData: CommentData) {\n    const ui = this.kit.useUI()\n    if (!ui.$sendReplyBtn) {\n      const $btn = Utils.createElement(\n        `<span class=\"atk-state-btn\">` +\n          `<span class=\"atk-text-wrap\">` +\n          `${$t('reply')} <span class=\"atk-text\"></span>` +\n          `</span>` +\n          `<span class=\"atk-cancel atk-icon-close atk-icon\"></span>` +\n          `</span>`,\n      )\n      $btn.querySelector<HTMLElement>('.atk-text')!.innerText = `@${commentData.nick}`\n      $btn.addEventListener('click', () => {\n        this.kit.useEditor().resetState()\n      })\n      ui.$stateWrap.append($btn)\n      ui.$sendReplyBtn = $btn\n    }\n\n    this.comment = commentData\n\n    ui.$textarea.focus()\n  }\n\n  private cancelReply() {\n    if (!this.comment) return\n\n    const ui = this.kit.useUI()\n    if (ui.$sendReplyBtn) {\n      ui.$sendReplyBtn.remove()\n      ui.$sendReplyBtn = undefined\n    }\n    this.comment = undefined\n  }\n}\n","import type PlugKit from './_kit'\nimport EditorPlugin from './_plug'\nimport Submit from './submit'\nimport type { CommentData } from '@/types'\nimport $t from '@/i18n'\nimport * as Utils from '@/lib/utils'\n\nexport default class StateEdit extends EditorPlugin {\n  private comment?: CommentData\n\n  constructor(kit: PlugKit) {\n    super(kit)\n\n    // add effect when state switch to `edit`\n    this.useEditorStateEffect('edit', (comment) => {\n      this.edit(comment)\n\n      return () => {\n        this.cancelEdit()\n      }\n    })\n\n    // register submit preset\n    this.kit.useMounted(() => {\n      const submitPlug = this.kit.useDeps(Submit)\n      if (!submitPlug) throw Error('SubmitPlug not initialized')\n\n      submitPlug.registerCustom({\n        activeCond: () => !!this.comment, // active this custom submit when edit mode\n        req: async () => {\n          const saveData = {\n            content: this.kit.useEditor().getContentFinal(),\n            nick: this.kit.useUI().$name.value,\n            email: this.kit.useUI().$email.value,\n            link: this.kit.useUI().$link.value,\n          }\n          const comment = this.comment!\n          const nComment = await this.kit.useApi().comments.updateComment(comment.id, {\n            ...comment,\n            ...saveData,\n          })\n          return nComment.data\n        },\n        post: (nComment: CommentData) => {\n          this.kit.useData().updateComment(nComment)\n        },\n      })\n    })\n  }\n\n  private edit(comment: CommentData) {\n    const ui = this.kit.useUI()\n    if (!ui.$editCancelBtn) {\n      const $btn = Utils.createElement(\n        `<span class=\"atk-state-btn\">` +\n          `<span class=\"atk-text-wrap\">` +\n          `${$t('editCancel')}` +\n          `</span>` +\n          `<span class=\"atk-cancel atk-icon-close atk-icon\"></span>` +\n          `</span>`,\n      )\n      $btn.onclick = () => {\n        this.kit.useEditor().resetState()\n      }\n      ui.$stateWrap.append($btn)\n      ui.$editCancelBtn = $btn\n    }\n    this.comment = comment\n\n    ui.$header.style.display = 'none' // TODO: support modify header information\n\n    ui.$name.value = comment.nick || ''\n    ui.$email.value = comment.email || ''\n    ui.$link.value = comment.link || ''\n\n    this.kit.useEditor().setContent(comment.content)\n    ui.$textarea.focus()\n\n    this.updateSubmitBtnText($t('save'))\n  }\n\n  private cancelEdit() {\n    if (!this.comment) return\n\n    const ui = this.kit.useUI()\n\n    if (ui.$editCancelBtn) {\n      ui.$editCancelBtn.remove()\n      ui.$editCancelBtn = undefined\n    }\n\n    this.comment = undefined\n\n    const { name, email, link } = this.kit.useUser().getData()\n    ui.$name.value = name\n    ui.$email.value = email\n    ui.$link.value = link\n\n    this.kit.useEditor().setContent('')\n    this.restoreSubmitBtnText()\n\n    ui.$header.style.display = '' // TODO: support modify header information\n  }\n\n  // -------------------------------------------------------------------\n  //  Submit Btn Text Modifier\n  // -------------------------------------------------------------------\n\n  private originalSubmitBtnText = 'Send'\n\n  private updateSubmitBtnText(text: string) {\n    this.originalSubmitBtnText = this.kit.useUI().$submitBtn.innerText\n    this.kit.useUI().$submitBtn.innerText = text\n  }\n\n  private restoreSubmitBtnText() {\n    this.kit.useUI().$submitBtn.innerText = this.originalSubmitBtnText\n  }\n}\n","import EditorPlugin from './_plug'\nimport type PlugKit from './_kit'\nimport * as Utils from '@/lib/utils'\nimport $t from '@/i18n'\n\nexport default class Closable extends EditorPlugin {\n  constructor(kit: PlugKit) {\n    super(kit)\n\n    const onOpen = () => this.open()\n    const onClose = () => this.close()\n\n    this.kit.useMounted(() => {\n      this.kit.useEvents().on('editor-open', onOpen)\n      this.kit.useEvents().on('editor-close', onClose)\n    })\n    this.kit.useUnmounted(() => {\n      this.kit.useEvents().off('editor-open', onOpen)\n      this.kit.useEvents().off('editor-close', onClose)\n    })\n  }\n\n  private open() {\n    this.kit.useUI().$textareaWrap.querySelector('.atk-comment-closed')?.remove()\n    this.kit.useUI().$textarea.style.display = ''\n    this.kit.useUI().$bottom.style.display = ''\n  }\n\n  private close() {\n    if (!this.kit.useUI().$textareaWrap.querySelector('.atk-comment-closed'))\n      this.kit\n        .useUI()\n        .$textareaWrap.prepend(\n          Utils.createElement(`<div class=\"atk-comment-closed\">${$t('onlyAdminCanReply')}</div>`),\n        )\n\n    if (!this.kit.useUser().getData().is_admin) {\n      this.kit.useUI().$textarea.style.display = 'none'\n      this.kit.useEvents().trigger('panel-close')\n      this.kit.useUI().$bottom.style.display = 'none'\n    } else {\n      // 管理员一直打开评论\n      this.kit.useUI().$textarea.style.display = ''\n      this.kit.useUI().$bottom.style.display = ''\n    }\n  }\n}\n","import type { PluginManager } from '../editor-kit'\nimport type EditorPlugin from './_plug'\n\n/**\n * PlugKit provides a set of methods to help you develop editor plug\n */\nexport default class PlugKit {\n  constructor(private plugins: PluginManager) {}\n\n  /** Use the editor */\n  useEditor() {\n    return this.plugins.getEditor()\n  }\n\n  /** Use the config of Artalk */\n  useConf() {\n    return this.plugins.getOptions().getConf().get()\n  }\n\n  /** Use the http api client */\n  useApi() {\n    return this.plugins.getOptions().getApi()\n  }\n\n  /** Use the data manager */\n  useData() {\n    return this.plugins.getOptions().getData()\n  }\n\n  /** Use the user manager */\n  useUser() {\n    return this.plugins.getOptions().getUser()\n  }\n\n  /** Use the checkers */\n  useCheckers() {\n    return this.plugins.getOptions().getCheckers()\n  }\n\n  /** Use the ui of editor */\n  useUI() {\n    return this.plugins.getEditor().getUI()\n  }\n\n  /** Use the events in editor scope */\n  useEvents() {\n    return this.plugins.getEvents()\n  }\n\n  /** Listen the event when plug is mounted */\n  useMounted(func: () => void) {\n    this.useEvents().on('mounted', func)\n  }\n\n  /** Listen the event when plug is unmounted */\n  useUnmounted(func: () => void) {\n    this.useEvents().on('unmounted', func)\n  }\n\n  /** Use the deps of other plug */\n  useDeps<T extends typeof EditorPlugin>(plug: T) {\n    return this.plugins.get(plug)\n  }\n\n  /** Use the root element of artalk */\n  useArtalkRootEl() {\n    return this.plugins.getOptions().getArtalkRootEl()\n  }\n}\n","import type { EventManager as IEventManager, Event, EventHandler, EventOptions } from '@/types'\n\nexport class EventManager<T> implements IEventManager<T> {\n  private events: Event<T>[] = []\n\n  /**\n   * Add an event listener for a specific event name\n   */\n  public on<K extends keyof T>(name: K, handler: EventHandler<T[K]>, opts: EventOptions = {}) {\n    this.events.push({\n      name,\n      handler: handler as EventHandler<T[keyof T]>,\n      ...opts,\n    })\n  }\n\n  /**\n   * Remove an event listener for a specific event name and handler\n   */\n  public off<K extends keyof T>(name: K, handler: EventHandler<T[K]>) {\n    if (!handler) return // not allow remove all events with same name\n    this.events = this.events.filter((evt) => !(evt.name === name && evt.handler === handler))\n  }\n\n  /**\n   * Trigger an event with an optional payload\n   */\n  public trigger<K extends keyof T>(name: K, payload?: T[K]) {\n    this.events\n      .slice(0) // make a copy, in case listeners are removed while iterating\n      .filter((evt) => evt.name === name && typeof evt.handler === 'function')\n      .forEach((evt) => {\n        if (evt.once) this.off(name, evt.handler)\n        evt.handler(payload!)\n      })\n  }\n}\n","import { getEnabledPlugs } from './editor'\nimport EditorPlugin from './editor/_plug'\nimport PlugKit from './editor/_kit'\nimport { EventManager } from '@/lib/event-manager'\nimport type {\n  Editor,\n  ArtalkPlugin,\n  DataManager,\n  ConfigManager,\n  UserManager,\n  EditorPluginManager as IEditorPluginManager,\n  CheckerManager,\n} from '@/types'\nimport type { Api } from '@/api'\n\nexport interface EditorEventPayloadMap {\n  mounted: undefined\n  unmounted: undefined\n  'header-input': { field: string; $input: HTMLInputElement }\n  'header-change': { field: string; $input: HTMLInputElement }\n  'content-updated': string\n  'panel-show': EditorPlugin\n  'panel-hide': EditorPlugin\n  'panel-close': undefined\n\n  'editor-close': undefined\n  'editor-open': undefined\n  'editor-submit': undefined\n  'editor-submitted': undefined\n}\n\nexport const EditorKit: ArtalkPlugin = (ctx) => {\n  ctx.provide(\n    'editorPlugs',\n    (editor, config, user, data, checkers, api) => {\n      const pluginManager = new PluginManager({\n        getArtalkRootEl: () => ctx.getEl(),\n        getEditor: () => editor,\n        getConf: () => config,\n        getUser: () => user,\n        getApi: () => api,\n        getData: () => data,\n        getCheckers: () => checkers,\n        onSubmitted: () => ctx.trigger('editor-submitted'),\n      })\n      editor.setPlugins(pluginManager)\n      return pluginManager\n    },\n    ['editor', 'config', 'user', 'data', 'checkers', 'api'] as const,\n  )\n}\n\nexport interface PluginManagerOptions {\n  getArtalkRootEl: () => HTMLElement\n  getEditor: () => Editor\n  getConf: () => ConfigManager\n  getUser: () => UserManager\n  getApi: () => Api\n  getData: () => DataManager\n  getCheckers: () => CheckerManager\n  onSubmitted: () => void\n}\n\nexport class PluginManager implements IEditorPluginManager {\n  private plugins: EditorPlugin[] = []\n  private openedPlug: EditorPlugin | null = null\n  private events = new EventManager<EditorEventPayloadMap>()\n\n  constructor(public opts: PluginManagerOptions) {\n    let confLoaded = false // config not loaded at first time\n    this.opts\n      .getConf()\n      .watchConf(['imgUpload', 'emoticons', 'preview', 'editorTravel', 'locale'], (conf) => {\n        // trigger unmount event will call all plugs' unmount function\n        // (this will only be called while conf reloaded, not be called at first time)\n        confLoaded && this.getEvents().trigger('unmounted')\n\n        // reset the plugs\n        this.clear()\n\n        // init the all enabled plugs\n        getEnabledPlugs(conf).forEach((Plug) => {\n          // create the plug instance\n          const kit = new PlugKit(this)\n          this.plugins.push(new Plug(kit))\n        })\n\n        // trigger event for plug initialization\n        this.getEvents().trigger('mounted')\n        confLoaded = true\n\n        // refresh the plug UI\n        this.loadPluginUI()\n      })\n\n    this.events.on('panel-close', () => this.closePluginPanel())\n    this.events.on('editor-submitted', () => opts.onSubmitted())\n  }\n\n  getPlugins() {\n    return this.plugins\n  }\n\n  getEvents() {\n    return this.events\n  }\n\n  getEditor() {\n    return this.opts.getEditor()\n  }\n\n  getOptions() {\n    return this.opts\n  }\n\n  private clear() {\n    this.plugins = []\n    this.events = new EventManager()\n    if (this.openedPlug) this.closePluginPanel()\n  }\n\n  private loadPluginUI() {\n    // handle ui, clear and reset the plug btns and plug panels\n    this.getEditor().getUI().$plugPanelWrap.innerHTML = ''\n    this.getEditor().getUI().$plugPanelWrap.style.display = 'none'\n    this.getEditor().getUI().$plugBtnWrap.innerHTML = ''\n\n    // load the plug UI\n    this.plugins.forEach((plug) => this.loadPluginItem(plug))\n  }\n\n  /** Load the plug btn and plug panel on editor ui */\n  private loadPluginItem(plug: EditorPlugin) {\n    const $btn = plug.$btn\n    if (!$btn) return\n    this.getEditor().getUI().$plugBtnWrap.appendChild($btn)\n\n    // bind the event when click plug btn\n    !$btn.onclick &&\n      ($btn.onclick = () => {\n        // removing the active class from all the buttons\n        this.opts\n          .getEditor()\n          .getUI()\n          .$plugBtnWrap.querySelectorAll('.active')\n          .forEach((item) => item.classList.remove('active'))\n\n        // if the plug is not the same as the openedPlug,\n        if (plug !== this.openedPlug) {\n          // then open the plug current clicked plug panel\n          this.openPluginPanel(plug)\n\n          // add active class for current plug panel\n          $btn.classList.add('active')\n        } else {\n          // then close the plug\n          this.closePluginPanel()\n        }\n      })\n\n    // initialization of plug panel\n    const $panel = plug.$panel\n    if ($panel) {\n      $panel.style.display = 'none'\n      this.getEditor().getUI().$plugPanelWrap.appendChild($panel)\n    }\n  }\n\n  get<T extends typeof EditorPlugin>(plug: T) {\n    return this.plugins.find((p) => p instanceof plug) as InstanceType<T> | undefined\n  }\n\n  /** Open the editor plug panel */\n  openPluginPanel(plug: EditorPlugin) {\n    this.plugins.forEach((aPlug) => {\n      const plugPanel = aPlug.$panel\n      if (!plugPanel) return\n\n      if (aPlug === plug) {\n        plugPanel.style.display = ''\n        this.events.trigger('panel-show', plug)\n      } else {\n        plugPanel.style.display = 'none'\n        this.events.trigger('panel-hide', plug)\n      }\n    })\n\n    this.getEditor().getUI().$plugPanelWrap.style.display = ''\n    this.openedPlug = plug\n  }\n\n  /** Close the editor plugin panel */\n  closePluginPanel() {\n    if (!this.openedPlug) return\n\n    this.getEditor().getUI().$plugPanelWrap.style.display = 'none'\n    this.events.trigger('panel-hide', this.openedPlug)\n    this.openedPlug = null\n  }\n\n  /** Get the content which is transformed by plugs */\n  getTransformedContent(rawContent: string) {\n    let result = rawContent\n    this.plugins.forEach((aPlug) => {\n      if (!aPlug.contentTransformer) return\n      result = aPlug.contentTransformer(result)\n    })\n    return result\n  }\n}\n","import type { ArtalkPlugin } from '@/types'\n\nexport const GotoFocus: ArtalkPlugin = (ctx) => {\n  const list = ctx.inject('list')\n\n  ctx.on('list-goto', async (commentID) => {\n    // find the comment node\n    let comment = ctx.getCommentNodes().find((c) => c.getID() === commentID)\n    if (!comment) {\n      // fetch and insert the comment from the server\n      const data = (await ctx.getApi().comments.getComment(commentID)).data\n      list.getLayout({ forceFlatMode: true }).insert(data.comment, data.reply_comment)\n      comment = ctx.getCommentNodes().find((c) => c.getID() === commentID)\n    }\n    if (!comment) return\n    comment.focus()\n  })\n}\n","import * as Utils from '@/lib/utils'\nimport * as Ui from '@/lib/ui'\nimport $t from '@/i18n'\n\nexport interface ErrorDialogOptions {\n  $err: HTMLElement\n\n  errMsg: string\n  errData?: any\n  retryFn?: () => void\n\n  onOpenSidebar?: () => void\n}\n\nexport function showErrorDialog(opts: ErrorDialogOptions) {\n  const errEl = Utils.createElement(`<span><span class=\"error-message\"></span><br/><br/></span>`)\n  errEl.querySelector<HTMLElement>('.error-message')!.innerText =\n    `${$t('listLoadFailMsg')}\\n${opts.errMsg}`\n\n  if (opts.retryFn) {\n    const $retryBtn = Utils.createElement(`<span style=\"cursor:pointer;\">${$t('listRetry')}</span>`)\n    $retryBtn.onclick = () => opts.retryFn && opts.retryFn()\n    errEl.appendChild($retryBtn)\n  }\n\n  if (opts.onOpenSidebar) {\n    const $openSidebar = Utils.createElement(\n      `<span atk-only-admin-show> | <span style=\"cursor:pointer;\">${$t('openName', { name: $t('ctrlCenter') })}</span></span>`,\n    )\n    errEl.appendChild($openSidebar)\n    $openSidebar.onclick = () => opts.onOpenSidebar && opts.onOpenSidebar()\n  }\n\n  Ui.setError(opts.$err, errEl)\n}\n","import * as Ui from '../../lib/ui'\nimport type { ArtalkPlugin } from '@/types'\nimport { showErrorDialog } from '@/components/error-dialog'\n\nexport const ErrorDialog: ArtalkPlugin = (ctx) => {\n  const list = ctx.inject('list')\n\n  ctx.on('list-fetch', () => {\n    // clear the original error when a new fetch is triggered\n    Ui.setError(list.getEl(), null)\n  })\n\n  ctx.on('list-failed', (err) => {\n    showErrorDialog({\n      $err: list.getEl(),\n      errMsg: err.msg,\n      errData: err.data,\n      retryFn: () => ctx.fetch({ offset: 0 }),\n    })\n  })\n}\n","import { WithEditor } from './with-editor'\nimport { Unread } from './unread'\nimport { Count } from './count'\nimport { SidebarBtn } from './sidebar-btn'\nimport { UnreadBadge } from './unread-badge'\nimport { GotoDispatcher } from './goto-dispatcher'\nimport { GotoFocus } from './goto-focus'\nimport { Copyright } from './copyright'\nimport { NoComment } from './no-comment'\nimport { Dropdown } from './dropdown'\nimport { TimeTicking } from './time-ticking'\nimport { ErrorDialog } from './error-dialog'\nimport { Loading } from './loading'\nimport { Fetch } from './fetch'\nimport { ReachBottom } from './reach-bottom'\nimport { GotoFirst } from './goto-first'\nimport type { ArtalkPlugin } from '@/types'\n\nconst ListPlugins: ArtalkPlugin[] = [\n  Fetch,\n  Loading,\n  Unread,\n  WithEditor,\n  Count,\n  SidebarBtn,\n  UnreadBadge,\n  Dropdown,\n  GotoDispatcher,\n  GotoFocus,\n  NoComment,\n  Copyright,\n  TimeTicking,\n  ErrorDialog,\n  ReachBottom,\n  GotoFirst,\n]\n\nexport { ListPlugins }\n","import type { ListFetchParams, ArtalkPlugin } from '@/types'\n\nexport const Fetch: ArtalkPlugin = (ctx) => {\n  const conf = ctx.inject('config')\n\n  ctx.on('list-fetch', (_params) => {\n    if (ctx.getData().getLoading()) return\n    ctx.getData().setLoading(true)\n\n    const params: ListFetchParams = {\n      // default params\n      offset: 0,\n      limit: conf.get().pagination.pageSize,\n      flatMode: conf.get().flatMode as boolean, // always be boolean because had been handled in Artalk.init\n      paramsModifier: conf.get().listFetchParamsModifier,\n      ..._params,\n    }\n\n    // must before other function call\n    ctx.getData().setListLastFetch({\n      params,\n    })\n\n    // prepare params for request\n    const reqParams = {\n      limit: params.limit,\n      offset: params.offset,\n      flat_mode: params.flatMode,\n      page_key: conf.get().pageKey,\n      site_name: conf.get().site,\n    }\n\n    // call the modifier function\n    if (params.paramsModifier) params.paramsModifier(reqParams)\n\n    // start request\n    ctx\n      .getApi()\n      .comments.getComments({\n        ...reqParams,\n        ...ctx.getApi().getUserFields(),\n      })\n      .then(({ data }) => {\n        // Must before all other function call and event trigger,\n        // because it will depend on the lastData\n        // TODO: this is global variable, easy to use, but not good, consider to refactor.\n        // refactor work is hard, because it is used in many places.\n        ctx.getData().setListLastFetch({ params, data })\n\n        // 装置评论\n        ctx.getData().loadComments(data.comments)\n\n        // 更新页面数据\n        ctx.getData().updatePage(data.page)\n\n        // trigger events when success\n        params.onSuccess && params.onSuccess(data)\n\n        ctx.trigger('list-fetched', { params, data })\n      })\n      .catch((e) => {\n        // 显示错误对话框\n        const error = {\n          msg: e.msg || String(e),\n          data: e.data,\n        }\n\n        params.onError && params.onError(error)\n\n        // trigger events when error\n        ctx.trigger('list-failed', error)\n        ctx.trigger('list-fetched', { params, error })\n\n        throw e\n      })\n      .finally(() => {\n        ctx.getData().setLoading(false)\n      })\n  })\n}\n","import type { ArtalkPlugin } from '@/types'\nimport * as Ui from '@/lib/ui'\n\nexport const Loading: ArtalkPlugin = (ctx) => {\n  const list = ctx.inject('list')\n\n  ctx.on('list-fetch', (p) => {\n    if (p.offset === 0)\n      // only show loading when fetch first page\n      Ui.setLoading(true, list.getEl())\n    // else if not first page, show loading in paginator (code not there)\n  })\n\n  ctx.on('list-fetched', () => {\n    Ui.setLoading(false, list.getEl())\n  })\n}\n","import type { ArtalkPlugin } from '@/types'\nimport * as Utils from '@/lib/utils'\n\nexport const Unread: ArtalkPlugin = (ctx) => {\n  const conf = ctx.inject('config')\n\n  ctx.on('comment-rendered', (comment) => {\n    // comment unread highlight\n    if (conf.get().listUnreadHighlight) {\n      const notifies = ctx.getData().getNotifies()\n      const notify = notifies.find((o) => o.comment_id === comment.getID())\n\n      if (notify) {\n        // if comment contains in unread list\n        comment.getRender().setUnread(true)\n        comment.getRender().setOpenAction(() => {\n          window.open(notify.read_link)\n\n          // remove notify which has been read\n          ctx.getData().updateNotifies(notifies.filter((o) => o.comment_id !== comment.getID()))\n        })\n      } else {\n        // comment not in unread list\n        comment.getRender().setUnread(false)\n      }\n    }\n  })\n\n  ctx.on('list-goto', (commentID) => {\n    const notifyKey = Utils.getQueryParam('atk_notify_key')\n    if (notifyKey) {\n      // mark as read\n      ctx\n        .getApi()\n        .notifies.markNotifyRead(commentID, notifyKey)\n        .then(() => {\n          // remove from unread list\n          ctx.getData().updateNotifies(\n            ctx\n              .getData()\n              .getNotifies()\n              .filter((o) => o.comment_id !== commentID),\n          )\n        })\n    }\n  })\n}\n","import type { Context as IContext, ArtalkPlugin, PageData } from '@/types'\nimport $t from '@/i18n'\n\nexport const WithEditor: ArtalkPlugin = (ctx) => {\n  const list = ctx.inject('list')\n  const editorPlugs = ctx.inject('editorPlugs')\n  let $closeCommentBtn: HTMLElement | undefined\n\n  // on Artalk mounted\n  // (after all components had mounted)\n  ctx.on('mounted', () => {\n    $closeCommentBtn = list\n      .getEl()\n      .querySelector<HTMLElement>('[data-action=\"admin-close-comment\"]')!\n\n    // bind editor close button click event\n    $closeCommentBtn.addEventListener('click', () => {\n      const page = ctx.getData().getPage()\n      if (!page) throw new Error('Page data not found')\n\n      page.admin_only = !page.admin_only\n      adminPageEditSave(ctx, page)\n    })\n  })\n\n  // on comment list loaded (it will include page data update)\n  ctx.on('page-loaded', (page) => {\n    // if page comment is closed\n    if (page?.admin_only === true) {\n      // then close editor\n      editorPlugs?.getEvents().trigger('editor-close')\n      $closeCommentBtn && ($closeCommentBtn.innerText = $t('openComment'))\n    } else {\n      // the open editor\n      editorPlugs?.getEvents().trigger('editor-open')\n      $closeCommentBtn && ($closeCommentBtn.innerText = $t('closeComment'))\n    }\n  })\n\n  ctx.on('list-loaded', (comments) => {\n    // 防止评论框被吞\n    ctx.editorResetState()\n  })\n}\n\n/** 管理员设置页面信息 */\nfunction adminPageEditSave(ctx: IContext, page: PageData) {\n  ctx.editorShowLoading()\n  ctx\n    .getApi()\n    .pages.updatePage(page.id, page)\n    .then(({ data }) => {\n      ctx.getData().updatePage(data)\n    })\n    .catch((err) => {\n      ctx.editorShowNotify(`${$t('editFail')}: ${err.message || String(err)}`, 'e')\n    })\n    .finally(() => {\n      ctx.editorHideLoading()\n    })\n}\n","import type { ArtalkPlugin } from '@/types'\nimport * as Utils from '@/lib/utils'\nimport $t from '@/i18n'\n\nexport const Count: ArtalkPlugin = (ctx) => {\n  const list = ctx.inject('list')\n\n  const refreshCountNumEl = () => {\n    const $count = list.getEl().querySelector('.atk-comment-count .atk-text')\n    if (!$count) return\n\n    const text = Utils.htmlEncode(\n      $t('counter', {\n        count: `${Number(ctx.getData().getListLastFetch()?.data?.count) || 0}`,\n      }),\n    )\n    $count.innerHTML = text.replace(/(\\d+)/, '<span class=\"atk-comment-count-num\">$1</span>')\n  }\n\n  ctx.on('list-loaded', () => {\n    refreshCountNumEl()\n  })\n\n  ctx.on('comment-inserted', () => {\n    // 评论数增加 1\n    const last = ctx.getData().getListLastFetch()\n    if (last?.data) last.data.count += 1\n  })\n\n  ctx.on('comment-deleted', () => {\n    // 评论数减 1\n    const last = ctx.getData().getListLastFetch()\n    if (last?.data) last.data.count -= 1\n  })\n}\n","import type { ArtalkPlugin } from '@/types'\nimport $t from '@/i18n'\n\nexport const SidebarBtn: ArtalkPlugin = (ctx) => {\n  const list = ctx.inject('list')\n  let $openSidebarBtn: HTMLElement | null = null\n\n  const syncByUser = () => {\n    if (!$openSidebarBtn) return\n    const user = ctx.inject('user').getData()\n\n    // 已输入个人信息\n    if (!!user.name && !!user.email) {\n      $openSidebarBtn.classList.remove('atk-hide')\n\n      // update button text (normal user or admin)\n      const $btnText = $openSidebarBtn.querySelector<HTMLElement>('.atk-text')\n      if ($btnText) $btnText.innerText = !user.is_admin ? $t('msgCenter') : $t('ctrlCenter')\n    } else {\n      $openSidebarBtn.classList.add('atk-hide')\n    }\n  }\n\n  ctx.watchConf(['locale'], (conf) => {\n    $openSidebarBtn = list.getEl().querySelector<HTMLElement>('[data-action=\"open-sidebar\"]')\n    if (!$openSidebarBtn) return\n\n    $openSidebarBtn.onclick = () => {\n      // use onclick rather than addEventListener to prevent duplicate event\n      ctx.showSidebar()\n    }\n\n    syncByUser()\n  })\n\n  ctx.on('user-changed', (user) => {\n    syncByUser()\n  })\n}\n","import type { ArtalkPlugin } from '@/types'\n\nexport const UnreadBadge: ArtalkPlugin = (ctx) => {\n  const list = ctx.inject('list')\n  let $unreadBadge: HTMLElement | null = null\n\n  const showUnreadBadge = (count: number) => {\n    if (!$unreadBadge) return\n\n    if (count > 0) {\n      $unreadBadge.innerText = `${Number(count || 0)}`\n      $unreadBadge.style.display = 'block'\n    } else {\n      $unreadBadge.style.display = 'none'\n    }\n  }\n\n  ctx.on('mounted', () => {\n    $unreadBadge = list.getEl().querySelector<HTMLElement>('.atk-unread-badge')\n  })\n\n  ctx.on('notifies-updated', (notifies) => {\n    showUnreadBadge(notifies.length || 0)\n  })\n}\n","import type { ArtalkPlugin } from '@/types'\nimport * as Utils from '@/lib/utils'\nimport $t from '@/i18n'\n\nexport const Dropdown: ArtalkPlugin = (ctx) => {\n  const list = ctx.inject('list')\n  const conf = ctx.inject('config')\n\n  const reloadUseParamsEditor = (func: (p: any) => void) => {\n    conf.update({\n      listFetchParamsModifier: func,\n    })\n    ctx.reload()\n  }\n\n  const initDropdown = ($dropdownOn: HTMLElement) => {\n    renderDropdown({\n      $dropdownWrap: $dropdownOn,\n      dropdownList: [\n        [\n          $t('sortLatest'),\n          () => {\n            reloadUseParamsEditor((p) => {\n              p.sort_by = 'date_desc'\n            })\n          },\n        ],\n        [\n          $t('sortBest'),\n          () => {\n            reloadUseParamsEditor((p) => {\n              p.sort_by = 'vote'\n            })\n          },\n        ],\n        [\n          $t('sortOldest'),\n          () => {\n            reloadUseParamsEditor((p) => {\n              p.sort_by = 'date_asc'\n            })\n          },\n        ],\n        [\n          $t('sortAuthor'),\n          () => {\n            reloadUseParamsEditor((p) => {\n              p.view_only_admin = true\n            })\n          },\n        ],\n      ],\n    })\n  }\n\n  ctx.watchConf(['listSort', 'locale'], (conf) => {\n    const $count = list.getEl().querySelector<HTMLElement>('.atk-comment-count')\n    if (!$count) return\n\n    // 评论列表排序 Dropdown 下拉选择层\n    if (conf.listSort) {\n      initDropdown($count)\n    } else {\n      removeDropdown({\n        $dropdownWrap: $count,\n      })\n    }\n  })\n}\n\n/** 评论排序方式选择下拉菜单 */\nfunction renderDropdown(conf: {\n  $dropdownWrap: HTMLElement\n  dropdownList: [string, () => void][]\n}) {\n  const { $dropdownWrap, dropdownList } = conf\n  if ($dropdownWrap.querySelector('.atk-dropdown')) return\n\n  // 修改 class\n  $dropdownWrap.classList.add('atk-dropdown-wrap')\n\n  // 插入图标\n  $dropdownWrap.append(Utils.createElement(`<span class=\"atk-arrow-down-icon\"></span>`))\n\n  // 列表项点击事件\n  let curtActive = 0 // 当前选中\n  const onItemClick = (i: number, $item: HTMLElement, name: string, action: () => void) => {\n    action()\n\n    // set active\n    curtActive = i\n    $dropdown.querySelectorAll('.active').forEach((e) => {\n      e.classList.remove('active')\n    })\n    $item.classList.add('active')\n\n    // 关闭层 (临时消失，取消 :hover)\n    $dropdown.style.display = 'none'\n    setTimeout(() => {\n      $dropdown.style.display = ''\n    }, 80)\n  }\n\n  // 生成列表元素\n  const $dropdown = Utils.createElement(`<ul class=\"atk-dropdown atk-fade-in\"></ul>`)\n  dropdownList.forEach((item, i) => {\n    const [name, action] = item\n\n    const $item = Utils.createElement(`<li class=\"atk-dropdown-item\"><span></span></li>`)\n    const $link = $item.querySelector<HTMLElement>('span')!\n    $link.innerText = name\n    $link.onclick = () => {\n      onItemClick(i, $item, name, action)\n    }\n    $dropdown.append($item)\n\n    if (i === curtActive) $item.classList.add('active') // 默认选中项\n  })\n\n  $dropdownWrap.append($dropdown)\n}\n\n/** 删除评论排序方式选择下拉菜单 */\nfunction removeDropdown(conf: { $dropdownWrap: HTMLElement }) {\n  const { $dropdownWrap } = conf\n  $dropdownWrap.classList.remove('atk-dropdown-wrap')\n  $dropdownWrap.querySelector('.atk-arrow-down-icon')?.remove()\n  $dropdownWrap.querySelector('.atk-dropdown')?.remove()\n}\n","import type { ArtalkPlugin } from '@/types'\nimport * as Utils from '@/lib/utils'\n\nexport const GotoDispatcher: ArtalkPlugin = (ctx) => {\n  let lastID = 0\n  const check = ({ locker }: { locker: boolean }) => {\n    const commentID = extractCommentID()\n    if (!commentID) return\n\n    if (locker && lastID === commentID) return // if the commentID is the same as the last one, do nothing\n    lastID = commentID // record the last commentID\n\n    ctx.trigger('list-goto', commentID) // trigger event\n  }\n\n  const hashChangeHandler = () => check({ locker: false })\n  const listLoadedHandler = () => check({ locker: true })\n  ctx.on('mounted', () => {\n    window.addEventListener('hashchange', hashChangeHandler)\n    ctx.on('list-loaded', listLoadedHandler)\n  })\n  ctx.on('unmounted', () => {\n    window.removeEventListener('hashchange', hashChangeHandler)\n    ctx.off('list-loaded', listLoadedHandler)\n  })\n}\n\nfunction extractCommentID(): number | null {\n  // Try get from hash\n  // Hash retrieval priority is higher than query,\n  // Because click goto will change hash.\n  const match = window.location.hash.match(/#atk-comment-([0-9]+)/)\n  let commentId =\n    match && match[1] && !Number.isNaN(parseFloat(match[1])) ? parseFloat(match[1]) : null\n\n  // Fail over to get from query\n  if (!commentId) {\n    commentId = Number(Utils.getQueryParam('atk_comment')) // same as backend GetReplyLink()\n  }\n\n  return commentId || null\n}\n","import type { ArtalkPlugin } from '@/types'\nimport * as Utils from '@/lib/utils'\nimport { sanitize } from '@/lib/sanitizer'\n\nexport const NoComment: ArtalkPlugin = (ctx) => {\n  const list = ctx.inject('list')\n  const conf = ctx.inject('config')\n\n  ctx.on('list-loaded', (comments) => {\n    // 无评论\n    const isNoComment = comments.length <= 0\n    let $noComment = list.getCommentsWrapEl().querySelector<HTMLElement>('.atk-list-no-comment')\n\n    if (isNoComment) {\n      if (!$noComment) {\n        $noComment = Utils.createElement('<div class=\"atk-list-no-comment\"></div>')\n\n        // sanitize before set innerHTML\n        $noComment.innerHTML = sanitize(conf.get().noComment || ctx.$t('noComment'))\n        list.getCommentsWrapEl().appendChild($noComment)\n      }\n    } else {\n      $noComment?.remove()\n    }\n  })\n}\n","import type { ArtalkPlugin } from '@/types'\nimport { version as ARTALK_VERSION } from '~/package.json'\n\nexport const Copyright: ArtalkPlugin = (ctx) => {\n  const list = ctx.inject('list')\n\n  ctx.on('mounted', () => {\n    const $copyright = list.getEl().querySelector<HTMLElement>('.atk-copyright')\n    if (!$copyright) return\n\n    $copyright.innerHTML =\n      `Powered By <a href=\"https://artalk.js.org\" ` +\n      `target=\"_blank\" title=\"Artalk v${ARTALK_VERSION}\">` +\n      `Artalk</a>`\n  })\n}\n","import type { ArtalkPlugin } from '@/types'\nimport * as Utils from '@/lib/utils'\n\n/** 评论时间自动更新 */\nexport const TimeTicking: ArtalkPlugin = (ctx) => {\n  const list = ctx.inject('list')\n  const conf = ctx.inject('config')\n  let timer: number | null = null\n\n  ctx.on('mounted', () => {\n    timer = window.setInterval(() => {\n      list\n        .getEl()\n        .querySelectorAll<HTMLElement>('[data-atk-comment-date]')\n        .forEach((el) => {\n          const date = new Date(Number(el.getAttribute('data-atk-comment-date')))\n          el.innerText = conf.get().dateFormatter?.(date) || Utils.timeAgo(date, ctx.$t)\n        })\n    }, 30 * 1000) // 30s 更新一次\n  })\n\n  ctx.on('unmounted', () => {\n    timer && window.clearInterval(timer)\n  })\n}\n","import type { ArtalkPlugin } from '@/types'\n\nexport const ReachBottom: ArtalkPlugin = (ctx) => {\n  const list = ctx.inject('list')\n  const conf = ctx.inject('config')\n  let observer: IntersectionObserver | null = null\n\n  const setupObserver = ($target: HTMLElement) => {\n    const scrollEvtAt = conf.get().scrollRelativeTo?.() || null\n\n    observer = new IntersectionObserver(\n      ([entries]) => {\n        if (entries.isIntersecting) {\n          clearObserver() // clear before trigger event to avoid trigger twice `list-reach-bottom`\n\n          // note that this event will be triggered only once\n          // until the next list is loaded\n          ctx.trigger('list-reach-bottom')\n        }\n      },\n      {\n        threshold: 0.9, // when the target is 90% visible\n\n        // @see https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/root\n        // If the root is null, then the bounds of the actual document viewport are used.\n        root: scrollEvtAt,\n      },\n    )\n    observer.observe($target)\n  }\n\n  const clearObserver = () => {\n    observer?.disconnect()\n    observer = null\n  }\n\n  ctx.on('list-loaded', () => {\n    clearObserver()\n\n    // get the second last child\n    const children = list.getCommentsWrapEl().childNodes\n    const $target = children.length > 2 ? (children[children.length - 2] as HTMLElement) : null\n    if (!$target) return\n\n    // check IntersectionObserver support\n    if (!('IntersectionObserver' in window)) {\n      console.warn('IntersectionObserver api not supported')\n      return\n    }\n\n    // use IntersectionObserver to detect reach bottom\n    setupObserver($target)\n  })\n\n  ctx.on('unmounted', () => {\n    clearObserver()\n  })\n}\n","import type { ArtalkPlugin } from '@/types'\nimport * as Utils from '@/lib/utils'\n\n/** List scroll to the first comment */\nexport const GotoFirst: ArtalkPlugin = (ctx) => {\n  const list = ctx.inject('list')\n  const conf = ctx.inject('config')\n\n  const handler = () => {\n    const $relative = conf.get().scrollRelativeTo?.()\n    ;($relative || window).scroll({\n      top: Utils.getOffset(list.getEl(), $relative).top,\n      left: 0,\n    })\n  }\n\n  ctx.on('mounted', () => {\n    ctx.on('list-goto-first', handler)\n  })\n\n  ctx.on('unmounted', () => {\n    ctx.off('list-goto-first', handler)\n  })\n}\n","import type { ArtalkPlugin, List } from '@/types'\nimport { version as ARTALK_VERSION } from '~/package.json'\nimport * as Utils from '@/lib/utils'\nimport $t from '@/i18n'\n\nlet IgnoreVersionCheck = false\n\nexport const VersionCheck: ArtalkPlugin = (ctx) => {\n  const list = ctx.inject('list')\n  ctx.watchConf(['apiVersion', 'versionCheck'], (conf) => {\n    if (conf.apiVersion && conf.versionCheck && !IgnoreVersionCheck)\n      versionCheck(list, ARTALK_VERSION, conf.apiVersion)\n  })\n}\n\nfunction versionCheck(list: List, feVer: string, beVer: string) {\n  const comp = Utils.versionCompare(feVer, beVer)\n  const sameVer = comp === 0\n  if (sameVer) return\n\n  const errEl = Utils.createElement(\n    `<div class=\"atk-version-check-notice\">${$t('updateMsg', {\n      name: comp < 0 ? $t('client') : $t('server'),\n    })} <span class=\"atk-info\">` +\n      `${$t('currentVersion')}: ${$t('client')} ${feVer} / ${$t('server')} ${beVer}` +\n      `</span></div>`,\n  )\n  const ignoreBtn = Utils.createElement(`<span class=\"atk-ignore-btn\">${$t('ignore')}</span>`)\n  ignoreBtn.onclick = () => {\n    errEl.remove()\n    IgnoreVersionCheck = true\n  }\n  errEl.append(ignoreBtn)\n  list.getEl().parentElement!.prepend(errEl)\n}\n","import type { ArtalkPlugin } from '@/types'\n\n// Notice: Singleton pattern needs to be loaded as lazy as possible,\n//         because the SSG application does not have a `window` context.\nlet darkModeMedia: MediaQueryList | undefined\n\nfunction updateClassnames($els: HTMLElement[], darkMode: boolean) {\n  const DarkModeClassName = 'atk-dark-mode'\n\n  $els.forEach(($el) => {\n    if (darkMode) $el.classList.add(DarkModeClassName)\n    else $el.classList.remove(DarkModeClassName)\n  })\n}\n\nexport const DarkMode: ArtalkPlugin = (ctx) => {\n  const conf = ctx.inject('config')\n  const layers = ctx.inject('layers')\n\n  // the handler bind to Artalk instance, don't forget to remove it when Artalk instance destroyed\n  let darkModeAutoHandler: ((evt: MediaQueryListEvent) => void) | undefined\n\n  const sync = (darkMode: boolean | 'auto') => {\n    // the elements that classnames need to be updated when darkMode changed\n    const $els = [ctx.getEl(), layers.getEl()]\n\n    // init darkModeMedia if not exists, and only create once\n    if (!darkModeMedia) {\n      darkModeMedia = window.matchMedia('(prefers-color-scheme: dark)')\n    }\n\n    if (darkMode === 'auto') {\n      // if darkMode is 'auto', add handler\n      if (!darkModeAutoHandler) {\n        // the handler that will be called when darkModeMedia changed\n        darkModeAutoHandler = (evt) => updateClassnames($els, evt.matches)\n        darkModeMedia.addEventListener('change', darkModeAutoHandler)\n      }\n\n      // update classnames immediately\n      updateClassnames($els, darkModeMedia.matches)\n    } else {\n      // if darkMode is boolean, remove handler\n      if (darkModeAutoHandler) {\n        darkModeMedia.removeEventListener('change', darkModeAutoHandler)\n        darkModeAutoHandler = undefined\n      }\n\n      // update classnames immediately\n      updateClassnames($els, darkMode)\n    }\n  }\n\n  ctx.watchConf(['darkMode'], (conf) => sync(conf.darkMode))\n  ctx.on('created', () => sync(conf.get().darkMode))\n  ctx.on('unmounted', () => {\n    // if handler exists, don't forget to remove it, or it will cause memory leak\n    darkModeAutoHandler && darkModeMedia?.removeEventListener('change', darkModeAutoHandler)\n    darkModeAutoHandler = undefined\n  })\n}\n","import type { ArtalkPlugin, ListFetchedArgs } from '@/types'\nimport type { Api } from '@/api'\nimport $t from '@/i18n'\n\ninterface PageVoteOptions {\n  /** Up Vote Button Selector */\n  upBtnEl: string\n\n  /** Down Vote Button Selector */\n  downBtnEl: string\n\n  /** Up Vote Count Selector */\n  upCountEl: string\n\n  /** Down Vote Count Selector */\n  downCountEl: string\n\n  /** Active class name if the vote is already cast */\n  activeClass?: string\n}\n\nconst defaults: PageVoteOptions = {\n  upBtnEl: '.artalk-page-vote-up',\n  downBtnEl: '.artalk-page-vote-down',\n  upCountEl: '.artalk-page-vote-up-count',\n  downCountEl: '.artalk-page-vote-down-count',\n  activeClass: 'active',\n}\n\ntype VoteBtnHandler = (evt: MouseEvent) => void\n\ninterface PageVoteState {\n  upBtnEl?: HTMLElement | null\n  downBtnEl?: HTMLElement | null\n  upCountEl?: HTMLElement | null\n  downCountEl?: HTMLElement | null\n  voteUpHandler?: VoteBtnHandler\n  voteDownHandler?: VoteBtnHandler\n  activeClass?: string\n}\n\nexport const PageVoteWidget: ArtalkPlugin = (ctx) => {\n  const conf = ctx.inject('config')\n  let state: PageVoteState = initState()\n  let cleanup: (() => void) | undefined\n\n  ctx.watchConf(['pageVote'], (conf) => {\n    const options = { ...defaults, ...(typeof conf.pageVote === 'object' ? conf.pageVote : {}) }\n\n    cleanup?.()\n    if (conf.pageVote) {\n      state = loadOptions(state, options, voteUpHandler, voteDownHandler)\n      cleanup = () => (state = resetState(state))\n    }\n  })\n\n  ctx.on('unmounted', () => {\n    cleanup?.()\n    ctx.off('list-fetched', listFetchedHandler)\n  })\n\n  ctx.on('list-fetched', listFetchedHandler)\n\n  // List fetched handler\n  let currPageId = 0\n  function listFetchedHandler({ data }: ListFetchedArgs) {\n    if (!conf.get().pageVote || !checkEls(state) || !data) return\n\n    if (currPageId !== data.page.id) {\n      // Initialize vote status in a new page\n      currPageId = data.page.id\n      updateVoteStatus(state, data.page.vote_up, data.page.vote_down, false, false) // reset initial status\n      fetchVoteStatus(state, currPageId, ctx.getApi())\n    } else {\n      // Update vote status in the same page\n      updateVoteStatus(state, data.page.vote_up, data.page.vote_down)\n    }\n  }\n\n  // Vote button click handlers\n  const handlerOptions = () => ({\n    state,\n    pageId: ctx.getData().getPage()?.id || 0,\n    httpApi: ctx.getApi(),\n  })\n  const voteUpHandler = voteBtnHandler('up', handlerOptions)\n  const voteDownHandler = voteBtnHandler('down', handlerOptions)\n}\n\nfunction loadOptions(\n  _state: PageVoteState,\n  opts: PageVoteOptions,\n  voteUpHandler: VoteBtnHandler,\n  voteDownHandler: VoteBtnHandler,\n): PageVoteState {\n  const state: PageVoteState = { ..._state } // clone to keep immutable\n  state.upBtnEl = document.querySelector<HTMLElement>(opts.upBtnEl)\n  state.downBtnEl = document.querySelector<HTMLElement>(opts.downBtnEl)\n  state.upCountEl = document.querySelector<HTMLElement>(opts.upCountEl)\n  state.downCountEl = document.querySelector<HTMLElement>(opts.downCountEl)\n  state.activeClass = opts.activeClass\n  state.voteUpHandler = voteUpHandler\n  state.voteDownHandler = voteDownHandler\n  state.upBtnEl?.addEventListener('click', voteUpHandler)\n  state.downBtnEl?.addEventListener('click', voteDownHandler)\n  return state\n}\n\nfunction checkEls(state: PageVoteState) {\n  return state.upBtnEl || state.downBtnEl || state.upCountEl || state.downCountEl\n}\n\nfunction initState(): PageVoteState {\n  return {}\n}\n\nfunction resetState(state: PageVoteState): PageVoteState {\n  state.voteUpHandler && state.upBtnEl?.removeEventListener('click', state.voteUpHandler)\n  state.voteDownHandler && state.downBtnEl?.removeEventListener('click', state.voteDownHandler)\n  return initState()\n}\n\nfunction updateVoteStatus(\n  state: PageVoteState,\n  up: number | string,\n  down: number | string,\n  isUp?: boolean,\n  isDown?: boolean,\n) {\n  // Up vote count\n  if (state.upCountEl) {\n    state.upCountEl.innerText = String(up)\n  } else if (state.upBtnEl) {\n    state.upBtnEl.innerText = `${$t('voteUp')} (${up})`\n  }\n\n  // Down vote count\n  if (state.downCountEl) {\n    state.downCountEl.innerText = String(down)\n  } else if (state.downBtnEl) {\n    state.downBtnEl.innerText = `${$t('voteDown')} (${down})`\n  }\n\n  if (typeof isUp === 'boolean')\n    state.upBtnEl?.classList.toggle(state.activeClass || 'active', isUp)\n  if (typeof isDown === 'boolean')\n    state.downBtnEl?.classList.toggle(state.activeClass || 'active', isDown)\n}\n\ninterface VoteBtnHandlerOptions {\n  state: PageVoteState\n  pageId: number\n  httpApi: Api\n}\n\nconst voteBtnHandler =\n  (choice: 'up' | 'down', options: () => VoteBtnHandlerOptions) => (evt: MouseEvent) => {\n    evt.preventDefault()\n    const { state, pageId, httpApi } = options()\n    if (!pageId) return\n    httpApi.votes\n      .createVote('page', pageId, choice, {\n        ...httpApi.getUserFields(),\n      })\n      .then(({ data }) => {\n        updateVoteStatus(state, data.up, data.down, data.is_up, data.is_down)\n      })\n      .catch((err) => {\n        window.alert($t('voteFail'))\n        console.error('[ArtalkPageVote]', err)\n      })\n  }\n\nfunction fetchVoteStatus(state: PageVoteState, pageId: number, httpApi: Api) {\n  httpApi.votes\n    .getVote('page', pageId)\n    .then(({ data }) => {\n      updateVoteStatus(state, data.up, data.down, data.is_up, data.is_down)\n    })\n    .catch((err) => {\n      console.error('[ArtalkPageVote]', err)\n    })\n}\n","import type { ArtalkPlugin } from '@/types'\nimport { Api, createApiHandlers } from '@/api'\nimport { convertApiOptions } from '@/config'\n\nexport const ApiService: ArtalkPlugin = (ctx) => {\n  ctx.provide('apiHandlers', () => createApiHandlers(), [] as const)\n  ctx.provide(\n    'api',\n    (user, config, apiHandlers) => new Api(convertApiOptions(config.get(), user, apiHandlers)),\n    ['user', 'config', 'apiHandlers'] as const,\n    {\n      lifecycle: 'transient',\n    },\n  )\n}\n","import type { LocalUser, UserManager as IUserManager } from '@/types'\n\nconst LOCAL_USER_KEY = 'ArtalkUser'\n\ninterface UserOpts {\n  onUserChanged?: (user: LocalUser) => void\n}\n\nexport class UserManager implements IUserManager {\n  private data: LocalUser\n\n  constructor(private opts: UserOpts) {\n    // Import from localStorage\n    const localUser = JSON.parse(window.localStorage.getItem(LOCAL_USER_KEY) || '{}')\n\n    // Initialize\n    this.data = {\n      name: localUser.name || localUser.nick || '', // nick is deprecated (for historical compatibility)\n      email: localUser.email || '',\n      link: localUser.link || '',\n      token: localUser.token || '',\n      is_admin: localUser.is_admin || localUser.isAdmin || false,\n    }\n  }\n\n  getData() {\n    return this.data\n  }\n\n  /** Update user data and save to localStorage */\n  update(obj: Partial<LocalUser> = {}) {\n    Object.entries(obj).forEach(([key, value]) => {\n      this.data[key] = value\n    })\n\n    window.localStorage.setItem(LOCAL_USER_KEY, JSON.stringify(this.data))\n    this.opts.onUserChanged && this.opts.onUserChanged(this.data)\n  }\n\n  /**\n   * Logout\n   *\n   * @description Logout will clear login status, but not clear user data (name, email, link)\n   */\n  logout() {\n    this.update({\n      token: '',\n      is_admin: false,\n    })\n  }\n\n  /** Check if user has filled basic data */\n  checkHasBasicUserInfo() {\n    return !!this.data.name && !!this.data.email\n  }\n}\n\nexport default UserManager\n","import type { CheckerCtx } from '.'\nimport $t from '@/i18n'\nimport * as Utils from '@/lib/utils'\nimport * as Ui from '@/lib/ui'\n\n/** 图片验证码 */\nexport function imgBody(checker: CheckerCtx) {\n  // 图片验证方式\n  const elem = Utils.createElement(\n    `<span><img class=\"atk-captcha-img\" src=\"${checker.get('img_data') || ''}\">${$t('captchaCheck')}</span>`,\n  )\n\n  // 刷新验证码\n  elem.querySelector<HTMLElement>('.atk-captcha-img')!.onclick = () => {\n    const imgEl = elem.querySelector('.atk-captcha-img')\n    checker\n      .getApi()\n      .captcha.getCaptcha()\n      .then((res) => {\n        imgEl!.setAttribute('src', res.data.img_data)\n      })\n      .catch((err) => {\n        console.error('Failed to get captcha image ', err)\n      })\n  }\n  return elem\n}\n\n/** iframe 形式的通用验证服务 */\nexport function iframeBody(checker: CheckerCtx) {\n  const $iframeWrap = Utils.createElement(`<div class=\"atk-checker-iframe-wrap\"></div>`)\n  const $iframe = Utils.createElement<HTMLIFrameElement>(\n    `<iframe class=\"atk-fade-in\" referrerpolicy=\"strict-origin-when-cross-origin\"></iframe>`,\n  )\n  $iframe.style.display = 'none'\n  Ui.showLoading($iframeWrap, { transparentBg: true })\n  $iframe.src = checker.getOpts().getCaptchaIframeURL()\n  $iframe.onload = () => {\n    $iframe.style.display = ''\n    Ui.hideLoading($iframeWrap)\n  }\n  $iframeWrap.append($iframe)\n\n  const $closeBtn = Utils.createElement(\n    `<div class=\"atk-close-btn\"><i class=\"atk-icon atk-icon-close\"></i></div>`,\n  )\n  $iframeWrap.append($closeBtn)\n\n  checker.hideInteractInput()\n\n  // 轮询状态\n  let stop = false // 打断\n  const sleep = (ms: number) =>\n    new Promise((resolve) => {\n      window.setTimeout(() => {\n        resolve(null)\n      }, ms)\n    })\n  ;(async function queryStatus() {\n    await sleep(1000)\n    if (stop) return\n    let isPass = false\n    try {\n      const resp = await checker.getApi().captcha.getCaptchaStatus()\n      isPass = resp.data.is_pass\n    } catch {\n      isPass = false\n    }\n    if (isPass) {\n      checker.triggerSuccess()\n    } else {\n      queryStatus()\n    }\n  })()\n\n  $closeBtn.onclick = () => {\n    stop = true\n    checker.cancel()\n  }\n\n  return $iframeWrap\n}\n","import * as render from './captcha-renders'\nimport type { Checker } from '.'\n\nconst CaptchaChecker: Checker = {\n  request(checker, inputVal) {\n    return checker.getApi().captcha.verifyCaptcha({\n      value: inputVal,\n    })\n  },\n\n  body(checker) {\n    if (checker.get('iframe')) return render.iframeBody(checker)\n    return render.imgBody(checker)\n  },\n\n  onSuccess(checker, data, inputVal, formEl) {\n    checker.set('val', inputVal)\n  },\n\n  onError(checker, err, inputVal, formEl) {\n    formEl.querySelector<HTMLElement>('.atk-captcha-img')!.click() // 刷新验证码\n    formEl.querySelector<HTMLInputElement>('input[type=\"text\"]')!.value = '' // 清空输入框输入\n  },\n}\n\nexport default CaptchaChecker\n","import type { Checker } from '.'\nimport $t from '@/i18n'\nimport * as Utils from '@/lib/utils'\n\nconst AdminChecker: Checker<{ token: string }> = {\n  inputType: 'password',\n\n  async request(checker, inputVal) {\n    return (\n      await checker.getApi().user.login({\n        name: checker.getUser().getData().name,\n        email: checker.getUser().getData().email,\n        password: inputVal,\n      })\n    ).data\n  },\n\n  body(checker) {\n    return Utils.createElement(`<span>${$t('adminCheck')}</span>`)\n  },\n\n  onSuccess(checker, res, inputVal, formEl) {\n    checker.getUser().update({\n      is_admin: true,\n      token: res.token,\n    })\n    checker.getOpts().onReload()\n  },\n\n  onError(checker, err, inputVal, formEl) {},\n}\n\nexport default AdminChecker\n","import * as Utils from '../lib/utils'\nimport $t from '@/i18n'\n\ntype BtnClickHandler = (btnEl: HTMLElement, dialog: Dialog) => boolean | void\n\n/**\n * 对话框\n */\nexport default class Dialog {\n  public $el: HTMLElement\n  public $content: HTMLElement\n  public $actions: HTMLElement\n\n  constructor(contentEl: HTMLElement) {\n    this.$el = Utils.createElement(\n      `<div class=\"atk-layer-dialog-wrap\">\n        <div class=\"atk-layer-dialog\">\n          <div class=\"atk-layer-dialog-content\"></div>\n          <div class=\"atk-layer-dialog-actions\"></div>\n        </div>\n      </div>`,\n    )\n\n    // 按钮\n    this.$actions = this.$el.querySelector<HTMLElement>('.atk-layer-dialog-actions')!\n\n    // 内容\n    this.$content = this.$el.querySelector('.atk-layer-dialog-content')!\n    this.$content.appendChild(contentEl)\n  }\n\n  /** 按钮 · 确定 */\n  public setYes(handler: BtnClickHandler) {\n    const btn = Utils.createElement<HTMLButtonElement>(\n      `<button data-action=\"confirm\">${$t('confirm')}</button>`,\n    )\n    btn.onclick = this.onBtnClick(handler)\n    this.$actions.appendChild(btn)\n\n    return this\n  }\n\n  /** 按钮 · 取消 */\n  public setNo(handler: BtnClickHandler) {\n    const btn = Utils.createElement<HTMLButtonElement>(\n      `<button data-action=\"cancel\">${$t('cancel')}</button>`,\n    )\n    btn.onclick = this.onBtnClick(handler)\n    this.$actions.appendChild(btn)\n\n    return this\n  }\n\n  private onBtnClick(handler: BtnClickHandler) {\n    return (evt: Event) => {\n      const re = handler(evt.currentTarget as HTMLElement, this)\n      if (re === undefined || re === true) {\n        this.$el.remove()\n      }\n    }\n  }\n}\n","import CaptchaChecker from './captcha'\nimport AdminChecker from './admin'\nimport type { Api } from '@/api'\nimport Dialog from '@/components/dialog'\nimport $t from '@/i18n'\nimport * as Utils from '@/lib/utils'\nimport type { UserManager, CheckerManager as ICheckerManager, LayerManager } from '@/types'\n\nexport interface CheckerCaptchaPayload extends CheckerPayload {\n  img_data?: string\n  iframe?: string\n}\n\nexport interface CheckerPayload {\n  onSuccess?: () => void\n  onMount?: (dialogEl: HTMLElement) => void\n  onCancel?: () => void\n}\n\nexport interface CheckerLauncherOptions {\n  getApi: () => Api\n  getLayers: () => LayerManager\n  getUser: () => UserManager\n  getCaptchaIframeURL: () => string\n  onReload: () => void\n}\n\nfunction wrapPromise<P extends CheckerPayload = CheckerPayload>(fn: (p: P) => void) {\n  return (payload: P) =>\n    new Promise<void>((resolve, reject) => {\n      const cancelFn = payload.onCancel\n      payload.onCancel = () => {\n        cancelFn && cancelFn()\n        reject(new Error('user canceled the checker'))\n      }\n      const successFn = payload.onSuccess\n      payload.onSuccess = () => {\n        successFn && successFn()\n        resolve()\n      }\n      fn(payload)\n    })\n}\n\n/**\n * Checker Launcher\n */\nexport class CheckerLauncher implements ICheckerManager {\n  constructor(private opts: CheckerLauncherOptions) {}\n\n  public checkCaptcha: (payload: CheckerCaptchaPayload) => Promise<void> = wrapPromise((p) => {\n    this.check(CaptchaChecker, p, (ctx) => {\n      ctx.set('img_data', p.img_data)\n      ctx.set('iframe', p.iframe)\n    })\n  })\n\n  public checkAdmin: (payload: CheckerPayload) => Promise<void> = wrapPromise((p) => {\n    this.check(AdminChecker, p)\n  })\n\n  public check(checker: Checker, payload: CheckerPayload, beforeCheck?: (c: CheckerCtx) => void) {\n    // 显示层\n    const layer = this.opts.getLayers().create(`checker-${new Date().getTime()}`)\n    layer.show()\n\n    const close = () => {\n      layer.destroy()\n    }\n\n    // 构建 Checker 的上下文\n    const checkerStore: CheckerStore = {}\n    let hideInteractInput = false\n    const checkerCtx: CheckerCtx = {\n      set: (key, val) => {\n        checkerStore[key] = val\n      },\n      get: (key) => checkerStore[key],\n      getOpts: () => this.opts,\n      getUser: () => this.opts.getUser(),\n      getApi: () => this.opts.getApi(),\n      hideInteractInput: () => {\n        hideInteractInput = true\n      },\n      triggerSuccess: () => {\n        close()\n        if (checker.onSuccess) checker.onSuccess(checkerCtx, '', '', formEl)\n        if (payload.onSuccess) payload.onSuccess()\n      },\n      cancel: () => {\n        close()\n        if (payload.onCancel) payload.onCancel()\n      },\n    }\n\n    if (beforeCheck) beforeCheck(checkerCtx)\n\n    // 创建表单\n    const formEl = Utils.createElement()\n    formEl.appendChild(checker.body(checkerCtx))\n\n    // 输入框\n    const $input = Utils.createElement<HTMLInputElement>(\n      `<input id=\"check\" type=\"${checker.inputType || 'text'}\" autocomplete=\"off\" required placeholder=\"\">`,\n    )\n    formEl.appendChild($input)\n    setTimeout(() => $input.focus(), 80) // 延迟 Focus\n\n    // 绑定键盘事件\n    $input.onkeyup = (evt) => {\n      if (evt.key === 'Enter' || evt.keyCode === 13) {\n        // 按下回车键\n        evt.preventDefault()\n        layer.getEl().querySelector<HTMLButtonElement>('button[data-action=\"confirm\"]')!.click()\n      }\n    }\n\n    let btnTextOrg: string | undefined\n    const dialog = new Dialog(formEl)\n\n    // 确认按钮\n    dialog.setYes((btnEl) => {\n      const inputVal = $input.value.trim()\n\n      // 按钮操作\n      if (!btnTextOrg) btnTextOrg = btnEl.innerText\n      const btnTextSet = (btnText: string) => {\n        btnEl.innerText = btnText\n        btnEl.classList.add('error')\n      }\n      const btnTextRestore = () => {\n        btnEl.innerText = btnTextOrg || ''\n        btnEl.classList.remove('error')\n      }\n\n      btnEl.innerText = `${$t('loading')}...`\n\n      // 发送请求\n      checker\n        .request(checkerCtx, inputVal)\n        .then((data) => {\n          // 请求成功\n          close()\n\n          if (checker.onSuccess) checker.onSuccess(checkerCtx, data, inputVal, formEl)\n          if (payload.onSuccess) payload.onSuccess()\n        })\n        .catch((err) => {\n          // 请求失败\n          btnTextSet(String(err.message || String(err)))\n\n          if (checker.onError) checker.onError(checkerCtx, err, inputVal, formEl)\n\n          // 错误显示 3s 后恢复按钮\n          const tf = setTimeout(() => btnTextRestore(), 3000)\n          $input.onfocus = () => {\n            btnTextRestore()\n            clearTimeout(tf)\n          }\n        })\n\n      return false\n    })\n\n    // 取消按钮\n    dialog.setNo(() => {\n      close()\n      if (payload.onCancel) payload.onCancel()\n      return false\n    })\n\n    if (hideInteractInput) {\n      $input.style.display = 'none'\n      dialog.$el.querySelector<HTMLElement>('.atk-layer-dialog-actions')!.style.display = 'none'\n    }\n\n    // 层装载 dialog 元素\n    layer.getEl().append(dialog.$el)\n\n    // onMount 回调\n    if (payload.onMount) payload.onMount(dialog.$el)\n  }\n}\n\nexport interface Checker<T = any> {\n  el?: HTMLElement\n  inputType?: 'password' | 'text'\n  body: (checker: CheckerCtx) => HTMLElement\n  request: (checker: CheckerCtx, inputVal: string) => Promise<T>\n  onSuccess?: (checker: CheckerCtx, respData: T, inputVal: string, formEl: HTMLElement) => void\n  onError?: (checker: CheckerCtx, errData: any, inputVal: string, formEl: HTMLElement) => void\n}\n\ninterface CheckerStore {\n  val?: string\n  img_data?: string\n  iframe?: string\n}\n\nexport interface CheckerCtx {\n  get<K extends keyof CheckerStore>(key: K): CheckerStore[K]\n  set<K extends keyof CheckerStore>(key: K, val: CheckerStore[K]): void\n  getOpts(): CheckerLauncherOptions\n  getApi(): Api\n  getUser(): UserManager\n  hideInteractInput(): void\n  triggerSuccess(): void\n  cancel(): void\n}\n","import type { ArtalkPlugin } from '@/types'\nimport { CheckerLauncher } from '@/components/checker'\n\nexport const CheckersService: ArtalkPlugin = (ctx) => {\n  ctx.provide(\n    'checkers',\n    (api, apiHandlers, layers, user, config) => {\n      const checkers = new CheckerLauncher({\n        getApi: () => api,\n        getLayers: () => layers,\n        getUser: () => user,\n        onReload: () => ctx.reload(),\n\n        // make sure suffix with a slash, because it will be used as a base url when call `fetch`\n        getCaptchaIframeURL: () => `${config.get().server}/api/v2/captcha/?t=${+new Date()}`,\n      })\n\n      apiHandlers.add('need_captcha', (res) => checkers.checkCaptcha(res))\n      apiHandlers.add('need_login', () => checkers.checkAdmin({}))\n\n      return checkers\n    },\n    ['api', 'apiHandlers', 'layers', 'user', 'config'] as const,\n  )\n}\n","import * as Utils from '../lib/utils'\nimport EditorHTML from './editor.html?raw'\n\nconst Sel = {\n  $header: '.atk-header',\n  $name: '.atk-header [name=\"name\"]',\n  $email: '.atk-header [name=\"email\"]',\n  $link: '.atk-header [name=\"link\"]',\n  $textareaWrap: '.atk-textarea-wrap',\n  $textarea: '.atk-textarea',\n  $bottom: '.atk-bottom',\n  $submitBtn: '.atk-send-btn',\n  $notifyWrap: '.atk-notify-wrap',\n  $bottomLeft: '.atk-bottom-left',\n  $stateWrap: '.atk-state-wrap',\n  $plugBtnWrap: '.atk-plug-btn-wrap',\n  $plugPanelWrap: '.atk-plug-panel-wrap',\n}\n\nexport interface EditorUI extends Record<keyof typeof Sel, HTMLElement> {\n  $el: HTMLElement\n  $name: HTMLInputElement\n  $email: HTMLInputElement\n  $link: HTMLInputElement\n  $textarea: HTMLTextAreaElement\n  $submitBtn: HTMLButtonElement\n  $sendReplyBtn?: HTMLElement\n  $editCancelBtn?: HTMLElement\n}\n\nexport function render() {\n  const $el = Utils.createElement(EditorHTML)\n  const ui = { $el }\n  Object.entries(Sel).forEach(([k, sel]) => {\n    ui[k] = $el.querySelector(sel)\n  })\n  return ui as EditorUI\n}\n","import Mover from '../plugins/editor/mover'\nimport type { EditorState, CommentData, Editor } from '@/types'\nimport * as Ui from '@/lib/ui'\n\nexport class EditorStateManager {\n  constructor(private editor: Editor) {}\n\n  private stateCurt: EditorState = 'normal'\n  private stateUnmountFn: (() => void) | null = null\n\n  /** Get current state */\n  get() {\n    return this.stateCurt\n  }\n\n  /**\n   * Switch editor state\n   *\n   * @param state The state to switch\n   * @param payload The cause of state switch\n   */\n  switch(state: EditorState, payload?: { $comment: HTMLElement; comment: CommentData }) {\n    // trigger unmount\n    if (this.stateUnmountFn) {\n      this.stateUnmountFn()\n      this.stateUnmountFn = null\n\n      // move editor back to the initial position\n      this.editor.getPlugins()?.get(Mover)?.back()\n    }\n\n    // invoke effect function and save unmount function\n    if (state !== 'normal' && payload) {\n      // move editor position\n      let moveAfterEl = payload.$comment\n      if (!this.editor.getOptions().getConf().get().flatMode)\n        moveAfterEl = moveAfterEl.querySelector<HTMLElement>('.atk-footer')!\n      this.editor.getPlugins()?.get(Mover)?.move(moveAfterEl)\n\n      const $relative = this.editor.getOptions().getConf().get().scrollRelativeTo?.()\n      Ui.scrollIntoView(this.editor.getUI().$el, true, $relative)\n\n      const plugin = this.editor\n        .getPlugins()\n        ?.getPlugins()\n        .find((p) => p.editorStateEffectWhen === state)\n      if (plugin && plugin.editorStateEffect) {\n        this.stateUnmountFn = plugin.editorStateEffect(payload.comment)\n      }\n    }\n\n    // change current state\n    this.stateCurt = state\n  }\n}\n","import * as Ui from '../lib/ui'\nimport marked from '../lib/marked'\nimport { render, type EditorUI } from './ui'\nimport { EditorStateManager } from './state'\nimport type { ConfigManager, CommentData, Editor as IEditor, EventManager } from '@/types'\nimport type { PluginManager } from '@/plugins/editor-kit'\n\nexport interface EditorOptions {\n  getEvents: () => EventManager\n  getConf: () => ConfigManager\n}\n\nexport class Editor implements IEditor {\n  private opts: EditorOptions\n  private $el: HTMLElement\n  private ui: EditorUI\n  private state: EditorStateManager\n  private plugins?: PluginManager\n\n  constructor(opts: EditorOptions) {\n    this.opts = opts\n\n    // init editor ui\n    this.ui = render()\n    this.$el = this.ui.$el\n\n    // init state manager\n    this.state = new EditorStateManager(this)\n  }\n\n  getOptions() {\n    return this.opts\n  }\n\n  getEl() {\n    return this.$el\n  }\n\n  getUI() {\n    return this.ui\n  }\n\n  getPlugins() {\n    return this.plugins\n  }\n\n  setPlugins(plugins: PluginManager) {\n    this.plugins = plugins\n  }\n\n  getState() {\n    return this.state.get()\n  }\n\n  getHeaderInputEls() {\n    return { name: this.ui.$name, email: this.ui.$email, link: this.ui.$link }\n  }\n\n  getContentFinal() {\n    let content = this.getContentRaw()\n\n    // plugin hook: final content transformer\n    const plugins = this.getPlugins()\n    if (plugins) content = plugins.getTransformedContent(content)\n\n    return content\n  }\n\n  getContentRaw() {\n    return this.ui.$textarea.value || ''\n  }\n\n  getContentMarked() {\n    return marked(this.getContentFinal())\n  }\n\n  setContent(val: string) {\n    this.ui.$textarea.value = val\n\n    // plug hook: content updated\n    this.getPlugins()?.getEvents().trigger('content-updated', val)\n  }\n\n  insertContent(val: string) {\n    if ((document as any).selection) {\n      this.ui.$textarea.focus()\n      ;(document as any).selection.createRange().text = val\n      this.ui.$textarea.focus()\n    } else if (this.ui.$textarea.selectionStart || this.ui.$textarea.selectionStart === 0) {\n      const sStart = this.ui.$textarea.selectionStart\n      const sEnd = this.ui.$textarea.selectionEnd\n      const sT = this.ui.$textarea.scrollTop\n      this.setContent(\n        this.ui.$textarea.value.substring(0, sStart) +\n          val +\n          this.ui.$textarea.value.substring(sEnd, this.ui.$textarea.value.length),\n      )\n      this.ui.$textarea.focus()\n      this.ui.$textarea.selectionStart = sStart + val.length\n      this.ui.$textarea.selectionEnd = sStart + val.length\n      this.ui.$textarea.scrollTop = sT\n    } else {\n      this.ui.$textarea.focus()\n      this.ui.$textarea.value += val\n    }\n  }\n\n  focus() {\n    this.ui.$textarea.focus()\n  }\n\n  reset() {\n    this.setContent('')\n    this.resetState()\n  }\n\n  resetState() {\n    this.state.switch('normal')\n  }\n\n  setReplyComment(comment: CommentData, $comment: HTMLElement) {\n    this.state.switch('reply', { comment, $comment })\n  }\n\n  setEditComment(comment: CommentData, $comment: HTMLElement) {\n    this.state.switch('edit', { comment, $comment })\n  }\n\n  showNotify(msg: string, type: any) {\n    Ui.showNotify(this.ui.$notifyWrap, msg, type)\n  }\n\n  showLoading() {\n    Ui.showLoading(this.ui.$el)\n  }\n\n  hideLoading() {\n    Ui.hideLoading(this.ui.$el)\n  }\n\n  submit() {\n    const next = () => {\n      this.getPlugins()?.getEvents().trigger('editor-submit')\n      this.opts.getEvents().trigger('editor-submit')\n    }\n    const beforeSubmit = this.opts.getConf().get().beforeSubmit\n    if (beforeSubmit) {\n      beforeSubmit(this, next)\n    } else {\n      next()\n    }\n  }\n}\n","export default \"<div class=\\\"atk-main-editor\\\">\\n  <div class=\\\"atk-header\\\">\\n    <input name=\\\"name\\\" class=\\\"atk-name\\\" type=\\\"text\\\" required=\\\"required\\\" />\\n    <input name=\\\"email\\\" class=\\\"atk-email\\\" type=\\\"email\\\" required=\\\"required\\\" />\\n    <input name=\\\"link\\\" class=\\\"atk-link\\\" type=\\\"url\\\" />\\n  </div>\\n  <div class=\\\"atk-textarea-wrap\\\">\\n    <textarea class=\\\"atk-textarea\\\"></textarea>\\n  </div>\\n  <div class=\\\"atk-plug-panel-wrap\\\" style=\\\"display: none\\\"></div>\\n  <div class=\\\"atk-bottom\\\">\\n    <div class=\\\"atk-item atk-bottom-left\\\">\\n      <span class=\\\"atk-state-wrap\\\"></span>\\n      <span class=\\\"atk-plug-btn-wrap\\\"></span>\\n    </div>\\n    <div class=\\\"atk-item\\\">\\n      <button type=\\\"button\\\" class=\\\"atk-send-btn\\\"></button>\\n    </div>\\n  </div>\\n  <div class=\\\"atk-notify-wrap\\\"></div>\\n</div>\\n\"","import type {\n  NotifyData,\n  PageData,\n  CommentData,\n  DataManager as IDataManager,\n  ListFetchParams,\n  ListLastFetchData,\n  EventManager,\n} from '@/types'\n\nexport class DataManager implements IDataManager {\n  /** Loading status */\n  private loading: boolean = false\n\n  /** List last fetch data */\n  private listLastFetch?: ListLastFetchData\n\n  /** Comment list (Flatten list and unordered) */\n  private comments: CommentData[] = []\n\n  /** Notify list */\n  private notifies: NotifyData[] = []\n\n  /** Page data */\n  private page?: PageData\n\n  constructor(protected events: EventManager) {}\n\n  getLoading() {\n    return this.loading\n  }\n\n  setLoading(val: boolean) {\n    this.loading = val\n  }\n\n  getListLastFetch() {\n    return this.listLastFetch\n  }\n\n  setListLastFetch(val: ListLastFetchData) {\n    this.listLastFetch = val\n  }\n\n  // -------------------------------------------------------------------\n  //  Comments\n  // -------------------------------------------------------------------\n  getComments() {\n    return this.comments\n  }\n\n  fetchComments(params: Partial<ListFetchParams>) {\n    this.events.trigger('list-fetch', params)\n  }\n\n  findComment(id: number) {\n    return this.comments.find((c) => c.id === id)\n  }\n\n  clearComments() {\n    this.comments = []\n    this.events.trigger('list-loaded', this.comments)\n  }\n\n  loadComments(partialComments: CommentData[]) {\n    this.events.trigger('list-load', partialComments)\n\n    this.comments.push(...partialComments)\n\n    this.events.trigger('list-loaded', this.comments)\n  }\n\n  insertComment(comment: CommentData) {\n    this.comments.push(comment)\n\n    this.events.trigger('comment-inserted', comment)\n    this.events.trigger('list-loaded', this.comments) // list-loaded should always keep the last\n  }\n\n  updateComment(comment: CommentData) {\n    this.comments = this.comments.map((c) => {\n      if (c.id === comment.id) return comment\n      return c\n    })\n\n    this.events.trigger('comment-updated', comment)\n    this.events.trigger('list-loaded', this.comments)\n  }\n\n  deleteComment(id: number) {\n    const comment = this.comments.find((c) => c.id === id)\n    if (!comment) throw new Error(`Comment ${id} not found`)\n    this.comments = this.comments.filter((c) => c.id !== id)\n\n    this.events.trigger('comment-deleted', comment)\n    this.events.trigger('list-loaded', this.comments)\n  }\n\n  // -------------------------------------------------------------------\n  //  Notifies\n  // -------------------------------------------------------------------\n  getNotifies() {\n    return this.notifies\n  }\n\n  updateNotifies(notifies: NotifyData[]) {\n    this.notifies = notifies\n\n    this.events.trigger('notifies-updated', this.notifies)\n  }\n\n  // -------------------------------------------------------------------\n  // Page\n  // -------------------------------------------------------------------\n  getPage() {\n    return this.page\n  }\n\n  updatePage(pageData: PageData) {\n    this.page = pageData\n\n    this.events.trigger('page-loaded', pageData)\n  }\n}\n","import type { Layer as ILayer } from '@/types/layer'\n\nexport interface LayerOptions {\n  onShow: () => void\n  onHide: () => void\n}\n\nexport class Layer implements ILayer {\n  private allowMaskClose = true\n  private onAfterHide?: () => void\n\n  constructor(\n    private $el: HTMLElement,\n    private opts: LayerOptions,\n  ) {}\n\n  setOnAfterHide(func: () => void) {\n    this.onAfterHide = func\n  }\n\n  setAllowMaskClose(allow: boolean) {\n    this.allowMaskClose = allow\n  }\n\n  getAllowMaskClose() {\n    return this.allowMaskClose\n  }\n\n  getEl() {\n    return this.$el\n  }\n\n  show() {\n    this.opts.onShow()\n    this.$el.style.display = ''\n  }\n\n  hide() {\n    this.opts.onHide()\n    this.$el.style.display = 'none'\n    this.onAfterHide && this.onAfterHide()\n  }\n\n  destroy() {\n    this.opts.onHide()\n    this.$el.remove()\n    this.onAfterHide && this.onAfterHide()\n  }\n}\n","import * as Ui from '@/lib/ui'\n\nlet bodyOrgOverflow: string\nlet bodyOrgPaddingRight: string\n\nexport function getScrollbarHelper() {\n  return {\n    init() {\n      bodyOrgOverflow = document.body.style.overflow\n      bodyOrgPaddingRight = document.body.style.paddingRight\n    },\n\n    unlock() {\n      document.body.style.overflow = bodyOrgOverflow\n      document.body.style.paddingRight = bodyOrgPaddingRight\n    },\n\n    lock() {\n      document.body.style.overflow = 'hidden'\n      const barPaddingRight = parseInt(\n        window.getComputedStyle(document.body, null).getPropertyValue('padding-right'),\n        10,\n      )\n      document.body.style.paddingRight = `${Ui.getScrollBarWidth() + barPaddingRight || 0}px`\n    },\n  }\n}\n","import { getScrollbarHelper } from './scrollbar-helper'\nimport { Layer } from './layer'\nimport * as Utils from '@/lib/utils'\n\nexport class LayerWrap {\n  private $wrap: HTMLElement\n  private $mask: HTMLElement\n  private items: Layer[] = []\n\n  constructor() {\n    this.$wrap = Utils.createElement(\n      `<div class=\"atk-layer-wrap\" style=\"display: none;\"><div class=\"atk-layer-mask\"></div></div>`,\n    )\n    this.$mask = this.$wrap.querySelector<HTMLElement>('.atk-layer-mask')!\n  }\n\n  createItem(name: string, el?: HTMLElement) {\n    // init element\n    el = el || this.createItemElement(name)\n    el.setAttribute('data-layer-name', name)\n    this.$wrap.appendChild(el)\n\n    // create layer instance\n    const layer = new Layer(el, {\n      onHide: () => this.hideWrap(el!),\n      onShow: () => this.showWrap(),\n    })\n\n    // register mask click event\n    this.getMask().addEventListener('click', () => {\n      layer.getAllowMaskClose() && layer.hide()\n    })\n\n    // add to items\n    this.items.push(layer)\n\n    return layer\n  }\n\n  private createItemElement(name: string) {\n    const el = document.createElement('div')\n    el.classList.add('atk-layer-item')\n    el.style.display = 'none'\n    this.$wrap.appendChild(el)\n    return el\n  }\n\n  getWrap() {\n    return this.$wrap\n  }\n\n  getMask() {\n    return this.$mask\n  }\n\n  showWrap() {\n    this.$wrap.style.display = 'block'\n    this.$mask.style.display = 'block'\n    this.$mask.classList.add('atk-fade-in')\n    getScrollbarHelper().lock()\n  }\n\n  hideWrap($el: HTMLElement) {\n    // if wrap contains more than one item, do not hide entire wrap\n    if (\n      this.items\n        .map((l) => l.getEl())\n        .filter((e) => e !== $el && e.isConnected && e.style.display !== 'none').length > 0\n    ) {\n      return\n    }\n\n    this.$wrap.style.display = 'none'\n    getScrollbarHelper().unlock()\n  }\n}\n","import { getScrollbarHelper } from './scrollbar-helper'\nimport { LayerWrap } from './wrap'\nimport type { LayerManager as ILayerManager } from '@/types'\n\nexport class LayerManager implements ILayerManager {\n  private wrap = new LayerWrap()\n\n  constructor() {\n    getScrollbarHelper().init()\n  }\n\n  getEl() {\n    return this.wrap.getWrap()\n  }\n\n  create(name: string, el?: HTMLElement) {\n    return this.wrap.createItem(name, el)\n  }\n\n  destroy() {\n    this.wrap.getWrap().remove()\n  }\n}\n","import type { LayoutStrategyCreator } from '.'\nimport type { CommentNode } from '@/comment'\nimport * as ListNest from '@/list/nest'\n\nexport const createNestStrategy: LayoutStrategyCreator = (opts) => ({\n  import: (comments) => {\n    // 遍历 root 评论\n    const rootNodes = ListNest.makeNestCommentNodeList(comments, opts.nestSortBy, opts.nestMax)\n    rootNodes.forEach((rootNode: ListNest.CommentNode) => {\n      const rootC = opts.createCommentNode(rootNode.comment)\n\n      // 显示并播放渐入动画\n      opts.$commentsWrap?.appendChild(rootC.getEl())\n      rootC.getRender().playFadeAnim()\n\n      // 加载子评论\n      const loadChildren = (parentC: CommentNode, parentNode: ListNest.CommentNode) => {\n        parentNode.children.forEach((node: ListNest.CommentNode) => {\n          const replyD = comments.find((c) => c.id === node.comment.rid)\n          const childD = node.comment\n          const childC = opts.createCommentNode(childD, replyD)\n\n          // 插入到父评论中\n          parentC.putChild(childC)\n\n          // 递归加载子评论\n          loadChildren(childC, node)\n        })\n      }\n      loadChildren(rootC, rootNode)\n\n      // 限高检测\n      rootC.getRender().checkHeightLimit()\n    })\n  },\n  insert: (comment, replyComment) => {\n    // 嵌套模式\n    const node = opts.createCommentNode(comment, replyComment)\n\n    if (comment.rid === 0) {\n      // root评论 新增\n      opts.$commentsWrap?.prepend(node.getEl())\n    } else {\n      // 子评论 新增\n      const parent = opts.findCommentNode(comment.rid)\n      if (parent) {\n        parent.putChild(node, opts.nestSortBy === 'DATE_ASC' ? 'append' : 'prepend')\n\n        // 若父评论存在 “子评论部分” 限高，取消限高\n        node.getParents().forEach((p) => {\n          p.getRender().heightLimitRemoveForChildren()\n        })\n      }\n    }\n\n    node.getRender().checkHeightLimit()\n\n    node.scrollIntoView() // 滚动到可以见\n    node.getRender().playFadeAnim() // 播放评论渐出动画\n  },\n})\n","import type { CommentData } from '@/types'\n\nexport type CommentNode = {\n  id: number\n  comment: CommentData\n  children: CommentNode[]\n  parent?: CommentNode\n  level: number\n}\n\nexport type SortByType = 'DATE_DESC' | 'DATE_ASC' | 'SRC_INDEX' | 'VOTE_UP_DESC'\n\n// 构建树状结构列表\nexport function makeNestCommentNodeList(\n  srcData: CommentData[],\n  sortBy: SortByType = 'DATE_DESC',\n  nestMax = 2,\n) {\n  const nodeList: CommentNode[] = []\n\n  const roots = srcData.filter((o) => o.rid === 0)\n  roots.forEach((root: CommentData) => {\n    const rootNode: CommentNode = {\n      id: root.id,\n      comment: root,\n      children: [],\n      level: 1,\n    }\n\n    rootNode.parent = rootNode\n    nodeList.push(rootNode)\n    ;(function loadChildren(parentNode: CommentNode) {\n      const children = srcData.filter((o) => o.rid === parentNode.id)\n      if (children.length === 0) return\n      if (parentNode.level >= nestMax) parentNode = parentNode.parent!\n      children.forEach((child: CommentData) => {\n        const childNode: CommentNode = {\n          id: child.id,\n          comment: child,\n          children: [],\n          parent: parentNode,\n          level: parentNode.level + 1,\n        }\n\n        parentNode.children.push(childNode)\n        loadChildren(childNode)\n      })\n    })(rootNode)\n  })\n\n  // 排序\n  const sortFunc = (a: CommentNode, b: CommentNode): number => {\n    let v = a.id - b.id\n    if (sortBy === 'DATE_ASC') v = +new Date(a.comment.date) - +new Date(b.comment.date)\n    else if (sortBy === 'DATE_DESC') v = +new Date(b.comment.date) - +new Date(a.comment.date)\n    else if (sortBy === 'SRC_INDEX') v = srcData.indexOf(a.comment) - srcData.indexOf(b.comment)\n    else if (sortBy === 'VOTE_UP_DESC') v = b.comment.vote_up - a.comment.vote_up\n    return v\n  }\n\n  ;(function sortLevels(nodes: CommentNode[]) {\n    nodes.forEach((node) => {\n      node.children = node.children.sort(sortFunc)\n      sortLevels(node.children)\n    })\n  })(nodeList)\n\n  return nodeList\n}\n","import type { LayoutStrategyCreator, LayoutOptions } from '.'\nimport type { CommentData } from '@/types'\n\nexport const createFlatStrategy: LayoutStrategyCreator = (opts) => ({\n  import: (comments) => {\n    comments.forEach((comment: CommentData) => {\n      const replyComment =\n        comment.rid === 0 ? undefined : comments.find((c) => c.id === comment.rid)\n      insertComment(opts, 'append', comment, replyComment)\n    })\n  },\n  insert: (comment, replyComment) => {\n    const node = insertComment(opts, 'prepend', comment, replyComment)\n    node.scrollIntoView()\n  },\n})\n\n/** 导入评论 · 平铺模式 */\nfunction insertComment(\n  opts: LayoutOptions,\n  insertMode: 'append' | 'prepend',\n  comment: CommentData,\n  replyComment?: CommentData | undefined,\n) {\n  if (comment.is_collapsed) comment.is_allow_reply = false\n  const node = opts.createCommentNode(comment, replyComment)\n\n  // 可见评论添加到界面\n  // 注：不可见评论用于显示 “引用内容”\n  if (comment.visible) {\n    const $comment = node.getEl()\n    const $listCommentsWrap = opts.$commentsWrap\n    if (insertMode === 'append') $listCommentsWrap?.append($comment)\n    if (insertMode === 'prepend') $listCommentsWrap?.prepend($comment)\n    node.getRender().playFadeAnim()\n  }\n\n  // 平铺评论插入后 · 内容限高检测\n  // 插入列表的评论 (visible=true) 和关联的评论 (visible=false) 都需要检测\n  node.getRender().checkHeightLimit()\n\n  return node\n}\n","import * as ListNest from '../nest'\nimport { createNestStrategy } from './nest'\nimport { createFlatStrategy } from './flat'\nimport type { CommentNode } from '@/comment'\nimport type { CommentData } from '@/types'\n\nexport interface LayoutOptions {\n  /** The comments wrap of list */\n  $commentsWrap: HTMLElement\n  nestSortBy: ListNest.SortByType\n  nestMax: number\n  flatMode: boolean\n\n  createCommentNode(comment: CommentData, replyComment?: CommentData): CommentNode\n  findCommentNode(id: number): CommentNode | undefined\n}\n\nexport interface LayoutStrategy {\n  import(comments: CommentData[]): void\n  insert(comment: CommentData, replyComment?: CommentData): void\n}\n\nexport type LayoutStrategyCreator = (opts: LayoutOptions) => LayoutStrategy\n\nexport class ListLayout {\n  constructor(private options: LayoutOptions) {}\n\n  private getStrategy() {\n    return this.options.flatMode\n      ? createFlatStrategy(this.options)\n      : createNestStrategy(this.options)\n  }\n\n  import(comments: CommentData[]) {\n    this.getStrategy().import(comments)\n  }\n\n  insert(comment: CommentData, replyComment?: CommentData) {\n    this.getStrategy().insert(comment, replyComment)\n  }\n}\n","import * as Utils from '../lib/utils'\nimport $t from '../i18n'\n\nexport interface IHeightLimitConf {\n  /** After expand btn click */\n  afterExpandBtnClick?: () => void\n  /** Allow Scroll */\n  scrollable?: boolean\n}\n\nexport interface IHeightLimitRule {\n  /** Target element need to check */\n  el: HTMLElement | null | undefined\n\n  /** Max height (unit: px) */\n  max: number\n\n  /** Whether or not the element contains `<img />` */\n  imgCheck?: boolean\n}\n\nexport type THeightLimitRuleSet = IHeightLimitRule[]\n\n/** Check all elements below the max height limit */\nexport function check(conf: IHeightLimitConf, rules: THeightLimitRuleSet) {\n  rules.forEach(({ el, max, imgCheck }) => {\n    if (!el) return\n\n    // set max height for avoiding img exceed the limit while loading\n    if (imgCheck) el.style.maxHeight = `${max + 1}px` // allow 1px more for next detecting\n\n    let lock = false\n    const _check = () => {\n      if (lock) return\n      if (Utils.getHeight(el) <= max) return // if not exceed the limit, do nothing\n\n      const afterExpandBtnClick = () => {\n        lock = true // add lock to prevent collapse again after expand when image lazy loaded\n        conf.afterExpandBtnClick?.()\n      }\n\n      !conf.scrollable\n        ? applyHeightLimit({ el, max, afterExpandBtnClick })\n        : applyScrollableHeightLimit({ el, max })\n    }\n\n    // check immediately\n    _check()\n\n    // check images after loaded\n    if (imgCheck) {\n      // check again when image loaded\n      const imgs = el.querySelectorAll<HTMLImageElement>('.atk-content img')\n      if (imgs.length === 0) el.style.maxHeight = ''\n      imgs.forEach((img) => {\n        img.onload = () => _check()\n      })\n    }\n  })\n}\n\n/** Height limit CSS class name */\nconst HEIGHT_LIMIT_CSS = 'atk-height-limit'\n\n/** Apply height limit on an element and add expand btn */\nexport function applyHeightLimit(obj: {\n  el: HTMLElement\n  max: number\n  afterExpandBtnClick?: (e: MouseEvent) => void\n}) {\n  if (!obj.el) return\n  if (!obj.max) return\n  if (obj.el.classList.contains(HEIGHT_LIMIT_CSS)) return\n\n  obj.el.classList.add(HEIGHT_LIMIT_CSS)\n  obj.el.style.height = `${obj.max}px`\n  obj.el.style.overflow = 'hidden'\n\n  /* Expand button */\n  const $expandBtn = Utils.createElement(\n    `<div class=\"atk-height-limit-btn\">${$t('readMore')}</span>`,\n  )\n  $expandBtn.onclick = (e) => {\n    e.stopPropagation()\n    disposeHeightLimit(obj.el)\n\n    if (obj.afterExpandBtnClick) obj.afterExpandBtnClick(e)\n  }\n  obj.el.append($expandBtn)\n}\n\n/** Dispose height limit on an element and remove expand btn */\nexport function disposeHeightLimit($el: HTMLElement) {\n  if (!$el) return\n  if (!$el.classList.contains(HEIGHT_LIMIT_CSS)) return\n\n  $el.classList.remove(HEIGHT_LIMIT_CSS)\n  Array.from($el.children).forEach((e) => {\n    if (e.classList.contains('atk-height-limit-btn')) e.remove()\n  })\n  $el.style.height = ''\n  $el.style.maxHeight = ''\n  $el.style.overflow = ''\n}\n\n/** Height limit scrollable CSS class name */\nconst HEIGHT_LIMIT_SCROLL_CSS = 'atk-height-limit-scroll'\n\n/** Apply scrollable height limit */\nexport function applyScrollableHeightLimit(opt: { el: HTMLElement; max: number }) {\n  if (!opt.el) return\n  if (opt.el.classList.contains(HEIGHT_LIMIT_SCROLL_CSS)) return\n  opt.el.classList.add(HEIGHT_LIMIT_SCROLL_CSS)\n  opt.el.style.height = `${opt.max}px`\n}\n","import * as Utils from '../../lib/utils'\nimport type Render from '../render'\nimport $t from '@/i18n'\n\n/**\n * 评论头部界面\n */\nexport default function renderHeader(r: Render) {\n  Object.entries({\n    renderNick,\n    renderVerifyBadge,\n    renderDate,\n    renderUABadge,\n  }).forEach(([name, render]) => {\n    render(r)\n  })\n}\n\nfunction renderNick(r: Render) {\n  r.$headerNick = r.$el.querySelector<HTMLElement>('.atk-nick')!\n\n  if (r.data.link) {\n    const $nickA = Utils.createElement<HTMLLinkElement>(\n      '<a target=\"_blank\" rel=\"noreferrer noopener nofollow\"></a>',\n    )\n    $nickA.innerText = r.data.nick\n    $nickA.href = Utils.isValidURL(r.data.link) ? r.data.link : `https://${r.data.link}`\n    r.$headerNick.append($nickA)\n  } else {\n    r.$headerNick.innerText = r.data.nick\n  }\n}\n\nfunction renderVerifyBadge(ctx: Render) {\n  ctx.$headerBadgeWrap = ctx.$el.querySelector<HTMLElement>('.atk-badge-wrap')!\n  ctx.$headerBadgeWrap.innerHTML = ''\n\n  const badgeText = ctx.data.badge_name\n  const badgeColor = ctx.data.badge_color\n  if (badgeText) {\n    const $badge = Utils.createElement(`<span class=\"atk-badge\"></span>`)\n    $badge.innerText = badgeText.replace('管理员', $t('admin')) // i18n patch\n    $badge.style.backgroundColor = badgeColor || ''\n    ctx.$headerBadgeWrap.append($badge)\n  } else if (ctx.data.is_verified) {\n    const $verifiedBadge = Utils.createElement(\n      `<span class=\"atk-icon-verified\" title=\"${$t('emailVerified')}\"></span>`,\n    ) // 邮箱验证徽章\n    ctx.$headerBadgeWrap.append($verifiedBadge)\n  }\n\n  if (ctx.data.is_pinned) {\n    const $pinnedBadge = Utils.createElement(`<span class=\"atk-pinned-badge\">${$t('pin')}</span>`) // 置顶徽章\n    ctx.$headerBadgeWrap.append($pinnedBadge)\n  }\n}\n\nfunction renderDate(ctx: Render) {\n  const $date = ctx.$el.querySelector<HTMLElement>('.atk-date')!\n  $date.innerText = ctx.comment.getDateFormatted()\n  $date.setAttribute('data-atk-comment-date', String(+new Date(ctx.data.date)))\n}\n\nfunction renderUABadge(ctx: Render) {\n  if (!ctx.opts.uaBadge && !ctx.data.ip_region) return\n\n  let $uaWrap = ctx.$header.querySelector('atk-ua-wrap')\n  if (!$uaWrap) {\n    $uaWrap = Utils.createElement(`<span class=\"atk-ua-wrap\"></span>`)\n    ctx.$header.append($uaWrap)\n  }\n\n  $uaWrap.innerHTML = ''\n\n  if (ctx.data.ip_region) {\n    const $regionBadge = Utils.createElement(`<span class=\"atk-region-badge\"></span>`)\n    $regionBadge.innerText = ctx.data.ip_region\n    $uaWrap.append($regionBadge)\n  }\n\n  if (ctx.opts.uaBadge) {\n    const { browser, os } = ctx.comment.getUserUA()\n    if (String(browser).trim()) {\n      const $uaBrowser = Utils.createElement(`<span class=\"atk-ua ua-browser\"></span>`)\n      $uaBrowser.innerText = browser\n      $uaWrap.append($uaBrowser)\n    }\n\n    if (String(os).trim()) {\n      const $usOS = Utils.createElement(`<span class=\"atk-ua ua-os\"></span>`)\n      $usOS.innerText = os\n      $uaWrap.append($usOS)\n    }\n  }\n}\n","import * as Utils from '../lib/utils'\nimport $t from '@/i18n'\n\ninterface ActionBtnOptions {\n  /** 按钮文字 (动态/静态) */\n  text: (() => string) | string\n\n  /** 仅管理员可用 */\n  adminOnly?: boolean\n\n  /** 确认操作 */\n  confirm?: boolean\n\n  /** 确认时提示文字 */\n  confirmText?: string\n}\n\n/**\n * 通用操作按钮\n */\nexport default class ActionBtn {\n  private opts: ActionBtnOptions\n  public $el: HTMLElement\n\n  public isLoading = false // 正在加载\n\n  public msgRecTimer?: number // 消息显示复原定时器\n  public msgRecTimerFunc?: () => void // 消息显示复原操作\n  public get isMessaging() {\n    return !!this.msgRecTimer\n  } // 消息正在显示\n\n  public isConfirming = false // 正在确认\n  public confirmRecTimer?: number // 确认消息复原定时器\n\n  /** 构造函数 */\n  constructor(opts: ActionBtnOptions | string | (() => string)) {\n    this.$el = Utils.createElement(`<span class=\"atk-common-action-btn\"></span>`)\n\n    this.opts = typeof opts !== 'object' ? { text: opts } : opts\n    this.$el.innerText = this.getText()\n\n    // 仅管理员可操作\n    if (this.opts.adminOnly) this.$el.setAttribute('atk-only-admin-show', '')\n  }\n\n  /** 将按钮装载到指定元素 */\n  public appendTo(dom: HTMLElement) {\n    dom.append(this.$el)\n    return this\n  }\n\n  /** 获取按钮文字（动态/静态） */\n  private getText() {\n    return typeof this.opts.text === 'string' ? this.opts.text : this.opts.text()\n  }\n\n  /** 设置点击事件 */\n  public setClick(func: () => void) {\n    this.$el.onclick = (e) => {\n      e.stopPropagation() // 防止穿透\n\n      // 按钮处于加载状态，禁止点击\n      if (this.isLoading) {\n        return\n      }\n\n      // 操作确认\n      if (this.opts.confirm && !this.isMessaging) {\n        const confirmRestore = () => {\n          this.isConfirming = false\n          this.$el.classList.remove('atk-btn-confirm')\n          this.$el.innerText = this.getText()\n        }\n\n        if (!this.isConfirming) {\n          this.isConfirming = true\n          this.$el.classList.add('atk-btn-confirm')\n          this.$el.innerText = this.opts.confirmText || $t('actionConfirm')\n          this.confirmRecTimer = window.setTimeout(() => confirmRestore(), 5000)\n          return\n        }\n\n        if (this.confirmRecTimer) window.clearTimeout(this.confirmRecTimer)\n        confirmRestore()\n      }\n\n      // 立刻释放掉原有的定时器（当显示消息后，用户立刻点击时）\n      if (this.msgRecTimer) {\n        this.fireMsgRecTimer()\n        this.clearMsgRecTimer()\n        return\n      }\n\n      // 触发设定的点击事件\n      func()\n    }\n  }\n\n  /** 文字刷新（动态/静态） */\n  public updateText(text?: (() => string) | string) {\n    if (text) this.opts.text = text\n    this.setLoading(false)\n    this.$el.innerText = this.getText()\n  }\n\n  /** 设置加载状态 */\n  public setLoading(value: boolean, loadingText?: string) {\n    if (this.isLoading === value) return\n    this.isLoading = value\n    if (value) {\n      this.$el.classList.add('atk-btn-loading')\n      this.$el.innerText = loadingText || `${$t('loading')}...`\n    } else {\n      this.$el.classList.remove('atk-btn-loading')\n      this.$el.innerText = this.getText()\n    }\n  }\n\n  /** 错误消息 */\n  public setError(text: string) {\n    this.setMsg(text, 'atk-btn-error')\n  }\n\n  /** 警告消息 */\n  public setWarn(text: string) {\n    this.setMsg(text, 'atk-btn-warn')\n  }\n\n  /** 成功消息 */\n  public setSuccess(text: string) {\n    this.setMsg(text, 'atk-btn-success')\n  }\n\n  /** 设置消息 */\n  public setMsg(text: string, className?: string, duringTime?: number, after?: () => void) {\n    this.setLoading(false)\n    if (className) this.$el.classList.add(className)\n    this.$el.innerText = text\n\n    // 设定复原 timer\n    this.setMsgRecTimer(() => {\n      this.$el.innerText = this.getText()\n      if (className) this.$el.classList.remove(className)\n      if (after) after()\n    }, duringTime || 2500) // 消息默认显示持续 2500s\n  }\n\n  /** 设置消息复原操作定时器 */\n  private setMsgRecTimer(func: () => void, duringTime: number) {\n    this.fireMsgRecTimer()\n    this.clearMsgRecTimer()\n\n    this.msgRecTimerFunc = func\n    this.msgRecTimer = window.setTimeout(() => {\n      func()\n      this.clearMsgRecTimer()\n    }, duringTime)\n  }\n\n  /** 立刻触发器复原定时器 */\n  private fireMsgRecTimer() {\n    if (this.msgRecTimerFunc) this.msgRecTimerFunc()\n  }\n\n  /** 仅清除 timer */\n  private clearMsgRecTimer() {\n    if (this.msgRecTimer) window.clearTimeout(this.msgRecTimer)\n    this.msgRecTimer = undefined\n    this.msgRecTimerFunc = undefined\n  }\n}\n","import ActionBtn from '../../components/action-btn'\nimport type Render from '../render'\nimport $t from '@/i18n'\n\n/**\n * 评论操作按钮界面\n */\nexport default function renderActions(r: Render) {\n  Object.entries({\n    renderVote,\n    renderReply,\n    // 管理员操作\n    renderCollapse,\n    renderModerator,\n    renderPin,\n    renderEdit,\n    renderDel,\n  }).forEach(([name, render]) => {\n    render(r)\n  })\n}\n\n// 操作按钮 - 投票\nfunction renderVote(r: Render) {\n  if (!r.opts.vote) return // 关闭投票功能\n\n  // 赞同按钮\n  r.voteBtnUp = new ActionBtn(() => `${$t('voteUp')} (${r.data.vote_up || 0})`).appendTo(r.$actions)\n  r.voteBtnUp.setClick(() => {\n    r.comment.getActions().vote('up')\n  })\n\n  // 反对按钮\n  if (r.opts.voteDown) {\n    r.voteBtnDown = new ActionBtn(() => `${$t('voteDown')} (${r.data.vote_down || 0})`).appendTo(\n      r.$actions,\n    )\n    r.voteBtnDown.setClick(() => {\n      r.comment.getActions().vote('down')\n    })\n  }\n}\n\n// 操作按钮 - 回复\nfunction renderReply(r: Render) {\n  if (!r.data.is_allow_reply) return // 不允许回复\n  const replyBtn = new ActionBtn({\n    text: $t('reply'),\n  })\n  replyBtn.appendTo(r.$actions)\n  replyBtn.setClick(() => {\n    r.opts.replyComment(r.data, r.$el)\n  })\n}\n\n// 操作按钮 - 折叠\nfunction renderCollapse(r: Render) {\n  const collapseBtn = new ActionBtn({\n    text: () => (r.data.is_collapsed ? $t('expand') : $t('collapse')),\n    adminOnly: true,\n  })\n  collapseBtn.appendTo(r.$actions)\n  collapseBtn.setClick(() => {\n    r.comment.getActions().adminEdit('collapsed', collapseBtn)\n  })\n}\n\n// 操作按钮 - 审核\nfunction renderModerator(r: Render) {\n  const pendingBtn = new ActionBtn({\n    text: () => (r.data.is_pending ? $t('pending') : $t('approved')),\n    adminOnly: true,\n  })\n  pendingBtn.appendTo(r.$actions)\n  pendingBtn.setClick(() => {\n    r.comment.getActions().adminEdit('pending', pendingBtn)\n  })\n}\n\n// 操作按钮 - 置顶\nfunction renderPin(r: Render) {\n  const pinnedBtn = new ActionBtn({\n    text: () => (r.data.is_pinned ? $t('unpin') : $t('pin')),\n    adminOnly: true,\n  })\n  pinnedBtn.appendTo(r.$actions)\n  pinnedBtn.setClick(() => {\n    r.comment.getActions().adminEdit('pinned', pinnedBtn)\n  })\n}\n\n// 操作按钮 - 编辑\nfunction renderEdit(r: Render) {\n  const editBtn = new ActionBtn({\n    text: $t('edit'),\n    adminOnly: true,\n  })\n  editBtn.appendTo(r.$actions)\n  editBtn.setClick(() => {\n    r.opts.editComment(r.data, r.$el)\n  })\n}\n\n// 操作按钮 - 删除\nfunction renderDel(r: Render) {\n  const delBtn = new ActionBtn({\n    text: $t('delete'),\n    confirm: true,\n    confirmText: $t('deleteConfirm'),\n    adminOnly: true,\n  })\n  delBtn.appendTo(r.$actions)\n  delBtn.setClick(() => {\n    r.comment.getActions().adminDelete(delBtn)\n  })\n}\n","import type Render from '../render'\nimport Avatar from './avatar'\nimport Header from './header'\nimport Content from './content'\nimport ReplyAt from './reply-at'\nimport ReplyTo from './reply-to'\nimport Pending from './pending'\nimport Actions from './actions'\n\nconst Renders = {\n  Avatar,\n  Header,\n  Content,\n  ReplyAt,\n  ReplyTo,\n  Pending,\n  Actions,\n}\n\nexport default function loadRenders(r: Render) {\n  Object.entries(Renders).forEach(([name, render]) => {\n    render(r)\n  })\n}\n","import * as Utils from '../../lib/utils'\nimport type Render from '../render'\n\n/**\n * 评论头像界面\n */\nexport default function renderAvatar(r: Render) {\n  const $avatar = r.$el.querySelector<HTMLElement>('.atk-avatar')!\n  const $avatarImg = Utils.createElement<HTMLImageElement>('<img />')\n\n  const avatarURLBuilder = r.opts.avatarURLBuilder\n  $avatarImg.src = avatarURLBuilder ? avatarURLBuilder(r.data) : r.comment.getGravatarURL()\n\n  if (r.data.link) {\n    const $avatarA = Utils.createElement<HTMLLinkElement>(\n      '<a target=\"_blank\" rel=\"noreferrer noopener nofollow\"></a>',\n    )\n    $avatarA.href = Utils.isValidURL(r.data.link) ? r.data.link : `https://${r.data.link}`\n    $avatarA.append($avatarImg)\n    $avatar.append($avatarA)\n  } else {\n    $avatar.append($avatarImg)\n  }\n}\n","import * as Utils from '../../lib/utils'\nimport * as Ui from '../../lib/ui'\nimport type Render from '../render'\nimport $t from '@/i18n'\n\n/**\n * 评论内容界面\n */\nexport default function renderContent(r: Render) {\n  if (!r.data.is_collapsed) {\n    r.$content.innerHTML = r.comment.getContentMarked()\n    r.$content.classList.remove('atk-hide', 'atk-collapsed')\n    return\n  }\n\n  // 内容 & 折叠\n  r.$content.classList.add('atk-hide', 'atk-type-collapsed')\n  const collapsedInfoEl = Utils.createElement(`\n    <div class=\"atk-collapsed\">\n      <span class=\"atk-text\">${$t('collapsedMsg')}</span>\n      <span class=\"atk-show-btn\">${$t('expand')}</span>\n    </div>`)\n  r.$body.insertAdjacentElement('beforeend', collapsedInfoEl)\n\n  const contentShowBtn = collapsedInfoEl.querySelector<HTMLElement>('.atk-show-btn')!\n  contentShowBtn.addEventListener('click', (e) => {\n    e.stopPropagation() // 防止穿透\n\n    if (r.$content.classList.contains('atk-hide')) {\n      r.$content.innerHTML = r.comment.getContentMarked()\n      r.$content.classList.remove('atk-hide')\n      Ui.playFadeInAnim(r.$content)\n      contentShowBtn.innerText = $t('collapse')\n    } else {\n      r.$content.innerHTML = ''\n      r.$content.classList.add('atk-hide')\n      contentShowBtn.innerText = $t('expand')\n    }\n  })\n}\n","import * as Utils from '../../lib/utils'\nimport type Render from '../render'\n\n/**\n * Reply user indicator (with arrow icon) in the comment meta header\n */\nexport default function renderReplyAt(r: Render) {\n  if (r.opts.flatMode || r.data.rid === 0) return // if not nested mode or root comment\n  if (!r.opts.replyTo) return // if no replyTo data\n\n  r.$replyAt = Utils.createElement(\n    `<span class=\"atk-item atk-reply-at\"><span class=\"atk-arrow\"></span><span class=\"atk-nick\"></span></span>`,\n  )\n  r.$replyAt.querySelector<HTMLElement>('.atk-nick')!.innerText = `${r.opts.replyTo.nick}`\n  r.$replyAt.onclick = () => {\n    r.comment.getActions().goToReplyComment()\n  }\n\n  r.$headerBadgeWrap.insertAdjacentElement('afterend', r.$replyAt)\n}\n","import type Render from '../render'\nimport * as Utils from '@/lib/utils'\nimport marked from '@/lib/marked'\nimport $t from '@/i18n'\n\n/**\n * 关联评论显示 (被回复的评论)\n */\nexport default function renderReplyTo(r: Render) {\n  if (!r.opts.flatMode) return // 仅平铺模式显示\n  if (!r.opts.replyTo) return\n\n  r.$replyTo = Utils.createElement(`\n    <div class=\"atk-reply-to\">\n      <div class=\"atk-meta\">${$t('reply')} <span class=\"atk-nick\"></span>:</div>\n      <div class=\"atk-content\"></div>\n    </div>`)\n\n  // Comment author name\n  const $nick = r.$replyTo.querySelector<HTMLElement>('.atk-nick')!\n  $nick.innerText = `@${r.opts.replyTo.nick}`\n  $nick.onclick = () => {\n    r.comment.getActions().goToReplyComment()\n  }\n\n  // Comment content\n  let replyContent = marked(r.opts.replyTo.content)\n  if (r.opts.replyTo.is_collapsed) replyContent = `[${$t('collapsed')}]`\n  r.$replyTo.querySelector<HTMLElement>('.atk-content')!.innerHTML = replyContent\n\n  // Mount the replyTo element\n  r.$body.prepend(r.$replyTo)\n}\n","import * as Utils from '../../lib/utils'\nimport type Render from '../render'\nimport $t from '@/i18n'\n\n/**\n * 待审核状态界面\n */\nexport default function renderPending(r: Render) {\n  if (!r.data.is_pending) return\n\n  const pendingEl = Utils.createElement(`<div class=\"atk-pending\">${$t('pendingMsg')}</div>`)\n  r.$body.prepend(pendingEl)\n}\n","import ActionBtn from '../components/action-btn'\nimport * as Utils from '../lib/utils'\nimport * as Ui from '../lib/ui'\n\nimport * as HeightLimit from './height-limit'\nimport CommentHTML from './comment.html?raw'\nimport loadRenders from './renders'\nimport type { CommentNode } from '.'\n\nexport default class Render {\n  public comment: CommentNode\n\n  public get data() {\n    return this.comment.getData()\n  }\n  public get opts() {\n    return this.comment.getOpts()\n  }\n\n  public $el!: HTMLElement\n  public $main!: HTMLElement\n  public $header!: HTMLElement\n  public $headerNick!: HTMLElement\n  public $headerBadgeWrap!: HTMLElement\n  public $body!: HTMLElement\n  public $content!: HTMLElement\n  public $childrenWrap!: HTMLElement | null\n  public $actions!: HTMLElement\n  public voteBtnUp?: ActionBtn\n  public voteBtnDown?: ActionBtn\n\n  public $replyTo?: HTMLElement // 回复评论内容 (平铺下显示)\n  public $replyAt?: HTMLElement // 回复 AT（层级嵌套下显示）\n\n  public constructor(comment: CommentNode) {\n    this.comment = comment\n  }\n\n  /**\n   * Render the comment ui\n   *\n   * If comment data is updated, call this method to re-render the comment ui.\n   * The method will be called multiple times, so it should be idempotent.\n   *\n   * Renders may add event listeners to the comment ui, so it should be called only once or override the original.\n   * Please be aware of the memory leak caused by the event listener.\n   */\n  public render() {\n    // init ui elements\n    this.$el = Utils.createElement(CommentHTML)\n\n    this.$main = this.$el.querySelector('.atk-main')!\n    this.$header = this.$el.querySelector('.atk-header')!\n    this.$body = this.$el.querySelector('.atk-body')!\n    this.$content = this.$body.querySelector('.atk-content')!\n    this.$actions = this.$el.querySelector('.atk-actions')!\n\n    this.$el.setAttribute('id', `atk-comment-${this.data.id}`)\n\n    // call all renders\n    loadRenders(this)\n\n    // append children wrap if exists\n    if (this.$childrenWrap) {\n      this.$main.append(this.$childrenWrap)\n    }\n\n    return this.$el\n  }\n\n  /** 内容限高检测 */\n  public checkHeightLimit() {\n    const conf = this.opts.heightLimit\n    if (!conf || !conf.content || !conf.children) return // 关闭限高\n\n    const contentMaxH = conf.content\n    const childrenMaxH = conf.children\n\n    HeightLimit.check(\n      {\n        afterExpandBtnClick: () => {\n          // 子评论数仅有 1，直接取消限高\n          const children = this.comment.getChildren()\n          if (children.length === 1)\n            HeightLimit.disposeHeightLimit(children[0].getRender().$content)\n        },\n        scrollable: conf.scrollable,\n      },\n      [\n        // 评论内容限高\n        { el: this.$content, max: contentMaxH, imgCheck: true },\n        { el: this.$replyTo, max: contentMaxH, imgCheck: true },\n        // 子评论区域限高（仅嵌套模式）\n        { el: this.$childrenWrap, max: childrenMaxH, imgCheck: false },\n      ],\n    )\n  }\n\n  /** 子评论区域移除限高 */\n  public heightLimitRemoveForChildren() {\n    if (!this.$childrenWrap) return\n    HeightLimit.disposeHeightLimit(this.$childrenWrap)\n  }\n\n  /** 渐出动画 */\n  playFadeAnim() {\n    Ui.playFadeInAnim(this.comment.getRender().$el)\n  }\n\n  /** 渐出动画 · 评论内容区域 */\n  playFadeAnimForBody() {\n    Ui.playFadeInAnim(this.comment.getRender().$body)\n  }\n\n  /** Perform the flash animation */\n  playFlashAnim() {\n    // Make sure the class is removed\n    this.$el.classList.remove('atk-flash-once')\n    window.setTimeout(() => {\n      // Add the class to perform the animation\n      this.$el.classList.add('atk-flash-once')\n    }, 150)\n  }\n\n  /** 获取子评论 Wrap */\n  public getChildrenWrap() {\n    if (!this.$childrenWrap) {\n      // if not exists, create a new one\n      this.$childrenWrap = Utils.createElement('<div class=\"atk-comment-children\"></div>')\n      this.$main.append(this.$childrenWrap)\n    }\n    return this.$childrenWrap\n  }\n\n  /** 设置已读 */\n  public setUnread(val: boolean) {\n    if (val) this.$el.classList.add('atk-unread')\n    else this.$el.classList.remove('atk-unread')\n  }\n\n  /** 设置为可点击的评论 */\n  public setOpenable(val: boolean) {\n    if (val) this.$el.classList.add('atk-openable')\n    else this.$el.classList.remove('atk-openable')\n  }\n\n  /** 设置点击评论打开置顶 URL */\n  public setOpenURL(url: string) {\n    this.setOpenable(true)\n    this.$el.onclick = (evt) => {\n      evt.stopPropagation()\n      window.open(url)\n    }\n  }\n\n  /** 设置点击评论时的操作 */\n  public setOpenAction(action: () => void) {\n    this.setOpenable(true)\n    this.$el.onclick = (evt) => {\n      evt.stopPropagation()\n      action()\n    }\n  }\n}\n","export default \"<div class=\\\"atk-comment-wrap\\\">\\n  <div class=\\\"atk-comment\\\">\\n    <div class=\\\"atk-avatar\\\"></div>\\n    <div class=\\\"atk-main\\\">\\n      <div class=\\\"atk-header\\\">\\n        <span class=\\\"atk-item atk-nick\\\"></span>\\n        <span class=\\\"atk-badge-wrap\\\"></span>\\n        <span class=\\\"atk-item atk-date\\\"></span>\\n      </div>\\n      <div class=\\\"atk-body\\\">\\n        <div class=\\\"atk-content\\\"></div>\\n      </div>\\n      <div class=\\\"atk-footer\\\">\\n        <div class=\\\"atk-actions\\\"></div>\\n      </div>\\n    </div>\\n  </div>\\n</div>\\n\"","import type { CommentNode } from '.'\nimport ActionBtn from '@/components/action-btn'\nimport $t from '@/i18n'\n\nexport default class CommentActions {\n  private comment: CommentNode\n\n  private get data() {\n    return this.comment.getData()\n  }\n  private get opts() {\n    return this.comment.getOpts()\n  }\n  private getApi() {\n    return this.comment.getOpts().getApi()\n  }\n\n  public constructor(comment: CommentNode) {\n    this.comment = comment\n  }\n\n  /** 投票操作 */\n  public vote(choice: 'up' | 'down') {\n    const actionBtn =\n      choice === 'up' ? this.comment.getRender().voteBtnUp : this.comment.getRender().voteBtnDown\n\n    this.getApi()\n      .votes.createVote('comment', this.data.id, choice, {\n        ...this.getApi().getUserFields(),\n      })\n      .then((res) => {\n        this.data.vote_up = res.data.up\n        this.data.vote_down = res.data.down\n        this.comment.getRender().voteBtnUp?.updateText()\n        this.comment.getRender().voteBtnDown?.updateText()\n      })\n      .catch((err) => {\n        actionBtn?.setError($t('voteFail'))\n        console.error(err)\n      })\n  }\n\n  /** 管理员 - 评论状态修改 */\n  public adminEdit(type: 'collapsed' | 'pending' | 'pinned', btnElem: ActionBtn) {\n    if (btnElem.isLoading) return // 若正在修改中\n\n    btnElem.setLoading(true, `${$t('editing')}...`)\n\n    // 克隆并修改当前数据\n    const modify = { ...this.data }\n    if (type === 'collapsed') {\n      modify.is_collapsed = !modify.is_collapsed\n    } else if (type === 'pending') {\n      modify.is_pending = !modify.is_pending\n    } else if (type === 'pinned') {\n      modify.is_pinned = !modify.is_pinned\n    }\n\n    this.getApi()\n      .comments.updateComment(this.data.id, {\n        ...modify,\n      })\n      .then((res) => {\n        btnElem.setLoading(false)\n\n        // 刷新当前 Comment UI\n        this.comment.setData(res.data)\n      })\n      .catch((err) => {\n        console.error(err)\n        btnElem.setError($t('editFail'))\n      })\n  }\n\n  /** 管理员 - 评论删除 */\n  public adminDelete(btnElem: ActionBtn) {\n    if (btnElem.isLoading) return // 若正在删除中\n\n    btnElem.setLoading(true, `${$t('deleting')}...`)\n    this.getApi()\n      .comments.deleteComment(this.data.id)\n      .then(() => {\n        btnElem.setLoading(false)\n        if (this.opts.onDelete) this.opts.onDelete(this.comment)\n      })\n      .catch((e) => {\n        console.error(e)\n        btnElem.setError($t('deleteFail'))\n      })\n  }\n\n  /** 快速跳转到该评论 */\n  public goToReplyComment() {\n    const origHash = window.location.hash\n    const modifyHash = `#atk-comment-${this.data.rid}`\n\n    window.location.hash = modifyHash\n    if (modifyHash === origHash) window.dispatchEvent(new Event('hashchange')) // 强制触发事件\n  }\n}\n","import type { Api } from '../api'\nimport * as Ui from '../lib/ui'\nimport * as Utils from '../lib/utils'\nimport marked from '../lib/marked'\nimport UADetect from '../lib/detect'\nimport CommentUI from './render'\nimport CommentActions from './actions'\nimport $t from '@/i18n'\nimport type { CommentData, Config, Context } from '@/types'\n\nexport interface CommentOptions {\n  // Hooks\n  onAfterRender?: () => void\n  onDelete?: (c: CommentNode) => void\n\n  /** The comment being replied to (linked comment) */\n  replyTo?: CommentData\n\n  // Referenced from ArtalkConfig\n  flatMode: boolean\n  vote: boolean\n  voteDown: boolean\n  uaBadge: boolean\n  nestMax: number\n  gravatar: Config['gravatar']\n  heightLimit: Config['heightLimit']\n  avatarURLBuilder: Config['avatarURLBuilder']\n  scrollRelativeTo: Config['scrollRelativeTo']\n  dateFormatter: Config['dateFormatter']\n\n  // TODO: Move to plugin folder and remove from core\n  getApi: () => Api\n  replyComment: Context['replyComment']\n  editComment: Context['editComment']\n}\n\nexport default class CommentNode {\n  $el?: HTMLElement\n\n  private renderInstance: CommentUI\n  private actionInstance: CommentActions\n\n  private data: CommentData\n  private opts: CommentOptions\n\n  private parent: CommentNode | null\n  private children: CommentNode[] = []\n\n  private nestCurt: number // 当前嵌套层数\n\n  constructor(data: CommentData, opts: CommentOptions) {\n    this.opts = opts\n    this.data = { ...data }\n    this.data.date = this.data.date.replace(/-/g, '/') // 解决 Safari 日期解析 NaN 问题\n\n    this.parent = null\n    this.nestCurt = 1 // 现在已嵌套 n 层\n\n    this.actionInstance = new CommentActions(this)\n    this.renderInstance = new CommentUI(this)\n  }\n\n  /** 渲染 UI */\n  public render() {\n    const newEl = this.renderInstance.render()\n\n    if (this.$el) this.$el.replaceWith(newEl)\n    this.$el = newEl\n    // Please be aware of the memory leak, the $el may be replaced multiple times.\n    // If somewhere else has a reference to the old $el, it will cause a memory leak.\n    // So it's limited to use the $el reference by `getEl()`.\n    // The `getEl()` will always return the latest $el.\n\n    if (this.opts.onAfterRender) this.opts.onAfterRender()\n  }\n\n  /** 获取评论操作实例对象 */\n  public getActions() {\n    return this.actionInstance\n  }\n\n  /** 获取评论渲染器实例对象 */\n  public getRender() {\n    return this.renderInstance\n  }\n\n  /** 获取评论数据 */\n  public getData() {\n    return this.data\n  }\n\n  /** 设置数据 */\n  public setData(data: CommentData) {\n    this.data = data\n\n    this.render()\n    this.getRender().playFadeAnimForBody()\n  }\n\n  /** 获取父评论 */\n  public getParent() {\n    return this.parent\n  }\n\n  /** 获取所有子评论 */\n  public getChildren() {\n    return this.children\n  }\n\n  /** 获取当前嵌套层数 */\n  public getNestCurt() {\n    return this.nestCurt\n  }\n\n  /** 判断是否为根评论 */\n  public getIsRoot() {\n    return this.data.rid === 0\n  }\n\n  /** 获取评论 ID */\n  public getID() {\n    return this.data.id\n  }\n\n  /** 置入子评论 */\n  public putChild(childNode: CommentNode, insertMode: 'append' | 'prepend' = 'append') {\n    childNode.parent = this\n    childNode.nestCurt = this.nestCurt + 1 // 嵌套层数 +1\n    this.children.push(childNode)\n\n    const $childrenWrap = this.getChildrenWrapEl()\n    const $childComment = childNode.getEl()\n    if (insertMode === 'append') $childrenWrap.append($childComment)\n    else if (insertMode === 'prepend') $childrenWrap.prepend($childComment)\n\n    childNode.getRender().playFadeAnim()\n    childNode.getRender().checkHeightLimit() // 内容限高\n  }\n\n  /** 获取存放子评论的元素对象 */\n  public getChildrenWrapEl(): HTMLElement {\n    // console.log(this.nestCurt)\n    if (this.nestCurt >= this.opts.nestMax) {\n      return this.parent!.getChildrenWrapEl()\n    }\n    return this.getRender().getChildrenWrap()\n  }\n\n  /** 获取所有父评论 */\n  public getParents() {\n    const flattenParents: CommentNode[] = []\n    let parent = this.parent\n    while (parent) {\n      flattenParents.push(parent)\n      parent = parent.getParent()\n    }\n    return flattenParents\n  }\n\n  /**\n   * Get the element of the comment\n   *\n   * The `getEl()` will always return the latest $el after calling `render()`.\n   * Please be aware of the memory leak if you use the $el reference directly.\n   */\n  public getEl() {\n    if (!this.$el) throw new Error('comment element not initialized before `getEl()`')\n    return this.$el\n  }\n\n  /**\n   * Focus on the comment\n   *\n   * Scroll to the comment and perform flash animation\n   */\n  focus() {\n    if (!this.$el) throw new Error('comment element not initialized before `focus()`')\n\n    // 若父评论存在 “子评论部分” 限高，取消限高\n    this.getParents().forEach((p) => {\n      p.getRender().heightLimitRemoveForChildren()\n    })\n\n    // Scroll to comment\n    this.scrollIntoView()\n\n    // Perform flash animation\n    this.getRender().playFlashAnim()\n  }\n\n  scrollIntoView() {\n    this.$el &&\n      Ui.scrollIntoView(this.$el, false, this.opts.scrollRelativeTo && this.opts.scrollRelativeTo())\n  }\n\n  /**\n   * Remove the comment node\n   */\n  remove() {\n    this.$el?.remove()\n  }\n\n  /** 获取 Gravatar 头像 URL */\n  public getGravatarURL() {\n    return Utils.getGravatarURL({\n      mirror: this.opts.gravatar.mirror,\n      params: this.opts.gravatar.params,\n      emailHash: this.data.email_encrypted,\n    })\n  }\n\n  /** 获取评论 markdown 解析后的内容 */\n  public getContentMarked() {\n    return marked(this.data.content)\n  }\n\n  /** 获取格式化后的日期 */\n  public getDateFormatted() {\n    const date = new Date(this.data.date)\n    return this.opts.dateFormatter?.(date) || Utils.timeAgo(date, $t)\n  }\n\n  /** 获取用户 UserAgent 信息 */\n  public getUserUA() {\n    const info = UADetect(this.data.ua)\n    return {\n      browser: `${info.browser} ${info.version}`,\n      os: `${info.os} ${info.osVersion}`,\n    }\n  }\n\n  /** 获取配置 */\n  public getOpts() {\n    return this.opts\n  }\n}\n","function Detect(userAgent?: string) {\n  const win = (window as any) || {}\n  const nav = navigator || {}\n\n  const u = String(userAgent || nav.userAgent)\n  const dest = {\n    os: '',\n    osVersion: '',\n    engine: '',\n    browser: '',\n    device: '',\n    language: '',\n    version: ''\n  }\n\n  // 内核\n  const engineMatch = {\n    Trident: u.includes('Trident') || u.includes('NET CLR'),\n    Presto: u.includes('Presto'),\n    WebKit: u.includes('AppleWebKit'),\n    Gecko: u.includes('Gecko/')\n  }\n\n  // 浏览器\n  const browserMatch = {\n    Safari: u.includes('Safari'),\n    Chrome: u.includes('Chrome') || u.includes('CriOS'),\n    IE: u.includes('MSIE') || u.includes('Trident'),\n    Edge: u.includes('Edge') || u.includes('Edg'),\n    Firefox: u.includes('Firefox') || u.includes('FxiOS'),\n    'Firefox Focus': u.includes('Focus'),\n    Chromium: u.includes('Chromium'),\n    Opera: u.includes('Opera') || u.includes('OPR'),\n    Vivaldi: u.includes('Vivaldi'),\n    Yandex: u.includes('YaBrowser'),\n    Kindle: u.includes('Kindle') || u.includes('Silk/'),\n    360: u.includes('360EE') || u.includes('360SE'),\n    UC: u.includes('UC') || u.includes(' UBrowser'),\n    QQBrowser: u.includes('QQBrowser'),\n    QQ: u.includes('QQ/'),\n    Baidu: u.includes('Baidu') || u.includes('BIDUBrowser'),\n    Maxthon: u.includes('Maxthon'),\n    Sogou: u.includes('MetaSr') || u.includes('Sogou'),\n    LBBROWSER: u.includes('LBBROWSER'),\n    '2345Explorer': u.includes('2345Explorer'),\n    TheWorld: u.includes('TheWorld'),\n    MIUI: u.includes('MiuiBrowser'),\n    Quark: u.includes('Quark'),\n    Qiyu: u.includes('Qiyu'),\n    Wechat: u.includes('MicroMessenger'),\n    Taobao: u.includes('AliApp(TB'),\n    Alipay: u.includes('AliApp(AP'),\n    Weibo: u.includes('Weibo'),\n    Douban: u.includes('com.douban.frodo'),\n    Suning: u.includes('SNEBUY-APP'),\n    iQiYi: u.includes('IqiyiApp'),\n  }\n\n  // 系统或平台\n  const osMatch = {\n    Windows: u.includes('Windows'),\n    Linux: u.includes('Linux') || u.includes('X11'),\n    'macOS': u.includes('Macintosh'),\n    Android: u.includes('Android') || u.includes('Adr'),\n    Ubuntu: u.includes('Ubuntu'),\n    FreeBSD: u.includes('FreeBSD'),\n    Debian: u.includes('Debian'),\n    'Windows Phone': u.includes('IEMobile') || u.includes('Windows Phone'),\n    BlackBerry: u.includes('BlackBerry') || u.includes('RIM'),\n    MeeGo: u.includes('MeeGo'),\n    Symbian: u.includes('Symbian'),\n    iOS: u.includes('like Mac OS X'),\n    'Chrome OS': u.includes('CrOS'),\n    WebOS: u.includes('hpwOS'),\n  }\n\n  // 设备\n  const deviceMatch = {\n    Mobile: u.includes('Mobi') || u.includes('iPh') || u.includes('480'),\n    Tablet: u.includes('Tablet') || u.includes('Pad') || u.includes('Nexus 7')\n  }\n\n  // 修正\n  if (deviceMatch.Mobile) {\n    deviceMatch.Mobile = !(u.includes('iPad'))\n  } else if (browserMatch.Chrome && u.includes('Edg')) {\n    // Chrome 内核的 Edge\n    browserMatch.Chrome = false\n    browserMatch.Edge = true\n  } else if (win.showModalDialog && win.chrome) {\n    browserMatch.Chrome = false\n    browserMatch['360'] = true\n  }\n\n  // 默认设备\n  dest.device = 'PC'\n\n  // 语言\n  dest.language = (() => {\n    const g = ((nav as any).browserLanguage || nav.language)\n    const arr = g.split('-')\n    if (arr[1]) arr[1] = arr[1].toUpperCase()\n    return arr.join('_')\n  })()\n\n  // 应用判断数据\n  const hash = {\n    engine: engineMatch,\n    browser: browserMatch,\n    os: osMatch,\n    device: deviceMatch,\n  }\n  Object.entries(hash).forEach(([type, match]) => {\n    Object.entries(match).forEach(([name, result]) => {\n      if (result === true) dest[type] = name\n    })\n  })\n\n  // 系统版本信息\n  const osVersion = {\n    Windows: () => {\n      const v = u.replace(/^.*Windows NT ([\\d.]+);.*$/, '$1')\n      const wvHash = {\n        '6.4': '10',\n        '6.3': '8.1',\n        '6.2': '8',\n        '6.1': '7',\n        '6.0': 'Vista',\n        '5.2': 'XP',\n        '5.1': 'XP',\n        '5.0': '2000',\n        '10.0': '10',\n        '11.0': '11' // 自定的，不是微软官方的判断方法\n      }\n      return wvHash[v] || v\n    },\n    Android: () => u.replace(/^.*Android ([\\d.]+);.*$/, '$1'),\n    iOS: () => u.replace(/^.*OS ([\\d_]+) like.*$/, '$1').replace(/_/g, '.'),\n    Debian: () => u.replace(/^.*Debian\\/([\\d.]+).*$/, '$1'),\n    'Windows Phone': () => u.replace(/^.*Windows Phone( OS)? ([\\d.]+);.*$/, '$2'),\n    'macOS': () => u.replace(/^.*Mac OS X ([\\d_]+).*$/, '$1').replace(/_/g, '.'),\n    WebOS: () => u.replace(/^.*hpwOS\\/([\\d.]+);.*$/, '$1')\n  }\n\n  dest.osVersion = ''\n  if (osVersion[dest.os]) {\n    dest.osVersion = osVersion[dest.os]()\n    if (dest.osVersion === u) {\n      dest.osVersion = ''\n    }\n  }\n\n  // 浏览器版本信息\n  const version = {\n    Safari: () => u.replace(/^.*Version\\/([\\d.]+).*$/, '$1'),\n    Chrome: () => u.replace(/^.*Chrome\\/([\\d.]+).*$/, '$1').replace(/^.*CriOS\\/([\\d.]+).*$/, '$1'),\n    IE: () => u.replace(/^.*MSIE ([\\d.]+).*$/, '$1').replace(/^.*rv:([\\d.]+).*$/, '$1'),\n    Edge: () => u.replace(/^.*(Edge|Edg|Edg[A-Z]{1})\\/([\\d.]+).*$/, '$2'),\n    Firefox: () => u.replace(/^.*Firefox\\/([\\d.]+).*$/, '$1').replace(/^.*FxiOS\\/([\\d.]+).*$/, '$1'),\n    'Firefox Focus': () => u.replace(/^.*Focus\\/([\\d.]+).*$/, '$1'),\n    Chromium: () => u.replace(/^.*Chromium\\/([\\d.]+).*$/, '$1'),\n    Opera: () => u.replace(/^.*Opera\\/([\\d.]+).*$/, '$1').replace(/^.*OPR\\/([\\d.]+).*$/, '$1'),\n    Vivaldi: () => u.replace(/^.*Vivaldi\\/([\\d.]+).*$/, '$1'),\n    Yandex: () => u.replace(/^.*YaBrowser\\/([\\d.]+).*$/, '$1'),\n    Kindle: () => u.replace(/^.*Version\\/([\\d.]+).*$/, '$1'),\n    Maxthon: () => u.replace(/^.*Maxthon\\/([\\d.]+).*$/, '$1'),\n    QQBrowser: () => u.replace(/^.*QQBrowser\\/([\\d.]+).*$/, '$1'),\n    QQ: () => u.replace(/^.*QQ\\/([\\d.]+).*$/, '$1'),\n    Baidu: () => u.replace(/^.*BIDUBrowser[\\s/]([\\d.]+).*$/, '$1'),\n    UC: () => u.replace(/^.*UC?Browser\\/([\\d.]+).*$/, '$1'),\n    Sogou: () => u.replace(/^.*SE ([\\d.X]+).*$/, '$1').replace(/^.*SogouMobileBrowser\\/([\\d.]+).*$/, '$1'),\n    '2345Explorer': () => u.replace(/^.*2345Explorer\\/([\\d.]+).*$/, '$1'),\n    TheWorld: () => u.replace(/^.*TheWorld ([\\d.]+).*$/, '$1'),\n    MIUI: () => u.replace(/^.*MiuiBrowser\\/([\\d.]+).*$/, '$1'),\n    Quark: () => u.replace(/^.*Quark\\/([\\d.]+).*$/, '$1'),\n    Qiyu: () => u.replace(/^.*Qiyu\\/([\\d.]+).*$/, '$1'),\n    Wechat: () => u.replace(/^.*MicroMessenger\\/([\\d.]+).*$/, '$1'),\n    Taobao: () => u.replace(/^.*AliApp\\(TB\\/([\\d.]+).*$/, '$1'),\n    Alipay: () => u.replace(/^.*AliApp\\(AP\\/([\\d.]+).*$/, '$1'),\n    Weibo: () => u.replace(/^.*weibo__([\\d.]+).*$/, '$1'),\n    Douban: () => u.replace(/^.*com.douban.frodo\\/([\\d.]+).*$/, '$1'),\n    Suning: () => u.replace(/^.*SNEBUY-APP([\\d.]+).*$/, '$1'),\n    iQiYi: () => u.replace(/^.*IqiyiVersion\\/([\\d.]+).*$/, '$1'),\n  }\n\n  dest.version = ''\n  if (version[dest.browser]) {\n    dest.version = version[dest.browser]()\n    if (dest.version === u) {\n      dest.version = ''\n    }\n  }\n\n  // 简化版本号\n  /* if (_this.osVersion.indexOf('.')) {\n    _this.osVersion = _this.osVersion.substring(0, _this.osVersion.indexOf('.'))\n  } */\n  if (dest.version.indexOf('.')) {\n    dest.version = dest.version.substring(0, dest.version.indexOf('.'))\n  }\n\n  // 修正\n  if (dest.os === 'iOS' && u.includes('iPad')) {\n    dest.os = 'iPadOS'\n  } else if (dest.browser === 'Edge' && !u.includes('Edg')) {\n    dest.engine = 'EdgeHTML'\n  } else if (dest.browser === 'MIUI') {\n    dest.os = 'Android'\n  } else if (dest.browser === 'Chrome' && Number(dest.version) > 27) {\n    dest.engine = 'Blink'\n  } else if (dest.browser === 'Opera' && Number(dest.version) > 12) {\n    dest.engine = 'Blink'\n  } else if (dest.browser === 'Yandex') {\n    dest.engine = 'Blink'\n  } else if (dest.browser === undefined) {\n    dest.browser = 'Unknow App'\n  }\n\n  return dest\n}\n\nexport default Detect\n","import * as Utils from '../lib/utils'\n\nexport interface ReadMoreBtnOptions {\n  /** 回调函数 */\n  onClick: (offset: number) => void\n\n  pageSize: number\n\n  text?: string\n}\n\n/**\n * 阅读更多按钮\n */\nexport default class ReadMoreBtn {\n  public opts: ReadMoreBtnOptions\n  public $el: HTMLElement\n  private $loading: HTMLElement\n  private $text: HTMLElement\n  private offset: number = 0\n  private total: number = 0\n  private origText: string = 'Load More'\n\n  /** 是否有更多内容 */\n  get hasMore() {\n    return this.total > this.offset + this.opts.pageSize\n  }\n\n  public constructor(opts: ReadMoreBtnOptions) {\n    this.opts = opts\n    this.origText = this.opts.text || this.origText\n\n    this.$el = Utils.createElement(\n      `<div class=\"atk-list-read-more\" style=\"display: none;\">\n      <div class=\"atk-list-read-more-inner\">\n        <div class=\"atk-loading-icon\" style=\"display: none;\"></div>\n        <span class=\"atk-text\">${this.origText}</span>\n      </div>\n    </div>`,\n    )\n\n    this.$loading = this.$el.querySelector<HTMLElement>('.atk-loading-icon')!\n    this.$text = this.$el.querySelector<HTMLElement>('.atk-text')!\n\n    this.$el.onclick = () => {\n      this.click()\n    }\n  }\n\n  click() {\n    if (this.hasMore) this.opts.onClick(this.offset + this.opts.pageSize)\n    this.checkDisabled()\n  }\n\n  /** 显示 */\n  show() {\n    this.$el.style.display = ''\n  }\n\n  /** 隐藏 */\n  hide() {\n    this.$el.style.display = 'none'\n  }\n\n  /** 加载 */\n  setLoading(isLoading: boolean) {\n    this.$loading.style.display = isLoading ? '' : 'none'\n    this.$text.style.display = isLoading ? 'none' : ''\n  }\n\n  /** 错误提示 */\n  showErr(errMsg: string) {\n    this.setLoading(false)\n\n    this.$text.innerText = errMsg\n    this.$el.classList.add('atk-err')\n    window.setTimeout(() => {\n      this.$text.innerText = this.origText\n      this.$el.classList.remove('atk-err')\n    }, 2000) // 2s后错误提示复原\n  }\n\n  /** 更新数据 */\n  public update(offset: number, total: number) {\n    this.offset = offset\n    this.total = total\n\n    this.checkDisabled()\n  }\n\n  public checkDisabled() {\n    if (this.hasMore) this.show()\n    else this.hide()\n  }\n}\n","import type { Paginator, IPgHolderOpt } from '.'\nimport ReadMoreBtn from '@/components/read-more-btn'\nimport $t from '@/i18n'\n\n/**\n * 阅读更多形式的分页\n */\nexport default class ReadMorePaginator implements Paginator {\n  private instance!: ReadMoreBtn\n  private onReachedBottom: (() => void) | null = null\n  private opt!: IPgHolderOpt\n\n  create(opt: IPgHolderOpt) {\n    this.opt = opt\n\n    this.instance = new ReadMoreBtn({\n      pageSize: opt.pageSize,\n      onClick: async (o) => {\n        opt.getData().fetchComments({\n          offset: o,\n        })\n      },\n      text: $t('loadMore'),\n    })\n\n    // 滚动到底部自动加载\n    if (opt.readMoreAutoLoad) {\n      this.onReachedBottom = () => {\n        if (!this.instance.hasMore || this.opt.getData().getLoading()) return\n        this.instance.click()\n      }\n      this.opt.getEvents().on('list-reach-bottom', this.onReachedBottom)\n    }\n\n    return this.instance.$el\n  }\n\n  setLoading(val: boolean) {\n    this.instance.setLoading(val)\n  }\n\n  update(offset: number, total: number) {\n    this.instance.update(offset, total)\n  }\n\n  showErr(msg: string) {\n    this.instance.showErr(msg)\n  }\n\n  next() {\n    this.instance.click()\n  }\n\n  getHasMore(): boolean {\n    return this.instance.hasMore\n  }\n\n  getIsClearComments(params: { offset?: number }): boolean {\n    return params.offset === 0\n  }\n\n  dispose(): void {\n    this.onReachedBottom && this.opt.getEvents().off('list-reach-bottom', this.onReachedBottom)\n    this.instance.$el.remove()\n  }\n}\n","import * as Utils from '../lib/utils'\nimport * as Ui from '../lib/ui'\n\nexport interface PaginationOptions {\n  /** 每页条数 */\n  pageSize: number\n\n  /** 回调函数 */\n  onChange: (offset: number) => void\n}\n\nexport default class Pagination {\n  private opts: PaginationOptions\n  public total: number\n  public $el: HTMLElement\n  public $input: HTMLInputElement\n  public inputTimer?: number\n  public $prevBtn: HTMLElement\n  public $nextBtn: HTMLElement\n\n  public page: number = 1\n  get pageSize(): number {\n    return this.opts.pageSize\n  }\n  get offset(): number {\n    return this.pageSize * (this.page - 1)\n  }\n  get maxPage(): number {\n    return Math.ceil(this.total / this.pageSize)\n  }\n\n  public constructor(total: number, opts: PaginationOptions) {\n    this.total = total\n    this.opts = opts\n\n    this.$el = Utils.createElement(\n      `<div class=\"atk-pagination-wrap\">\n        <div class=\"atk-pagination\">\n          <div class=\"atk-btn atk-btn-prev\" aria-label=\"Previous page\">\n            <svg stroke=\"currentColor\" fill=\"currentColor\" stroke-width=\"0\" viewBox=\"0 0 512 512\" height=\"14px\" width=\"14px\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M217.9 256L345 129c9.4-9.4 9.4-24.6 0-33.9-9.4-9.4-24.6-9.3-34 0L167 239c-9.1 9.1-9.3 23.7-.7 33.1L310.9 417c4.7 4.7 10.9 7 17 7s12.3-2.3 17-7c9.4-9.4 9.4-24.6 0-33.9L217.9 256z\"></path></svg>\n          </div>\n          <input type=\"text\" class=\"atk-input\" aria-label=\"Enter the number of page\" />\n          <div class=\"atk-btn atk-btn-next\" aria-label=\"Next page\">\n            <svg stroke=\"currentColor\" fill=\"currentColor\" stroke-width=\"0\" viewBox=\"0 0 512 512\" height=\"14px\" width=\"14px\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M294.1 256L167 129c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.3 34 0L345 239c9.1 9.1 9.3 23.7.7 33.1L201.1 417c-4.7 4.7-10.9 7-17 7s-12.3-2.3-17-7c-9.4-9.4-9.4-24.6 0-33.9l127-127.1z\"></path></svg>\n          </div>\n        </div>\n      </div>`,\n    )\n    this.$input = this.$el.querySelector('.atk-input')!\n    this.$input.value = `${this.page}`\n\n    this.$input.oninput = () => this.input()\n    this.$input.onkeydown = (e) => this.keydown(e)\n\n    this.$prevBtn = this.$el.querySelector('.atk-btn-prev')!\n    this.$nextBtn = this.$el.querySelector('.atk-btn-next')!\n\n    this.$prevBtn.onclick = () => this.prev()\n    this.$nextBtn.onclick = () => this.next()\n\n    this.checkDisabled()\n  }\n\n  public update(offset: number, total: number) {\n    this.page = Math.ceil(offset / this.pageSize) + 1\n    this.total = total\n\n    this.setInput(this.page)\n    this.checkDisabled()\n  }\n\n  public setInput(page: number) {\n    this.$input.value = `${page}`\n  }\n\n  public input(now: boolean = false) {\n    window.clearTimeout(this.inputTimer)\n\n    const value = this.$input.value.trim()\n\n    const modify = () => {\n      if (value === '') {\n        this.setInput(this.page)\n        return\n      }\n      let page = Number(value)\n      if (Number.isNaN(page)) {\n        this.setInput(this.page)\n        return\n      }\n      if (page < 1) {\n        this.setInput(this.page)\n        return\n      }\n      if (page > this.maxPage) {\n        this.setInput(this.maxPage)\n        page = this.maxPage\n      }\n      this.change(page)\n    }\n\n    // 延迟 800ms 执行\n    if (!now) this.inputTimer = window.setTimeout(() => modify(), 800)\n    else modify()\n  }\n\n  public prev() {\n    const page = this.page - 1\n    if (page < 1) {\n      return\n    }\n    this.change(page)\n  }\n\n  public next() {\n    const page = this.page + 1\n    if (page > this.maxPage) {\n      return\n    }\n    this.change(page)\n  }\n\n  public getHasMore() {\n    return this.page + 1 <= this.maxPage\n  }\n\n  public change(page: number) {\n    this.page = page\n    this.opts.onChange(this.offset)\n    this.setInput(page)\n    this.checkDisabled()\n  }\n\n  public checkDisabled() {\n    if (this.page + 1 > this.maxPage) {\n      this.$nextBtn.classList.add('atk-disabled')\n    } else {\n      this.$nextBtn.classList.remove('atk-disabled')\n    }\n\n    if (this.page - 1 < 1) {\n      this.$prevBtn.classList.add('atk-disabled')\n    } else {\n      this.$prevBtn.classList.remove('atk-disabled')\n    }\n  }\n\n  public keydown(e: KeyboardEvent) {\n    const keyCode = e.keyCode || e.which\n\n    if (keyCode === 38) {\n      // 上键\n      const page = Number(this.$input.value) + 1\n      if (page > this.maxPage) {\n        return\n      }\n      this.setInput(page)\n      this.input()\n    } else if (keyCode === 40) {\n      // 下键\n      const page = Number(this.$input.value) - 1\n      if (page < 1) {\n        return\n      }\n      this.setInput(page)\n      this.input()\n    } else if (keyCode === 13) {\n      // 回车\n      this.input(true)\n    }\n  }\n\n  /** 加载 */\n  setLoading(isLoading: boolean) {\n    if (isLoading) Ui.showLoading(this.$el)\n    else Ui.hideLoading(this.$el)\n  }\n}\n","import type { Paginator, IPgHolderOpt } from '.'\nimport PaginationComponent from '@/components/pagination'\n\n/**\n * 翻页形式的分页\n */\nexport default class UpDownPaginator implements Paginator {\n  private instance!: PaginationComponent\n\n  create(opt: IPgHolderOpt) {\n    this.instance = new PaginationComponent(opt.total, {\n      pageSize: opt.pageSize,\n      onChange: async (o) => {\n        opt.resetEditorState()\n\n        opt.getData().fetchComments({\n          offset: o,\n          onSuccess: () => {\n            opt.onListGotoFirst?.()\n          },\n        })\n      },\n    })\n\n    return this.instance.$el\n  }\n\n  setLoading(val: boolean) {\n    this.instance.setLoading(val)\n  }\n\n  update(offset: number, total: number) {\n    this.instance.update(offset, total)\n  }\n\n  next() {\n    this.instance.next()\n  }\n\n  getHasMore(): boolean {\n    return this.instance.getHasMore()\n  }\n\n  getIsClearComments(): boolean {\n    return true\n  }\n\n  dispose(): void {\n    this.instance.$el.remove()\n  }\n}\n","import type { ListOptions } from './list'\nimport { Paginator } from './paginator'\nimport ReadMorePaginator from './paginator/read-more'\nimport UpDownPaginator from './paginator/up-down'\nimport $t from '@/i18n'\nimport type { Config, List, ListLastFetchData } from '@/types'\n\nfunction createPaginatorByConf(conf: Pick<Config, 'pagination'>): Paginator {\n  if (conf.pagination.readMore) return new ReadMorePaginator()\n  return new UpDownPaginator()\n}\n\nfunction getPageDataByLastData(last: ListLastFetchData | undefined): {\n  offset: number\n  total: number\n} {\n  const r = { offset: 0, total: 0 }\n  if (!last) return r\n\n  r.offset = last.params.offset\n  if (last.data) r.total = last.params.flatMode ? last.data.count : last.data.roots_count\n\n  return r\n}\n\nexport interface PaginatorInitOptions extends ListOptions {\n  getList: () => List\n}\n\nexport const initListPaginatorFunc = (opts: PaginatorInitOptions) => {\n  let paginator: Paginator | null = null\n\n  // Init paginator when conf loaded\n  opts.getConf().watchConf(['pagination', 'locale'], (conf) => {\n    const list = opts.getList()\n    const data = opts.getData()\n\n    if (paginator) paginator.dispose() // if had been init, dispose it\n\n    // create paginator instance\n    paginator = createPaginatorByConf(conf)\n\n    // create paginator dom\n    const { offset, total } = getPageDataByLastData(data.getListLastFetch())\n    const $paginator = paginator.create({\n      pageSize: conf.pagination.pageSize,\n      total,\n\n      readMoreAutoLoad: conf.pagination.autoLoad,\n\n      ...opts,\n    })\n\n    // mount paginator dom\n    list.getCommentsWrapEl().after($paginator)\n\n    // update paginator info\n    paginator?.update(offset, total)\n  })\n\n  // When list loaded\n  opts.getEvents().on('list-loaded', (comments) => {\n    // update paginator info\n    const { offset, total } = getPageDataByLastData(opts.getData().getListLastFetch())\n    paginator?.update(offset, total)\n  })\n\n  // When list fetch\n  opts.getEvents().on('list-fetch', (params) => {\n    // if clear comments when fetch new page data\n    if (opts.getData().getComments().length > 0 && paginator?.getIsClearComments(params)) {\n      opts.getData().clearComments()\n    }\n  })\n\n  // When list error\n  opts.getEvents().on('list-failed', () => {\n    paginator?.showErr?.($t('loadFail'))\n  })\n\n  // loading\n  opts.getEvents().on('list-fetch', (params) => {\n    paginator?.setLoading(true)\n  })\n  opts.getEvents().on('list-fetched', ({ params }) => {\n    paginator?.setLoading(false)\n  })\n}\n","import ListHTML from './list.html?raw'\nimport { ListLayout } from './layout'\nimport { createCommentNode } from './comment'\nimport { initListPaginatorFunc } from './page'\nimport type { CommentData, EventManager, DataManager, ConfigManager, List as IList } from '@/types'\nimport * as Utils from '@/lib/utils'\nimport { CommentNode } from '@/comment'\nimport type { Api } from '@/api'\n\nexport interface ListOptions {\n  getApi: () => Api\n  getEvents: () => EventManager\n  getConf: () => ConfigManager\n  getData: () => DataManager\n\n  replyComment: (c: CommentData, $el: HTMLElement) => void\n  editComment: (c: CommentData, $el: HTMLElement) => void\n  resetEditorState: () => void\n  onListGotoFirst?: () => void\n}\n\nexport class List implements IList {\n  private opts: ListOptions\n  private $el: HTMLElement\n  getEl() {\n    return this.$el\n  }\n\n  private $commentsWrap: HTMLElement\n  getCommentsWrapEl() {\n    return this.$commentsWrap\n  }\n\n  private commentNodes: CommentNode[] = []\n  getCommentNodes() {\n    return this.commentNodes\n  }\n\n  constructor(opts: ListOptions) {\n    this.opts = opts\n\n    // Init base element\n    this.$el = Utils.createElement(ListHTML)\n    this.$commentsWrap = this.$el.querySelector('.atk-list-comments-wrap')!\n\n    // Init paginator\n    initListPaginatorFunc({\n      getList: () => this,\n      ...opts,\n    })\n\n    // Bind events\n    this.initCrudEvents()\n  }\n\n  getLayout({ forceFlatMode }: { forceFlatMode?: boolean } = {}) {\n    return new ListLayout({\n      $commentsWrap: this.$commentsWrap,\n      nestSortBy: this.opts.getConf().get().nestSort,\n      nestMax: this.opts.getConf().get().nestMax,\n      flatMode:\n        typeof forceFlatMode === 'boolean'\n          ? forceFlatMode\n          : (this.opts.getConf().get().flatMode as boolean),\n      // flatMode must be boolean because it had been handled when Artalk.init\n      createCommentNode: (d, r) => {\n        const node = createCommentNode({ forceFlatMode, ...this.opts }, d, r)\n        this.commentNodes.push(node) // store node instance\n        return node\n      },\n      findCommentNode: (id) => this.commentNodes.find((c) => c.getID() === id),\n    })\n  }\n\n  private initCrudEvents() {\n    this.opts.getEvents().on('list-load', (comments) => {\n      // 导入数据\n      this.getLayout().import(comments)\n    })\n\n    this.opts.getEvents().on('list-loaded', (comments) => {\n      if (comments.length === 0) {\n        this.commentNodes = []\n        this.$commentsWrap.innerHTML = ''\n      }\n    })\n\n    // When comment insert\n    this.opts.getEvents().on('comment-inserted', (comment) => {\n      const replyComment = comment.rid\n        ? this.commentNodes.find((c) => c.getID() === comment.rid)?.getData()\n        : undefined\n      this.getLayout().insert(comment, replyComment)\n    })\n\n    // When comment delete\n    this.opts.getEvents().on('comment-deleted', (comment) => {\n      const node = this.commentNodes.find((c) => c.getID() === comment.id)\n      if (!node) {\n        console.error(`comment node id=${comment.id} not found`)\n        return\n      }\n      node.remove()\n      this.commentNodes = this.commentNodes.filter((c) => c.getID() !== comment.id)\n      // TODO: remove child nodes\n    })\n\n    // When comment update\n    this.opts.getEvents().on('comment-updated', (comment) => {\n      const node = this.commentNodes.find((c) => c.getID() === comment.id)\n      node && node.setData(comment)\n    })\n  }\n}\n","export default \"<div class=\\\"atk-list\\\">\\n  <div class=\\\"atk-list-header\\\">\\n    <div class=\\\"atk-comment-count\\\">\\n      <div class=\\\"atk-text\\\"></div>\\n    </div>\\n    <div class=\\\"atk-right-action\\\">\\n      <span data-action=\\\"admin-close-comment\\\" class=\\\"atk-hide\\\" atk-only-admin-show></span>\\n      <span data-action=\\\"open-sidebar\\\" class=\\\"atk-hide atk-on\\\">\\n        <span class=\\\"atk-unread-badge\\\" style=\\\"display: none\\\"></span>\\n        <div class=\\\"atk-text\\\"></div>\\n      </span>\\n    </div>\\n  </div>\\n  <div class=\\\"atk-list-body\\\">\\n    <div class=\\\"atk-list-comments-wrap\\\"></div>\\n  </div>\\n  <div class=\\\"atk-list-footer\\\">\\n    <div class=\\\"atk-copyright\\\"></div>\\n  </div>\\n</div>\\n\"","import type { ConfigManager, EventManager, CommentData, DataManager } from '@/types'\nimport { CommentNode } from '@/comment'\nimport type { Api } from '@/api'\n\ninterface CreateCommentNodeOptions {\n  getApi: () => Api\n  getEvents: () => EventManager\n  getData: () => DataManager\n  getConf: () => ConfigManager\n  replyComment: (c: CommentData, $el: HTMLElement) => void\n  editComment: (c: CommentData, $el: HTMLElement) => void\n  forceFlatMode?: boolean\n}\n\nexport function createCommentNode(\n  opts: CreateCommentNodeOptions,\n  comment: CommentData,\n  replyComment?: CommentData,\n): CommentNode {\n  const conf = opts.getConf().get()\n\n  const instance = new CommentNode(comment, {\n    onAfterRender: () => {\n      opts.getEvents().trigger('comment-rendered', instance)\n    },\n    onDelete: (c: CommentNode) => {\n      opts.getData().deleteComment(c.getID())\n    },\n\n    replyTo: replyComment,\n\n    // TODO simplify reference\n    flatMode:\n      typeof opts?.forceFlatMode === 'boolean' ? opts?.forceFlatMode : (conf.flatMode as boolean),\n    gravatar: conf.gravatar,\n    nestMax: conf.nestMax,\n    heightLimit: conf.heightLimit,\n    avatarURLBuilder: conf.avatarURLBuilder,\n    scrollRelativeTo: conf.scrollRelativeTo,\n    vote: conf.vote,\n    voteDown: conf.voteDown,\n    uaBadge: conf.uaBadge,\n    dateFormatter: conf.dateFormatter,\n\n    // TODO: move to plugin folder and remove from core\n    getApi: opts.getApi,\n    replyComment: opts.replyComment,\n    editComment: opts.editComment,\n  })\n\n  // Render comment\n  instance.render()\n\n  return instance\n}\n","import SidebarHTML from './sidebar-layer.html?raw'\nimport type {\n  SidebarShowPayload,\n  ConfigManager,\n  UserManager,\n  LayerManager,\n  Layer,\n  SidebarLayer as ISidebarLayer,\n  CheckerManager,\n} from '@/types'\nimport * as Utils from '@/lib/utils'\nimport * as Ui from '@/lib/ui'\nimport type { Api } from '@/api'\n\nexport interface SidebarLayerOptions {\n  onShow?: () => void\n  onHide?: () => void\n\n  getCheckers: () => CheckerManager\n  getApi: () => Api\n  getConf: () => ConfigManager\n  getUser: () => UserManager\n  getLayers: () => LayerManager\n}\n\nexport class SidebarLayer implements ISidebarLayer {\n  private opts: SidebarLayerOptions\n  public $el: HTMLElement\n  public layer?: Layer\n  public $header: HTMLElement\n  public $closeBtn: HTMLElement\n  public $iframeWrap: HTMLElement\n  public $iframe?: HTMLIFrameElement\n\n  constructor(opts: SidebarLayerOptions) {\n    this.opts = opts\n    this.$el = Utils.createElement(SidebarHTML)\n    this.$header = this.$el.querySelector('.atk-sidebar-header')!\n    this.$closeBtn = this.$header.querySelector('.atk-sidebar-close')!\n    this.$iframeWrap = this.$el.querySelector('.atk-sidebar-iframe-wrap')!\n\n    this.$closeBtn.onclick = () => {\n      this.hide()\n    }\n  }\n\n  public async onUserChanged() {\n    this.refreshWhenShow = true\n  }\n\n  /** Refresh iFrame when show */\n  private refreshWhenShow = true\n\n  /** Animation timer */\n  private animTimer?: any = undefined\n\n  /** 显示 */\n  public async show(conf: SidebarShowPayload = {}) {\n    this.$el.style.transform = '' // 动画清除，防止二次打开失效\n\n    // init layer\n    this.initLayer()\n    this.layer!.show()\n\n    // init iframe\n    if (this.refreshWhenShow) {\n      this.refreshWhenShow = false\n      this.$iframeWrap.innerHTML = ''\n      this.$iframe = this.createIframe(conf.view)\n      this.$iframeWrap.append(this.$iframe)\n    } else {\n      // Sync Dark Mode (reload iframe if not match)\n      const $iframe = this.$iframe!\n      const iFrameSrc = $iframe.src\n      if (this.getDarkMode() !== iFrameSrc.includes('&darkMode=1')) {\n        this.iframeLoad(\n          $iframe,\n          iFrameSrc.replace(/&darkMode=\\d/, `&darkMode=${Number(this.getDarkMode())}`),\n        )\n      }\n    }\n\n    // 管理员身份验证 (若身份失效，弹出验证窗口)\n    this.authCheck({\n      onSuccess: () => this.show(conf), // retry show after auth check\n    })\n\n    // 执行滑动显示动画\n    this.animTimer = setTimeout(() => {\n      this.animTimer = undefined\n      this.$el.style.transform = 'translate(0, 0)'\n\n      this.opts.onShow?.()\n    }, 100)\n  }\n\n  /** 隐藏 */\n  public hide() {\n    this.layer?.hide()\n  }\n\n  // --------------------------------------------------\n\n  private async authCheck(opts: { onSuccess: () => void }) {\n    const data = (\n      await this.opts.getApi().user.getUserStatus({\n        ...this.opts.getApi().getUserFields(),\n      })\n    ).data\n    if (data.is_admin && !data.is_login) {\n      this.refreshWhenShow = true\n\n      // show checker layer\n      this.opts.getCheckers().checkAdmin({\n        onSuccess: () => {\n          setTimeout(() => {\n            opts.onSuccess()\n          }, 500)\n        },\n        onCancel: () => {\n          this.hide()\n        },\n      })\n\n      // hide sidebar layer\n      this.hide()\n    }\n  }\n\n  private initLayer() {\n    if (this.layer) return\n\n    this.layer = this.opts.getLayers().create('sidebar', this.$el)\n    this.layer.setOnAfterHide(() => {\n      // interrupt animation\n      this.animTimer && clearTimeout(this.animTimer)\n\n      // perform transform\n      this.$el.style.transform = ''\n\n      // trigger event\n      this.opts.onHide?.()\n    })\n  }\n\n  private createIframe(view?: string) {\n    const $iframe = Utils.createElement<HTMLIFrameElement>(\n      '<iframe referrerpolicy=\"strict-origin-when-cross-origin\"></iframe>',\n    )\n\n    // 准备 Iframe 参数\n    const baseURL = import.meta.env.DEV\n      ? 'http://localhost:23367/'\n      : Utils.getURLBasedOnApi({\n          base: this.opts.getConf().get().server,\n          path: '/sidebar/',\n        })\n\n    const query: any = {\n      pageKey: this.opts.getConf().get().pageKey,\n      site: this.opts.getConf().get().site || '',\n      user: JSON.stringify(this.opts.getUser().getData()),\n      time: +new Date(),\n    }\n\n    if (view) query.view = view\n    query.darkMode = this.getDarkMode() ? '1' : '0'\n\n    const urlParams = new URLSearchParams(query)\n    this.iframeLoad($iframe, `${baseURL}?${urlParams.toString()}`)\n\n    return $iframe\n  }\n\n  private getDarkMode() {\n    return this.opts.getConf().get().darkMode === 'auto'\n      ? window.matchMedia('(prefers-color-scheme: dark)').matches\n      : this.opts.getConf().get().darkMode\n  }\n\n  private iframeLoad($iframe: HTMLIFrameElement, src: string) {\n    $iframe.src = src\n\n    // 加载动画\n    Ui.showLoading(this.$iframeWrap)\n    $iframe.onload = () => {\n      Ui.hideLoading(this.$iframeWrap)\n    }\n  }\n}\n","export default \"<div class=\\\"atk-sidebar-layer\\\">\\n  <div class=\\\"atk-sidebar-inner\\\">\\n    <div class=\\\"atk-sidebar-header\\\">\\n      <div class=\\\"atk-sidebar-close\\\">\\n        <i class=\\\"atk-icon atk-icon-close-slim\\\"></i>\\n      </div>\\n    </div>\\n    <div class=\\\"atk-sidebar-iframe-wrap\\\"></div>\\n  </div>\\n</div>\\n\"","import type { ArtalkPlugin } from '@/types'\nimport { SidebarLayer } from '@/layer/sidebar-layer'\n\nexport const SidebarService: ArtalkPlugin = (ctx) => {\n  ctx.provide(\n    'sidebar',\n    (events, data, editor, checkers, api, config, user, layers) => {\n      const sidebarLayer = new SidebarLayer({\n        onShow: () => {\n          setTimeout(() => {\n            data.updateNotifies([])\n          }, 0)\n\n          events.trigger('sidebar-show')\n        },\n        onHide: () => {\n          // prevent comment box from being swallowed\n          editor.resetState()\n\n          events.trigger('sidebar-hide')\n        },\n        getCheckers: () => checkers,\n        getApi: () => api,\n        getConf: () => config,\n        getUser: () => user,\n        getLayers: () => layers,\n      })\n\n      ctx.on('user-changed', () => {\n        sidebarLayer?.onUserChanged()\n      })\n\n      return sidebarLayer\n    },\n    ['events', 'data', 'editor', 'checkers', 'api', 'config', 'user', 'layers'] as const,\n  )\n}\n","import { Markdown } from './markdown'\nimport { EditorKit } from './editor-kit'\nimport { ListPlugins } from './list'\nimport { Notifies } from './notifies'\nimport { PvCountWidget } from './stat'\nimport { VersionCheck } from './version-check'\nimport { AdminOnlyElem } from './admin-only-elem'\nimport { DarkMode } from './dark-mode'\nimport { PageVoteWidget } from './page-vote'\nimport { Services } from '@/services'\nimport type { ArtalkPlugin } from '@/types'\n\nexport const DefaultPlugins: ArtalkPlugin[] = [\n  ...Services,\n  Markdown,\n  EditorKit,\n  AdminOnlyElem,\n  ...ListPlugins,\n  Notifies,\n  PvCountWidget,\n  VersionCheck,\n  DarkMode,\n  PageVoteWidget,\n]\n","import { ApiService } from './api'\nimport { UserService } from './user'\nimport { CheckersService } from './checkers'\nimport { EditorService } from './editor'\nimport { I18nService } from './i18n'\nimport { DataService } from './data'\nimport { LayersService } from './layer'\nimport { ListService } from './list'\nimport { SidebarService } from './sidebar'\nimport { ArtalkPlugin } from '@/types'\n\nexport const Services: Set<ArtalkPlugin> = new Set([\n  DataService,\n  ApiService,\n  I18nService,\n  UserService,\n  EditorService,\n  ListService,\n  CheckersService,\n  LayersService,\n  SidebarService,\n])\n","import { ArtalkPlugin } from '@/types'\nimport { DataManager } from '@/data'\n\nexport const DataService: ArtalkPlugin = (ctx) => {\n  ctx.provide('data', (events) => new DataManager(events), ['events'] as const)\n\n  ctx.on('mounted', () => {\n    // Load comment list immediately after mounting\n    if (ctx.getConf().fetchCommentsOnInit) {\n      ctx.getData().fetchComments({ offset: 0 })\n    }\n  })\n}\n","export interface ApiHandlerPayload {\n  need_captcha: { img_data?: string; iframe?: string }\n  need_login: object\n  need_auth_login: object\n}\n\ntype PayloadKey = keyof ApiHandlerPayload\n\nexport interface ApiHandler<T extends PayloadKey = PayloadKey> {\n  action: T\n  handler: (data: ApiHandlerPayload[T]) => Promise<void>\n}\n\nexport interface ApiHandlers {\n  add: <T extends PayloadKey>(\n    action: T,\n    handler: (data: ApiHandlerPayload[T]) => Promise<void>,\n  ) => void\n  remove: (action: PayloadKey) => void\n  get: () => ApiHandler[]\n}\n\nexport function createApiHandlers(): ApiHandlers {\n  const handlers: ApiHandler[] = []\n  return {\n    add: (action, handler) => {\n      handlers.push({ action, handler })\n    },\n    remove: (action) => {\n      const index = handlers.findIndex((h) => h.action === action)\n      if (index !== -1) handlers.splice(index, 1)\n    },\n    get: () => handlers,\n  }\n}\n","import * as I18n from '@/i18n'\nimport type { ArtalkPlugin } from '@/types'\n\nexport const I18nService: ArtalkPlugin = (ctx) => {\n  ctx.watchConf(['locale'], (conf) => {\n    I18n.setLocale(conf.locale)\n  })\n}\n","import type { ArtalkPlugin } from '@/types'\nimport { UserManager } from '@/lib/user'\n\nexport const UserService: ArtalkPlugin = (ctx) => {\n  ctx.provide(\n    'user',\n    () => {\n      return new UserManager({\n        onUserChanged: (data) => {\n          ctx.trigger('user-changed', data)\n        },\n      })\n    },\n    [] as const,\n  )\n}\n","import type { ArtalkPlugin } from '@/types'\nimport { Editor } from '@/editor/editor'\n\nexport const EditorService: ArtalkPlugin = (ctx) => {\n  ctx.provide(\n    'editor',\n    (events, config) => {\n      const editor = new Editor({\n        getEvents: () => events,\n        getConf: () => config,\n      })\n      ctx.getEl().appendChild(editor.getEl())\n      return editor\n    },\n    ['events', 'config'] as const,\n  )\n}\n","import type { ArtalkPlugin } from '@/types'\nimport { List } from '@/list/list'\n\nexport const ListService: ArtalkPlugin = (ctx) => {\n  ctx.provide(\n    'list',\n    (api, events, config, data, editor) => {\n      const list = new List({\n        getApi: () => api,\n        getEvents: () => events,\n        getConf: () => config,\n        getData: () => data,\n\n        replyComment: (c, $el) => editor.setReplyComment(c, $el),\n        editComment: (c, $el) => editor.setEditComment(c, $el),\n        resetEditorState: () => editor.resetState(),\n        onListGotoFirst: () => ctx.listGotoFirst(),\n      })\n      ctx.getEl().appendChild(list.getEl())\n      return list\n    },\n    ['api', 'events', 'config', 'data', 'editor'] as const,\n  )\n}\n","import type { ArtalkPlugin } from '@/types'\nimport { LayerManager } from '@/layer'\n\nexport const LayersService: ArtalkPlugin = (ctx) => {\n  ctx.provide('layers', () => {\n    const layerManager = new LayerManager()\n    document.body.appendChild(layerManager.getEl())\n    ctx.on('unmounted', () => {\n      layerManager?.destroy()\n    })\n    return layerManager\n  })\n}\n","import type { ArtalkPlugin } from '@/types'\nimport * as marked from '@/lib/marked'\n\nexport const Markdown: ArtalkPlugin = (ctx) => {\n  ctx.watchConf(['imgLazyLoad', 'markedOptions'], (conf) => {\n    marked.initMarked({\n      markedOptions: conf.markedOptions,\n      imgLazyLoad: conf.imgLazyLoad,\n    })\n  })\n\n  ctx.watchConf(['markedReplacers'], (conf) => {\n    conf.markedReplacers && marked.setReplacers(conf.markedReplacers)\n  })\n}\n","import type { ArtalkPlugin } from '@/types'\n\nexport const AdminOnlyElem: ArtalkPlugin = (ctx) => {\n  const user = ctx.inject('user')\n\n  const scanApply = () => {\n    applyAdminOnlyEls(\n      user.getData().is_admin,\n      getAdminOnlyEls({\n        $root: ctx.getEl(),\n      }),\n    )\n  }\n\n  ctx.on('list-loaded', () => {\n    scanApply()\n  })\n\n  ctx.on('user-changed', (user) => {\n    scanApply()\n  })\n}\n\nfunction getAdminOnlyEls(opts: { $root: HTMLElement }): HTMLElement[] {\n  const els: HTMLElement[] = []\n\n  // elements in $root\n  opts.$root\n    .querySelectorAll<HTMLElement>(`[atk-only-admin-show]`)\n    .forEach((item) => els.push(item))\n\n  // TODO: provide a Artalk.conf hook to set whitelist of admin-only elements,\n  // and move following code to that hook (move into @artalk/artalk-sidebar)\n\n  // elements in sidebar\n  const $sidebarEl = document.querySelector<HTMLElement>('.atk-sidebar')\n  if ($sidebarEl)\n    $sidebarEl\n      .querySelectorAll<HTMLElement>(`[atk-only-admin-show]`)\n      .forEach((item) => els.push(item))\n\n  return els\n}\n\nfunction applyAdminOnlyEls(isAdmin: boolean, els: HTMLElement[]) {\n  els.forEach(($item: HTMLElement) => {\n    if (isAdmin) $item.classList.remove('atk-hide')\n    else $item.classList.add('atk-hide')\n  })\n}\n","import type { ArtalkPlugin } from '@/types'\n\nexport const Notifies: ArtalkPlugin = (ctx) => {\n  ctx.on('list-fetch', (params) => {\n    if (params.offset !== 0) return\n\n    const user = ctx.getApi().getUserFields()\n    if (!user) return\n\n    // Fetch all unread notifies\n    ctx\n      .getApi()\n      .notifies.getNotifies(user)\n      .then((res) => {\n        ctx.getData().updateNotifies(res.data.notifies)\n      })\n  })\n}\n","import { handleConfFormServer } from './config'\nimport { DefaultPlugins } from './plugins'\nimport { mergeDeep } from './lib/merge-deep'\nimport { MountError } from './plugins/mount-error'\nimport type { ConfigPartial, ArtalkPlugin, Context } from '@/types'\n\n/**\n * Global Plugins for all Artalk instances\n */\nexport const GlobalPlugins: Set<ArtalkPlugin> = new Set([...DefaultPlugins])\n\n/**\n * Plugin options for plugin initialization\n */\nexport const PluginOptions: WeakMap<ArtalkPlugin, any> = new WeakMap()\n\nexport async function mount(localConf: ConfigPartial, ctx: Context) {\n  const loaded = new Set<ArtalkPlugin>()\n  const loadPlugins = (plugins: Set<ArtalkPlugin>) => {\n    plugins.forEach((plugin) => {\n      if (typeof plugin !== 'function') return\n      if (loaded.has(plugin)) return\n      plugin(ctx, PluginOptions.get(plugin))\n      loaded.add(plugin)\n    })\n  }\n\n  // Load local plugins\n  loadPlugins(GlobalPlugins)\n\n  // Get conf from server\n  const { data } = await ctx\n    .getApi()\n    .conf.conf()\n    .catch((err) => {\n      MountError(ctx, { err, onRetry: () => mount(localConf, ctx) })\n      throw err\n    })\n\n  // Merge remote and local config\n  let conf: ConfigPartial = {\n    ...localConf,\n    apiVersion: data.version?.version, // server version info\n  }\n\n  const remoteConf = handleConfFormServer(data.frontend_conf || {})\n  conf = conf.preferRemoteConf ? mergeDeep(conf, remoteConf) : mergeDeep(remoteConf, conf)\n\n  // Apply local + remote conf\n  ctx.updateConf(conf)\n\n  // Load remote plugins\n  conf.pluginURLs &&\n    (await loadNetworkPlugins(conf.pluginURLs, ctx.getConf().server)\n      .then((plugins) => {\n        loadPlugins(plugins)\n      })\n      .catch((err) => {\n        console.error('Failed to load plugin', err)\n      }))\n}\n\n/**\n * Dynamically load plugins from Network\n */\nasync function loadNetworkPlugins(scripts: string[], apiBase: string): Promise<Set<ArtalkPlugin>> {\n  const networkPlugins = new Set<ArtalkPlugin>()\n  if (!scripts || !Array.isArray(scripts)) return networkPlugins\n\n  const tasks: Promise<void>[] = []\n\n  scripts.forEach((url) => {\n    // check url valid\n    if (!/^(http|https):\\/\\//.test(url))\n      url = `${apiBase.replace(/\\/$/, '')}/${url.replace(/^\\//, '')}`\n\n    tasks.push(\n      new Promise<void>((resolve) => {\n        // check if loaded\n        if (document.querySelector(`script[src=\"${url}\"]`)) {\n          resolve()\n          return\n        }\n\n        // load script\n        const script = document.createElement('script')\n        script.src = url\n        document.head.appendChild(script)\n        script.onload = () => resolve()\n        script.onerror = (err) => {\n          console.error('[artalk] Failed to load plugin', err)\n          resolve()\n        }\n      }),\n    )\n  })\n\n  await Promise.all(tasks)\n\n  // Read ArtalkPlugins object from window\n  Object.values(window.ArtalkPlugins || {}).forEach((plugin) => {\n    if (typeof plugin === 'function') networkPlugins.add(plugin)\n  })\n\n  return networkPlugins\n}\n","import { showErrorDialog } from '@/components/error-dialog'\nimport type { ArtalkPlugin } from '@/types'\n\nexport interface MountErrorOptions {\n  err?: { data?: { err_no_site?: boolean }; msg: string }\n  onRetry?: () => void\n}\n\nexport const MountError: ArtalkPlugin<MountErrorOptions> = (ctx, opts = {}) => {\n  const list = ctx.inject('list')\n  const user = ctx.inject('user')\n  const conf = ctx.inject('config')\n\n  const err = opts.err\n  if (!err) throw new Error('MountError: `err` is required')\n\n  let sidebarOpenView = ''\n\n  // if response err_no_site, modify the sidebar open view to create site\n  if (err.data?.err_no_site) {\n    const viewLoadParam = {\n      create_name: conf.get().site,\n      create_urls: `${window.location.protocol}//${window.location.host}`,\n    }\n    sidebarOpenView = `sites|${JSON.stringify(viewLoadParam)}`\n  }\n\n  showErrorDialog({\n    $err: list.getEl(),\n    errMsg: err.msg || String(err),\n    errData: err.data,\n    retryFn: () => opts.onRetry?.(),\n    onOpenSidebar: user.getData().is_admin\n      ? () =>\n          ctx.showSidebar({\n            view: sidebarOpenView as any,\n          })\n      : undefined, // only show open sidebar button when user is admin\n  })\n}\n","import type { Config, EventManager } from '@/types'\n\nexport function watchConf<T extends (keyof Config)[]>({\n  keys,\n  effect,\n  getConf,\n  getEvents,\n}: {\n  keys: T\n  effect: (conf: Pick<Config, T[number]>) => void\n  getConf: () => Config\n  getEvents: () => EventManager\n}): void {\n  const deepEqual = (a: any, b: any) => JSON.stringify(a) === JSON.stringify(b)\n  const val = () => {\n    const conf = getConf()\n    const res: any = {}\n    keys.forEach((key) => {\n      res[key] = conf[key]\n    })\n    return res\n  }\n  let lastVal: any = null\n  const handler = () => {\n    const newVal = val()\n    const isDiff = lastVal == null || !deepEqual(lastVal, newVal)\n    // only trigger when specific keys changed\n    if (isDiff) {\n      lastVal = newVal\n      effect(newVal)\n    }\n  }\n  getEvents().on('mounted', handler)\n  getEvents().on('updated', handler)\n}\n","import './style/main.scss'\n\nimport Context from './context'\nimport { handelCustomConf, convertApiOptions, getRootEl } from './config'\nimport * as Stat from './plugins/stat'\nimport { Api } from './api'\nimport { GlobalPlugins, PluginOptions, mount } from './mount'\nimport { ConfigService } from './services/config'\nimport { EventsService } from './services/events'\nimport type {\n  ConfigPartial,\n  EventPayloadMap,\n  ArtalkPlugin,\n  Context as IContext,\n  EventHandler,\n} from '@/types'\n\n/**\n * Artalk\n *\n * @see https://artalk.js.org\n */\nexport default class Artalk {\n  public ctx: IContext\n\n  constructor(conf: ConfigPartial) {\n    // Init Root Element\n    const $root = getRootEl(conf)\n    $root.classList.add('artalk')\n    $root.innerHTML = ''\n    conf.darkMode == true && $root.classList.add('atk-dark-mode')\n\n    // Init Context\n    const ctx = (this.ctx = new Context($root))\n\n    // Init required services\n    ;(() => {\n      // Init event manager\n      EventsService(ctx)\n\n      // Init config service\n      ConfigService(ctx)\n    })()\n\n    // Apply local conf first\n    ctx.updateConf(conf)\n\n    // Trigger created event\n    ctx.trigger('created')\n\n    // Load plugins and remote config, then mount Artalk\n    const mountArtalk = async () => {\n      await mount(conf, ctx)\n\n      // Trigger mounted event\n      ctx.trigger('mounted')\n    }\n\n    if (import.meta.env.DEV && import.meta.env.VITEST) {\n      global.devMountArtalk = mountArtalk\n    } else {\n      mountArtalk()\n    }\n  }\n\n  /** Get the config of Artalk */\n  public getConf() {\n    return this.ctx.getConf()\n  }\n\n  /** Get the root element of Artalk */\n  public getEl() {\n    return this.ctx.getEl()\n  }\n\n  /** Update config of Artalk */\n  public update(conf: ConfigPartial) {\n    this.ctx.updateConf(conf)\n  }\n\n  /** Reload comment list of Artalk */\n  public reload() {\n    this.ctx.reload()\n  }\n\n  /** Destroy instance of Artalk */\n  public destroy() {\n    this.ctx.destroy()\n  }\n\n  /** Add an event listener */\n  public on<K extends keyof EventPayloadMap>(name: K, handler: EventHandler<EventPayloadMap[K]>) {\n    this.ctx.on(name, handler)\n  }\n\n  /** Remove an event listener */\n  public off<K extends keyof EventPayloadMap>(name: K, handler: EventHandler<EventPayloadMap[K]>) {\n    this.ctx.off(name, handler)\n  }\n\n  /** Trigger an event */\n  public trigger<K extends keyof EventPayloadMap>(name: K, payload?: EventPayloadMap[K]) {\n    this.ctx.trigger(name, payload)\n  }\n\n  /** Set dark mode */\n  public setDarkMode(darkMode: boolean) {\n    this.ctx.setDarkMode(darkMode)\n  }\n\n  // ===========================\n  //       Static Members\n  // ===========================\n\n  /** Init Artalk */\n  public static init(conf: ConfigPartial): Artalk {\n    return new Artalk(conf)\n  }\n\n  /** Use plugin, the plugin will be used when Artalk.init */\n  public static use<T = any>(plugin: ArtalkPlugin<T>, options?: T) {\n    GlobalPlugins.add(plugin)\n    PluginOptions.set(plugin, options)\n  }\n\n  /** Load count widget */\n  public static loadCountWidget(c: ConfigPartial) {\n    const conf = handelCustomConf(c, true)\n\n    Stat.initCountWidget({\n      getApi: () => new Api(convertApiOptions(conf)),\n      siteName: conf.site,\n      countEl: conf.countEl,\n      pvEl: conf.pvEl,\n      pageKeyAttr: conf.statPageKeyAttr,\n      pvAdd: false,\n    })\n  }\n\n  // ===========================\n  //         Deprecated\n  // ===========================\n  /** @deprecated Please use `getEl()` instead */\n  public get $root() {\n    console.warn('`$root` is deprecated, please use `getEl()` instead')\n    return this.getEl()\n  }\n\n  /** @description Please use `getConf()` instead */\n  public get conf() {\n    console.warn('`conf` is deprecated, please use `getConf()` instead')\n    return this.getConf()\n  }\n}\n","import type { ArtalkPlugin, EventPayloadMap } from '@/types'\nimport { EventManager } from '@/lib/event-manager'\n\nexport const EventsService: ArtalkPlugin = (ctx) => {\n  ctx.provide('events', () => new EventManager<EventPayloadMap>())\n}\n","import type { Config, ArtalkPlugin, ConfigManager } from '@/types'\nimport { mergeDeep } from '@/lib/merge-deep'\nimport { handelCustomConf } from '@/config'\nimport { watchConf } from '@/lib/watch-conf'\n\nexport const ConfigService: ArtalkPlugin = (ctx) => {\n  let conf: Config = handelCustomConf({}, true)\n\n  ctx.provide(\n    'config',\n    (events) => {\n      let mounted = false\n      events.on('mounted', () => (mounted = true))\n      const instance: ConfigManager = {\n        watchConf: (keys, effect) => {\n          watchConf({\n            keys,\n            effect,\n            getConf: () => conf,\n            getEvents: () => events,\n          })\n        },\n        get: () => conf,\n        update: (config) => {\n          conf = mergeDeep<Config>(conf, handelCustomConf(config, false))\n          mounted && events.trigger('updated', conf)\n        },\n      }\n      return instance\n    },\n    ['events'] as const,\n  )\n}\n","import Artalk from './artalk'\nimport type * as ArtalkType from './types'\nimport { Defaults } from './defaults'\n\nexport type * from './types'\nexport { ArtalkType, Defaults }\n\nexport default Artalk\n\n// Manually expose the static methods from the Artalk class.\n// Directly exporting static methods from a class is not supported,\n// and it's important to maintain consistency in the library's API.\n// To ensure compatibility across different environments, such as CommonJS and browser IIFE,\n// this approach allows us to use `Artalk.init()` instead of `Artalk.default.init()`.\nexport const init = Artalk.init\nexport const use = Artalk.use\nexport const loadCountWidget = Artalk.loadCountWidget\n"],"names":["createElement","htmlStr","div","document","innerHTML","trim","firstElementChild","htmlEncode","str","temp","innerText","getQueryParam","name","match","RegExp","exec","window","location","search","decodeURIComponent","replace","getOffset","el","relativeTo","getOffsetRecursive","element","rect","getBoundingClientRect","scrollLeft","pageXOffset","documentElement","scrollTop","pageYOffset","top","left","elOffset","relativeToOffset","padWithZeros","vNumber","width","numAsString","toString","length","timeAgo","date","$t","n","oldTime","getTime","diffValue","Date","days","Math","floor","leave1","hours","leave2","minutes","leave3","seconds","round","vDay","getDate","vMonth","getMonth","getFullYear","dateFormat","error","console","getCorrectUserAgent","__async","this","uaRaw","navigator","userAgent","userAgentData","getHighEntropyValues","uaData","uaGot","err","majorPlatformVersion","Number","platformVersion","split","platform","isValidURL","urlRaw","url","URL","_","protocol","getURLBasedOnApi","opts","baseURL","base","path","en","placeholder","noComment","send","signIn","signUp","save","nick","email","link","emoticon","preview","uploadImage","uploadFail","commentFail","restoredMsg","onlyAdminCanReply","uploadLoginMsg","counter","sortLatest","sortOldest","sortBest","sortAuthor","openComment","closeComment","listLoadFailMsg","listRetry","loadMore","admin","reply","voteUp","voteDown","voteFail","readMore","actionConfirm","collapse","collapsed","collapsedMsg","expand","approved","pending","pendingMsg","edit","editCancel","delete","deleteConfirm","pin","unpin","now","adminCheck","captchaCheck","confirm","cancel","msgCenter","ctrlCenter","userProfile","noAccountPrompt","haveAccountPrompt","forgetPassword","resetPassword","changePassword","confirmPassword","passwordMismatch","verificationCode","verifySend","verifyResend","waitSeconds","emailVerified","password","username","nextStep","skipVerify","logoutConfirm","accountMergeNotice","accountMergeSelectOne","accountMergeConfirm","dismiss","merge","client","server","loading","loadFail","editing","editFail","deleting","deleteFail","reqGot","reqAborted","updateMsg","currentVersion","ignore","open","openName","GLOBAL_LOCALES_KEY","internal","findLocaleSet","lang","p1","p2","toLowerCase","toUpperCase","LocaleConf","LocaleDict","t","key","args","token","Utils.htmlEncode","_getDefaults","async","breaks","extensions","gfm","hooks","pedantic","renderer","silent","tokenizer","walkTokens","_defaults","changeDefaults","newDefaults","escapeTest","escapeReplace","source","escapeTestNoEncode","escapeReplaceNoEncode","escapeReplacements","getEscapeReplacement","ch","escape$1","html","encode","test","caret","regex","opt","obj","val","valSource","getRegex","cleanUrl","href","encodeURI","e","noopTest","splitCells","tableRow","count","cells","offset","escaped","curr","i","shift","pop","splice","push","rtrim","c","invert","l","suffLen","currChar","charAt","slice","outputLink","cap","raw","lexer","title","text","state","inLink","type","tokens","inlineTokens","_Tokenizer","constructor","options","__publicField","space","src","rules","block","newline","code","codeBlockStyle","fences","matchIndentToCode","indentToCode","map","node","matchIndentInNode","indentInNode","join","indentCodeCompensation","inline","anyPunctuation","heading","trimmed","depth","hr","blockquote","lines","inBlockquote","currentLines","currentRaw","currentText","blockTokens","lastToken","oldToken","newText","newToken","substring","list","bull","isordered","ordered","start","loose","items","itemRegex","endsWithBlankLine","endEarly","itemContents","line","repeat","nextLine","blankLine","indent","trimStart","nextBulletRegex","min","hrRegex","fencesBeginRegex","headingBeginRegex","htmlBeginRegex","rawLine","nextLineWithoutTabs","ischecked","istask","task","checked","trimEnd","spacers","filter","hasMultipleLineBreaks","some","pre","def","tag","table","headers","aligns","rows","item","header","align","row","cell","lheading","paragraph","escape","inRawBlock","trimmedUrl","rtrimSlash","lastParenIndex","b","indexOf","level","findClosingBracket","linkLen","reflink","links","nolink","emStrong","maskedSrc","prevChar","emStrongLDelim","punctuation","lLength","rDelim","rLength","delimTotal","midDelimTotal","endReg","emStrongRDelimAst","emStrongRDelimUnd","lastIndex","lastCharLength","index","codespan","hasNonSpaceChars","hasSpaceCharsOnBothEnds","br","del","autolink","prevCapZero","_b","_a","_backpedal","inlineText","bullet","_paragraph","_blockLabel","_tag","_comment","blockNormal","gfmTable","blockGfm","__spreadProps","blockPedantic","_punctuation","_inlineComment","_inlineLabel","inlineNormal","blockSkip","reflinkSearch","inlinePedantic","inlineGfm","inlineBreaks","normal","_Lexer","Object","create","inlineQueue","lex","lexInline","next","lastParagraphClipped","cutSrc","extTokenizer","call","startBlock","startIndex","Infinity","tempSrc","tempStart","forEach","getStartIndex","errMsg","charCodeAt","Error","keepPrevChar","keys","includes","lastIndexOf","startInline","_Renderer","langString","parser","parse","parseInline","body","j","listitem","itemBody","checkbox","unshift","tablecell","tablerow","k","content","strong","em","cleanHref","out","image","_TextRenderer","_Parser","textRenderer","anyToken","renderers","genericToken","ret","textToken","_Hooks","preprocess","markdown","postprocess","processAllTokens","provideLexer","provideParser","Set","Marked","setOptions","parseMarkdown","use","callback","values","concat","tableToken","listToken","defaults","childTokens","flat","pack","__spreadValues","ext","prevRenderer","apply","extLevel","prop","rendererProp","rendererFunc","tokenizerProp","tokenizerFunc","prevTokenizer","hooksProp","hooksFunc","prevHook","passThroughHooks","has","arg","Promise","resolve","then","packWalktokens","blockType","origOpt","throwError","onError","prototype","all","catch","message","msg","reject","markedInstance","marked","getDefaults","Parser","Renderer","TextRenderer","Lexer","Tokenizer","Hooks","escapes","unescapes","rescaped","runescaped","escapeHtmlChar","unescapeHtmlChar","escapeHtml","String","unescapeHtml","she","decode","unescape","version","assignment_1","assignment","result","stack","Array","arguments","hasOwnProperty","lowercase","string","asKey","accumulator","toMap_1","reduce","attributes","uris","require$$0","elements","voids","he","require$$1","require$$3","rstart","rend","rattrs","rtag","rtagend","require$$2","assign","handler","chars","lastItem","createStack","last","parsePart","substr","comment","parseEdge","parseEndTag","parseStartTag","same","tagName","rest","unary","attrs","low","u","doubleQuotedValue","singleQuotedValue","unquotedValue","pos","end","sanitizer","buffer","context","o","ignoring","allowedTags","value","classesOk","allowedClasses","attrsOk","allowedAttributes","lkey","className","colon","questionmark","hash","allowedSchemes","matches","scheme","testUrl","unignore","transformText","reset","a","iframe","img","insane","strict","configuration","insaneOptions","span","reg","class","style","sanitize","exports","createCommonjsModule","fn","module","index$1","defaultColors","toComment","cm","input","ref","colors","cache","re","m","word","color","factory","renderCode","hanabi","getRenderer","markedLinkRenderer","markedCodeRenderer","markedImageRenderer","orgLinkRenderer","isSameOriginLink","origin","getLinkOrigin","realLang","colorized","hljs","getLanguage","highlight","orgImageRenderer","imgLazyLoad","instance","replacers","markedOptions","getInstance","markedContent","alt","imgSrc","simpleMarked","dest","replacer","Context","_$root","providers","Map","initializedDeps","inject","provider","get","lifecycle","impl","deps","resolved","d","set","provide","createInjectionContainer","_deps","on","off","payload","trigger","getCommentNodes","getComments","getEl","destroy","firstChild","removeChild","getConf","updateConf","conf","update","watchConf","effect","getMarked","marked.getInstance","setDarkMode","darkMode","$root","I18n.t","getApi","getApiHandlers","getUser","getData","fetch","params","fetchComments","reload","listGotoFirst","replyComment","commentData","$comment","setReplyComment","editComment","setEditComment","editorShowLoading","showLoading","editorHideLoading","hideLoading","editorShowNotify","showNotify","editorResetState","resetState","showSidebar","show","hideSidebar","hide","checkAdmin","checkCaptcha","mergeDeep","objects","isObject","prev","pVal","oVal","isArray","Defaults","pageKey","pageTitle","site","sendBtn","editorTravel","flatMode","nestMax","nestSort","emoticons","pageVote","vote","uaBadge","listSort","countEl","pvEl","statPageKeyAttr","gravatar","mirror","pagination","pageSize","autoLoad","heightLimit","children","scrollable","imgUpload","reqTimeout","versionCheck","useBackendConf","preferRemoteConf","listUnreadHighlight","pvAdd","fetchCommentsOnInit","locale","apiVersion","pluginURLs","markedReplacers","handelCustomConf","customConf","full","pathname","language","matchMedia","convertApiOptions","user","handlers","siteName","timeout","getApiToken","userInfo","checkHasBasicUserInfo","initCountWidget","loadStatCount","query","containers","loadCommentCount","cacheData","pvCount","pages","logPv","page_key","page_title","site_name","data","pv","incrementPvCount","loadPvCount","els","selector","querySelectorAll","add","retrieveElements","pageKeys","pageKeyAttr","from","getAttribute","getPageKeys","res","stats","getStats","page_keys","defaultPageKey","updateElementsText","HttpClient","apiConfig","fetchParams","credentials","redirect","referrerPolicy","securityData","JSON","stringify","formData","property","append","Blob","FormData","toQueryString","cancelToken","abortControllers","abortController","signal","AbortController","abort","secure","format","baseUrl","__objRest","secureParams","baseApiParams","securityWorker","requestParams","mergeRequestParams","queryString","payloadFormatter","contentFormatters","responseFormat","customFetch","createAbortSignal","response","r","clone","ok","encodeQueryParam","encodeURIComponent","addQueryParam","addArrayQueryParam","v","rawQuery","addQueryParams","params1","params2","super","loginByEmail","request","method","registerByEmail","sendVerifyEmail","checkDataMerge","applyDataMerge","flushCache","warmUpCache","getCaptcha","getCaptchaStatus","verifyCaptcha","createComment","getComment","id","updateComment","deleteComment","getSocialLoginProviders","getDomain","getNotifies","markAllNotifyRead","markNotifyRead","commentId","notifyKey","getPages","fetchAllPages","getPageFetchStatus","page","updatePage","deletePage","fetchPage","sendEmail","getSettings","applySettings","settings","getSettingsTemplate","getSites","createSite","updateSite","deleteSite","exportArtrans","importArtrans","uploadArtrans","upload","updateProfile","login","getUserStatus","createUser","updateUser","deleteUser","getUsers","getVersion","syncVotes","getVote","targetName","targetId","createVote","choice","Fetch","init","apiToken","Headers","Authorization","resp","json","retry","promise","action","FetchException","createError","status","Api","ApiV2","_opts","getUserFields","EditorPlugin","kit","useBtn","$btn","Utils.createElement","usePanel","$panel","useContentTransformer","func","contentTransformer","usePanelShow","useEvents","aPlug","usePanelHide","useEditorStateEffect","stateName","effectFn","editorStateEffectWhen","editorStateEffect","LocalStorageKey","SubmitAddPreset","reqAdd","useApi","comments","getSubmitAddParams","useUser","useConf","useEditor","getContentFinal","rid","ua","Utils.getCorrectUserAgent","postSubmitAdd","commentNew","useData","insertComment","Submit","defaultPreset","onEditorSubmit","do","useMounted","useUnmounted","registerCustom","customs","focus","custom","find","activeCond","nComment","req","post","Mover","move","afterEl","isMoved","editorEl","useUI","$el","after","$travelPlace","replaceWith","classList","back","useArtalkRootEl","querySelector","remove","parentElem","$loading","transparentBg","background","appendChild","display","$spinner","setTimeout","isConnected","setLoading","scrollIntoView","elem","enableAnim","containerRect","clientHeight","scrollY","innerHeight","height","scrollOptions","behavior","scroll","playFadeInAnim","onAnimEnded","removeEventListener","addEventListener","playFadeAnim","setError","errorTextEl","HTMLElement","Emoticons","transEmoticonImageText","loadEmoticonsData","isImgLoaded","initEmoticonsList","changeListHeight","parentElement","isListLoaded","loadingTask","Ui.showLoading","handleData","Ui.hideLoading","Ui.setError","pushGrp","grp","remoteLoad","grpData","isOwOFormat","convertOwO","solveNullKey","solveSameKey","tmp","container","owoData","entries","grpName","nGrp","iconStr","icon","$grpWrap","$grp","setAttribute","$item","imgEl","onclick","insertContent","$grpSwitcher","openGrp","_c","AllowImgExts","Upload","initDragImg","$imgUploadInput","accept","$input","onchange","files","file","uploadImg","click","uploadFromFileList","onDragover","evt","stopPropagation","preventDefault","onDrop","dataTransfer","onPaste","clipboardData","$textarea","fileExt","insertPrefix","uploadPlaceholderTxt","customUploaderFn","imgUploader","public_url","imgURL","Utils.isValidURL","Utils.getURLBasedOnApi","setContent","Preview","isPlugPanelShow","updateContent","getContentMarked","EDITOR_PLUGS","onContentUpdated","localContent","localStorage","getItem","setItem","getContentRaw","$inputs","getHeaderInputEls","inputEventFns","changeEventFns","field","timer","abortFn","onInput","getState","fetchUserInfo","placeholders","logout","clearTimeout","api","CANCEL_TOKEN","abortRequest","onUserInfoFetched","finally","is_login","updateNotifies","notifies","is_admin","useCheckers","onSuccess","$link","onLinkChange","onLinkInputChange","onKeydown","adaptiveHeightByContent","keyCode","which","diff","offsetHeight","scrollHeight","onClick","submit","$submitBtn","setReply","cancelReply","submitPlug","useDeps","page_url","ui","$sendReplyBtn","$stateWrap","cancelEdit","saveData","$name","$email","$editCancelBtn","$header","updateSubmitBtnText","restoreSubmitBtnText","originalSubmitBtnText","onOpen","onClose","close","$textareaWrap","$bottom","prepend","PlugKit","plugins","getEditor","getOptions","getCheckers","getUI","getEvents","plug","getArtalkRootEl","EventManager","events","once","PluginManager","confLoaded","clear","confRefs","p","getEnabledPlugs","Plug","loadPluginUI","closePluginPanel","onSubmitted","getPlugins","openedPlug","$plugPanelWrap","$plugBtnWrap","loadPluginItem","openPluginPanel","plugPanel","getTransformedContent","rawContent","showErrorDialog","errEl","retryFn","$retryBtn","onOpenSidebar","$openSidebar","$err","ListPlugins","ctx","_params","getLoading","limit","paramsModifier","listFetchParamsModifier","setListLastFetch","reqParams","flat_mode","loadComments","notify","comment_id","getID","getRender","setUnread","setOpenAction","read_link","commentID","Utils.getQueryParam","editorPlugs","$closeCommentBtn","getPage","admin_only","adminPageEditSave","$count","getListLastFetch","$openSidebarBtn","syncByUser","$btnText","$unreadBadge","reloadUseParamsEditor","initDropdown","$dropdownOn","$dropdownWrap","dropdownList","curtActive","onItemClick","$dropdown","renderDropdown","sort_by","view_only_admin","removeDropdown","lastID","check","locker","isNaN","parseFloat","extractCommentID","hashChangeHandler","listLoadedHandler","getLayout","forceFlatMode","insert","reply_comment","isNoComment","$noComment","getCommentsWrapEl","$copyright","ARTALK_VERSION","setInterval","dateFormatter","Utils.timeAgo","clearInterval","errData","observer","clearObserver","disconnect","childNodes","$target","scrollEvtAt","scrollRelativeTo","IntersectionObserver","isIntersecting","threshold","root","observe","setupObserver","warn","$relative","Utils.getOffset","IgnoreVersionCheck","darkModeMedia","updateClassnames","$els","DarkModeClassName","upBtnEl","downBtnEl","upCountEl","downCountEl","activeClass","updateVoteStatus","up","down","isUp","isDown","toggle","voteBtnHandler","pageId","httpApi","votes","is_up","is_down","alert","LOCAL_USER_KEY","UserManager","localUser","isAdmin","onUserChanged","iframeBody","checker","$iframeWrap","$iframe","getOpts","getCaptchaIframeURL","onload","$closeBtn","hideInteractInput","stop","queryStatus","ms","isPass","captcha","is_pass","triggerSuccess","CaptchaChecker","inputVal","render.iframeBody","img_data","render.imgBody","formEl","AdminChecker","inputType","onReload","Dialog","contentEl","$actions","$content","setYes","btn","onBtnClick","setNo","currentTarget","wrapPromise","cancelFn","onCancel","successFn","CheckerLauncher","beforeCheck","layer","getLayers","checkerStore","checkerCtx","btnTextOrg","onkeyup","dialog","btnEl","btnTextRestore","btnText","tf","onfocus","onMount","Sel","$notifyWrap","$bottomLeft","EditorStateManager","editor","stateCurt","stateUnmountFn","moveAfterEl","_d","_f","_e","Ui.scrollIntoView","plugin","_g","Editor","sel","render","setPlugins","selection","createRange","selectionStart","sStart","sEnd","selectionEnd","sT","switch","wrapElem","notifyElem","s","w","notifyRemove","timeoutFn","Ui.showNotify","beforeSubmit","DataManager","listLastFetch","findComment","clearComments","partialComments","pageData","Layer","setOnAfterHide","onAfterHide","setAllowMaskClose","allow","allowMaskClose","getAllowMaskClose","onShow","onHide","bodyOrgOverflow","bodyOrgPaddingRight","getScrollbarHelper","overflow","paddingRight","unlock","lock","barPaddingRight","parseInt","getComputedStyle","getPropertyValue","inner","outer","position","visibility","w1","offsetWidth","w2","clientWidth","Ui.getScrollBarWidth","LayerWrap","$wrap","$mask","createItem","createItemElement","hideWrap","showWrap","getMask","getWrap","LayerManager","wrap","createNestStrategy","import","srcData","sortBy","nodeList","rootNode","parent","loadChildren","parentNode","child","childNode","sortFunc","vote_up","sortLevels","nodes","sort","ListNest.makeNestCommentNodeList","nestSortBy","rootC","createCommentNode","$commentsWrap","parentC","replyD","childD","childC","putChild","checkHeightLimit","findCommentNode","getParents","heightLimitRemoveForChildren","insertMode","is_collapsed","is_allow_reply","visible","$listCommentsWrap","ListLayout","getStrategy","max","imgCheck","maxHeight","_check","Utils.getHeight","contains","HEIGHT_LIMIT_SCROLL_CSS","applyScrollableHeightLimit","HEIGHT_LIMIT_CSS","$expandBtn","disposeHeightLimit","afterExpandBtnClick","applyHeightLimit","imgs","renderNick","$headerNick","$nickA","renderVerifyBadge","$headerBadgeWrap","badgeText","badge_name","badgeColor","badge_color","$badge","backgroundColor","is_verified","$verifiedBadge","is_pinned","$pinnedBadge","renderDate","$date","getDateFormatted","renderUABadge","ip_region","$uaWrap","$regionBadge","browser","os","getUserUA","$uaBrowser","$usOS","ActionBtn","getText","adminOnly","isMessaging","msgRecTimer","appendTo","dom","setClick","isLoading","confirmRestore","isConfirming","confirmText","confirmRecTimer","fireMsgRecTimer","clearMsgRecTimer","updateText","loadingText","setMsg","setWarn","setSuccess","duringTime","setMsgRecTimer","msgRecTimerFunc","renderVote","voteBtnUp","getActions","voteBtnDown","vote_down","renderReply","replyBtn","renderCollapse","collapseBtn","adminEdit","renderModerator","pendingBtn","is_pending","renderPin","pinnedBtn","renderEdit","editBtn","renderDel","delBtn","adminDelete","Renders","Avatar","$avatar","$avatarImg","avatarURLBuilder","getGravatarURL","$avatarA","Header","Content","collapsedInfoEl","$body","insertAdjacentElement","contentShowBtn","Ui.playFadeInAnim","ReplyAt","replyTo","$replyAt","goToReplyComment","ReplyTo","$replyTo","$nick","replyContent","Pending","pendingEl","Actions","Render","$main","$childrenWrap","contentMaxH","childrenMaxH","HeightLimit.check","getChildren","HeightLimit.disposeHeightLimit","playFadeAnimForBody","playFlashAnim","getChildrenWrap","setOpenable","setOpenURL","CommentActions","actionBtn","btnElem","modify","setData","onDelete","origHash","modifyHash","dispatchEvent","Event","CommentNode","nestCurt","actionInstance","renderInstance","CommentUI","newEl","onAfterRender","getParent","getNestCurt","getIsRoot","getChildrenWrapEl","$childComment","flattenParents","emailHash","email_encrypted","info","win","nav","osVersion","engine","device","engineMatch","Trident","Presto","WebKit","Gecko","browserMatch","Safari","Chrome","IE","Edge","Firefox","Chromium","Opera","Vivaldi","Yandex","Kindle","UC","QQBrowser","QQ","Baidu","Maxthon","Sogou","LBBROWSER","TheWorld","MIUI","Quark","Qiyu","Wechat","Taobao","Alipay","Weibo","Douban","Suning","iQiYi","osMatch","Windows","Linux","macOS","Android","Ubuntu","FreeBSD","Debian","BlackBerry","MeeGo","Symbian","iOS","WebOS","deviceMatch","Mobile","Tablet","showModalDialog","chrome","arr","browserLanguage","UADetect","ReadMoreBtn","origText","$text","hasMore","total","checkDisabled","showErr","ReadMorePaginator","readMoreAutoLoad","onReachedBottom","getHasMore","getIsClearComments","dispose","Pagination","oninput","onkeydown","keydown","$prevBtn","$nextBtn","maxPage","ceil","setInput","inputTimer","change","onChange","UpDownPaginator","PaginationComponent","resetEditorState","onListGotoFirst","getPageDataByLastData","roots_count","initListPaginatorFunc","paginator","getList","createPaginatorByConf","$paginator","List","initCrudEvents","commentNodes","SidebarLayer","refreshWhenShow","transform","initLayer","createIframe","view","iFrameSrc","getDarkMode","iframeLoad","authCheck","animTimer","time","urlParams","URLSearchParams","DefaultPlugins","findIndex","h","createApiHandlers","config","apiHandlers","layers","checkers","layerManager","sidebarLayer","initMarked","pluginManager","scanApply","$sidebarEl","getAdminOnlyEls","feVer","beVer","comp","pa","pb","na","nb","Utils.versionCompare","ignoreBtn","darkModeAutoHandler","sync","cleanup","_state","voteUpHandler","voteDownHandler","loadOptions","listFetchedHandler","currPageId","checkEls","fetchVoteStatus","handlerOptions","GlobalPlugins","PluginOptions","WeakMap","mount","localConf","loaded","loadPlugins","sidebarOpenView","err_no_site","viewLoadParam","create_name","create_urls","host","onRetry","MountError","remoteConf","ExcludedKeys","startsWith","handleConfFormServer","frontend_conf","scripts","apiBase","networkPlugins","tasks","script","head","onerror","ArtalkPlugins","loadNetworkPlugins","lastVal","newVal","Artalk","getRootEl","EventsService","mounted","ConfigService","loadCountWidget"],"mappings":"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","x_google_ignoreList":[5,6,7,8,9,10,11,12,13,14,15,17]}