{"version":3,"file":"ArtalkLite.cjs","sources":["../src/api/v2.ts","../src/api/fetch.ts","../src/api/index.ts","../../../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/lib/merge-deep.ts","../src/data.ts","../src/lib/utils.ts","../src/i18n/en.ts","../src/i18n/external.ts","../src/i18n/index.ts","../src/i18n/zh-CN.ts","../src/lib/event-manager.ts","../src/defaults.ts","../src/config.ts","../src/lib/watch-conf.ts","../src/context.ts","../src/api/handler.ts","../src/lib/ui.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/lib/component.ts","../src/editor/editor.html?raw","../src/editor/ui.ts","../src/plugins/editor/_plug.ts","../src/plugins/editor/mover.ts","../src/editor/state.ts","../src/editor/editor.ts","../src/layer/sidebar-layer.ts","../src/layer/sidebar-layer.html?raw","../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/scrollbar-helper.ts","../src/layer/layer.ts","../src/layer/wrap.ts","../src/layer/layer-manager.ts","../src/lib/user.ts","../src/service.ts","../src/plugins/stat.ts","../src/plugins/markdown.ts","../src/plugins/editor/local-storage.ts","../src/plugins/editor/submit-add.ts","../src/plugins/editor/submit.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/plugins/editor-kit.ts","../src/plugins/list/goto-focus.ts","../src/components/error-dialog.ts","../src/plugins/version-check.ts","../src/plugins/dark-mode.ts","../src/plugins/index.ts","../src/plugins/admin-only-elem.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/error-dialog.ts","../src/plugins/list/reach-bottom.ts","../src/plugins/list/goto-first.ts","../src/plugins/notifies.ts","../src/load.ts","../src/artalk.ts","../src/main.ts"],"sourcesContent":["/* 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 HandlerParamsVote {\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  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 Vote for a specific comment or page\n *\n * @tags Vote\n * @name Vote\n * @summary Vote\n * @request POST:/votes/{type}/{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    vote: (\n      type: 'comment_up' | 'comment_down' | 'page_up' | 'page_down',\n      targetId: number,\n      vote: HandlerParamsVote,\n      params: RequestParams = {},\n    ) =>\n      this.request<\n        HandlerResponseVote,\n        HandlerMap & {\n          msg?: string\n        }\n      >({\n        path: `/votes/${type}/${targetId}`,\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","'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 { ArtalkConfig } from '@/types'\n\nexport interface RendererOptions {\n  imgLazyLoad: ArtalkConfig['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 { ArtalkConfig } 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: ArtalkConfig['markedOptions']\n  imgLazyLoad: ArtalkConfig['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","/**\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 EventManager from './lib/event-manager'\nimport type {\n  NotifyData,\n  PageData,\n  CommentData,\n  DataManagerApi,\n  ListFetchParams,\n  ListLastFetchData,\n  EventPayloadMap,\n} from '@/types'\n\nexport class DataManager implements DataManagerApi {\n  private loading: boolean = false\n  private listLastFetch?: ListLastFetchData\n  private comments: CommentData[] = [] // Note: 无层级结构 + 无须排列\n  private notifies: NotifyData[] = []\n  private page?: PageData\n\n  constructor(protected events: EventManager<EventPayloadMap>) {}\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","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  frontend: 'Frontend',\n  backend: 'Backend',\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  frontend: '前端',\n  backend: '后端',\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","export type EventHandler<T> = (payload: T) => void\nexport interface Event<PayloadMap, K extends keyof PayloadMap = keyof PayloadMap>\n  extends EventOptions {\n  name: K\n  handler: EventHandler<PayloadMap[K]>\n}\nexport interface EventOptions {\n  once?: boolean\n}\n\nexport interface EventManagerFuncs<PayloadMap> {\n  on<K extends keyof PayloadMap>(\n    name: K,\n    handler: EventHandler<PayloadMap[K]>,\n    opts?: EventOptions,\n  ): void\n  off<K extends keyof PayloadMap>(name: K, handler: EventHandler<PayloadMap[K]>): void\n  trigger<K extends keyof PayloadMap>(name: K, payload?: PayloadMap[K]): void\n}\n\nexport default class EventManager<PayloadMap> implements EventManagerFuncs<PayloadMap> {\n  private events: Event<PayloadMap>[] = []\n\n  /**\n   * Add an event listener for a specific event name\n   */\n  public on<K extends keyof PayloadMap>(\n    name: K,\n    handler: EventHandler<PayloadMap[K]>,\n    opts: EventOptions = {},\n  ) {\n    this.events.push({\n      name,\n      handler: handler as EventHandler<PayloadMap[keyof PayloadMap]>,\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 PayloadMap>(name: K, handler: EventHandler<PayloadMap[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 PayloadMap>(name: K, payload?: PayloadMap[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 type { ArtalkConfig } from '@/types'\n\nconst defaults: ArtalkConfig = {\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: 'https://cdn.jsdelivr.net/gh/ArtalkJS/Emoticons/grps/default.json',\n\n  vote: true,\n  voteDown: false,\n  uaBadge: true,\n  listSort: true,\n  preview: 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  reqTimeout: 15000,\n  versionCheck: true,\n  useBackendConf: true,\n\n  locale: 'en',\n}\n\nif (ARTALK_LITE) {\n  defaults.vote = false\n  defaults.uaBadge = false\n  defaults.emoticons = false\n  defaults.preview = false\n}\n\nexport default defaults\n","import type { ApiOptions } from './api/options'\nimport { mergeDeep } from './lib/merge-deep'\nimport { createApiHandlers } from './api'\nimport Defaults from './defaults'\nimport type { ArtalkConfig, ContextApi } 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: Partial<ArtalkConfig>, full: true): ArtalkConfig\nexport function handelCustomConf(\n  customConf: Partial<ArtalkConfig>,\n  full?: false,\n): Partial<ArtalkConfig>\nexport function handelCustomConf(customConf: Partial<ArtalkConfig>, full = false) {\n  // 合并默认配置\n  const conf: Partial<ArtalkConfig> = full ? mergeDeep(Defaults, customConf) : customConf\n\n  // 绑定元素\n  if (conf.el && typeof conf.el === 'string') {\n    try {\n      const findEl = document.querySelector<HTMLElement>(conf.el)\n      if (!findEl) throw Error(`Target element \"${conf.el}\" was not found.`)\n      conf.el = findEl\n    } catch (e) {\n      console.error(e)\n      throw new Error('Please check your Artalk `el` config.')\n    }\n  }\n\n  // 默认 pageKey\n  if (conf.pageKey === '') conf.pageKey = `${window.location.pathname}` // @link http://bl.ocks.org/abernier/3070589\n\n  // 默认 pageTitle\n  if (conf.pageTitle === '') conf.pageTitle = `${document.title}`\n\n  // 服务器配置\n  if (conf.server) conf.server = conf.server.replace(/\\/$/, '').replace(/\\/api\\/?$/, '')\n\n  // 自适应语言\n  if (conf.locale === 'auto') conf.locale = navigator.language\n\n  // 自动判断启用平铺模式\n  if (conf.flatMode === 'auto') conf.flatMode = window.matchMedia('(max-width: 768px)').matches\n\n  // flatMode\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: Partial<ArtalkConfig>) {\n  const ExcludedKeys: (keyof ArtalkConfig)[] = [\n    'el',\n    'pageKey',\n    'pageTitle',\n    'server',\n    'site',\n    'pvEl',\n    'countEl',\n    'statPageKeyAttr',\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 * 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(conf: Partial<ArtalkConfig>, ctx?: ContextApi): 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: () => ctx?.get('user').getData().token,\n    userInfo: ctx?.get('user').checkHasBasicUserInfo()\n      ? {\n          name: ctx?.get('user').getData().name,\n          email: ctx?.get('user').getData().email,\n        }\n      : undefined,\n    handlers: ctx?.getApiHandlers(),\n  }\n}\n\nexport function createNewApiHandlers(ctx: ContextApi) {\n  const h = createApiHandlers()\n  h.add('need_captcha', (res) => ctx.checkCaptcha(res))\n  h.add('need_login', () => ctx.checkAdmin({}))\n\n  return h\n}\n","import type { ArtalkConfig, ContextApi } from '@/types'\n\nexport function watchConf<T extends (keyof ArtalkConfig)[]>(\n  ctx: ContextApi,\n  keys: T,\n  effect: (conf: Pick<ArtalkConfig, T[number]>) => void,\n): void {\n  const deepEqual = (a: any, b: any) => JSON.stringify(a) === JSON.stringify(b)\n  const val = () => {\n    const conf = ctx.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  ctx.on('mounted', handler)\n  ctx.on('updated', handler)\n}\n","/* eslint-disable @typescript-eslint/no-unsafe-declaration-merging */\nimport type { TInjectedServices } from './service'\nimport { Api, ApiHandlers } from './api'\n\nimport * as marked from './lib/marked'\nimport { mergeDeep } from './lib/merge-deep'\nimport { CheckerCaptchaPayload, CheckerPayload } from './components/checker'\n\nimport { DataManager } from './data'\nimport * as I18n from './i18n'\n\nimport EventManager from './lib/event-manager'\nimport { convertApiOptions, createNewApiHandlers, handelCustomConf } from './config'\nimport { watchConf } from './lib/watch-conf'\n\nimport type {\n  ArtalkConfig,\n  CommentData,\n  ListFetchParams,\n  ContextApi,\n  EventPayloadMap,\n  SidebarShowPayload,\n} from '@/types'\n\n// Auto dependency injection\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\ninterface Context extends TInjectedServices {}\n\n/**\n * Artalk Context\n */\nclass Context implements ContextApi {\n  /* 运行参数 */\n  conf: ArtalkConfig\n  data: DataManager\n  $root: HTMLElement\n\n  /* Event Manager */\n  private events = new EventManager<EventPayloadMap>()\n  private mounted = false\n\n  constructor(conf: ArtalkConfig) {\n    this.conf = conf\n\n    this.$root = conf.el as HTMLElement\n    this.$root.classList.add('artalk')\n    this.$root.innerHTML = ''\n    conf.darkMode && this.$root.classList.add('atk-dark-mode')\n\n    this.data = new DataManager(this.events)\n\n    this.on('mounted', () => {\n      this.mounted = true\n    })\n  }\n\n  inject(depName: string, obj: any) {\n    this[depName] = obj\n  }\n\n  get(depName: string) {\n    return this[depName]\n  }\n\n  getApi() {\n    return new Api(convertApiOptions(this.conf, this))\n  }\n\n  private apiHandlers = <ApiHandlers | null>null\n  getApiHandlers() {\n    if (!this.apiHandlers) this.apiHandlers = createNewApiHandlers(this)\n    return this.apiHandlers\n  }\n\n  getData() {\n    return this.data\n  }\n\n  replyComment(commentData: CommentData, $comment: HTMLElement): void {\n    this.editor.setReply(commentData, $comment)\n  }\n\n  editComment(commentData: CommentData, $comment: HTMLElement): void {\n    this.editor.setEditComment(commentData, $comment)\n  }\n\n  fetch(params: Partial<ListFetchParams>): void {\n    this.data.fetchComments(params)\n  }\n\n  reload(): void {\n    this.data.fetchComments({ offset: 0 })\n  }\n\n  /* List */\n  listGotoFirst(): void {\n    this.events.trigger('list-goto-first')\n  }\n\n  getCommentNodes() {\n    return this.list.getCommentNodes()\n  }\n\n  getComments() {\n    return this.data.getComments()\n  }\n\n  getCommentList = this.getCommentNodes\n  getCommentDataList = this.getComments\n\n  /* Editor */\n  editorShowLoading(): void {\n    this.editor.showLoading()\n  }\n\n  editorHideLoading(): void {\n    this.editor.hideLoading()\n  }\n\n  editorShowNotify(msg, type): void {\n    this.editor.showNotify(msg, type)\n  }\n\n  editorResetState(): void {\n    this.editor.resetState()\n  }\n\n  /* Sidebar */\n  showSidebar(payload?: SidebarShowPayload): void {\n    this.sidebarLayer.show(payload)\n  }\n\n  hideSidebar(): void {\n    this.sidebarLayer.hide()\n  }\n\n  /* Checker */\n  checkAdmin(payload: CheckerPayload): Promise<void> {\n    return this.checkerLauncher.checkAdmin(payload)\n  }\n\n  checkCaptcha(payload: CheckerCaptchaPayload): Promise<void> {\n    return this.checkerLauncher.checkCaptcha(payload)\n  }\n\n  /* Events */\n  on(name: any, handler: any) {\n    this.events.on(name, handler)\n  }\n\n  off(name: any, handler: any) {\n    this.events.off(name, handler)\n  }\n\n  trigger(name: any, payload?: any) {\n    this.events.trigger(name, payload)\n  }\n\n  /* i18n */\n  $t(key: I18n.I18nKeys, args: { [key: string]: string } = {}): string {\n    return I18n.t(key, args)\n  }\n\n  setDarkMode(darkMode: boolean | 'auto'): void {\n    this.updateConf({ darkMode })\n  }\n\n  updateConf(nConf: Partial<ArtalkConfig>): void {\n    this.conf = mergeDeep(this.conf, handelCustomConf(nConf, false))\n    this.mounted && this.events.trigger('updated', this.conf)\n  }\n\n  getConf(): ArtalkConfig {\n    return this.conf\n  }\n\n  getEl(): HTMLElement {\n    return this.$root\n  }\n\n  getMarked() {\n    return marked.getInstance()\n  }\n\n  watchConf<T extends (keyof ArtalkConfig)[]>(\n    keys: T,\n    effect: (conf: Pick<ArtalkConfig, T[number]>) => void,\n  ): void {\n    watchConf(this, keys, effect)\n  }\n}\n\nexport default Context\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 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 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 type { ContextApi } from '@/types'\nimport type User from '@/lib/user'\nimport * as Utils from '@/lib/utils'\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  getCtx: () => ContextApi\n  getApi: () => Api\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 发射台\n */\nexport default class CheckerLauncher {\n  constructor(private opts: CheckerLauncherOptions) {}\n\n  public checkCaptcha: (payload: CheckerCaptchaPayload) => Promise<void> = wrapPromise((p) => {\n    this.fire(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.fire(AdminChecker, p)\n  })\n\n  public fire(checker: Checker, payload: CheckerPayload, postFire?: (c: CheckerCtx) => void) {\n    // 显示层\n    const layer = this.opts.getCtx().get('layerManager').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.getCtx().get('user'),\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 (postFire) postFire(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(): User\n  hideInteractInput(): void\n  triggerSuccess(): void\n  cancel(): void\n}\n","import type { ContextApi } from '@/types'\n\nexport default abstract class Component {\n  public $el!: HTMLElement\n  public get conf() {\n    return this.ctx.conf\n  }\n\n  public constructor(public ctx: ContextApi) {}\n\n  getEl() {\n    return this.$el\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 * 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 type PlugKit from './_kit'\nimport type { CommentData, EditorState } from '@/types'\nimport * as Utils from '@/lib/utils'\n\n/**\n * Editor 插件\n */\nclass EditorPlug {\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 EditorPlug\n","import EditorPlug from './_plug'\nimport * as Utils from '@/lib/utils'\n\nexport default class Mover extends EditorPlug {\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      .useGlobalCtx()\n      .$root.querySelector('.atk-editor-travel-placeholder')\n      ?.replaceWith(this.kit.useUI().$el)\n    this.kit.useUI().$el.classList.remove('editor-traveling')\n  }\n}\n","import Mover from '../plugins/editor/mover'\nimport type Editor from './editor'\nimport type { EditorState, CommentData } from '@/types'\nimport * as Ui from '@/lib/ui'\n\nexport default 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.getPlugs()?.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.conf.flatMode)\n        moveAfterEl = moveAfterEl.querySelector<HTMLElement>('.atk-footer')!\n      this.editor.getPlugs()?.get(Mover)?.move(moveAfterEl)\n\n      const $relative =\n        this.editor.ctx.conf.scrollRelativeTo && this.editor.ctx.conf.scrollRelativeTo()\n      Ui.scrollIntoView(this.editor.getUI().$el, true, $relative)\n\n      const plugin = this.editor\n        .getPlugs()\n        ?.getPlugs()\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 Component from '../lib/component'\nimport * as Ui from '../lib/ui'\nimport marked from '../lib/marked'\nimport { render, EditorUI } from './ui'\nimport EditorStateManager from './state'\nimport type { CommentData, ContextApi, EditorApi } from '@/types'\n\nclass Editor extends Component implements EditorApi {\n  private ui: EditorUI\n  private state: EditorStateManager\n\n  getUI() {\n    return this.ui\n  }\n  getPlugs() {\n    return this.ctx.get('editorPlugs')\n  }\n  getState() {\n    return this.state.get()\n  }\n\n  constructor(ctx: ContextApi) {\n    super(ctx)\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  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    // plug hook: final content transformer\n    const plugs = this.getPlugs()\n    if (plugs) content = plugs.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.getPlugs()?.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  setReply(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 = () => this.ctx.trigger('editor-submit')\n    if (this.ctx.conf.beforeSubmit) {\n      this.ctx.conf.beforeSubmit(this, next)\n    } else {\n      next()\n    }\n  }\n}\n\nexport default Editor\n","import SidebarHTML from './sidebar-layer.html?raw'\nimport type { Layer } from './layer'\nimport type { ContextApi, SidebarShowPayload } from '@/types'\nimport Component from '@/lib/component'\nimport * as Utils from '@/lib/utils'\nimport * as Ui from '@/lib/ui'\n\nexport default class SidebarLayer extends Component {\n  public layer?: Layer\n  public $header: HTMLElement\n  public $closeBtn: HTMLElement\n  public $iframeWrap: HTMLElement\n  public $iframe?: HTMLIFrameElement\n\n  constructor(ctx: ContextApi) {\n    super(ctx)\n\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    // event\n    this.ctx.on('user-changed', () => {\n      this.refreshWhenShow = true\n    })\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      setTimeout(() => {\n        this.ctx.getData().updateNotifies([])\n      }, 0)\n\n      this.ctx.trigger('sidebar-show')\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.ctx.getApi().user.getUserStatus({\n        ...this.ctx.getApi().getUserFields(),\n      })\n    ).data\n    if (data.is_admin && !data.is_login) {\n      this.refreshWhenShow = true\n\n      // show checker layer\n      this.ctx.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.ctx.get('layerManager').create('sidebar', this.$el)\n    this.layer.setOnAfterHide(() => {\n      // 防止评论框被吞\n      this.ctx.editorResetState()\n\n      // interrupt animation\n      this.animTimer && clearTimeout(this.animTimer)\n\n      // perform transform\n      this.$el.style.transform = ''\n\n      // trigger event\n      this.ctx.trigger('sidebar-hide')\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.ctx.conf.server,\n          path: '/sidebar/',\n        })\n\n    const query: any = {\n      pageKey: this.conf.pageKey,\n      site: this.conf.site || '',\n      user: JSON.stringify(this.ctx.get('user').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.conf.darkMode === 'auto'\n      ? window.matchMedia('(prefers-color-scheme: dark)').matches\n      : this.conf.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 { LayoutStrategyCreator } from '.'\nimport type { CommentNode } from '@/comment'\nimport * as Ui from '@/lib/ui'\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'\nimport * as Ui from '@/lib/ui'\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-verified-icon\" 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 * as Utils from '../../lib/utils'\nimport 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\n  const replyBtn = Utils.createElement(`<span>${$t('reply')}</span>`)\n  r.$actions.append(replyBtn)\n  replyBtn.addEventListener('click', (e) => {\n    e.stopPropagation() // 防止穿透\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(type: 'up' | 'down') {\n    const actionBtn =\n      type === 'up' ? this.comment.getRender().voteBtnUp : this.comment.getRender().voteBtnDown\n\n    this.getApi()\n      .votes.vote(`comment_${type}`, this.data.id, {\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, ArtalkConfig, ContextApi } 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: ArtalkConfig['gravatar']\n  heightLimit: ArtalkConfig['heightLimit']\n  avatarURLBuilder: ArtalkConfig['avatarURLBuilder']\n  scrollRelativeTo: ArtalkConfig['scrollRelativeTo']\n  dateFormatter: ArtalkConfig['dateFormatter']\n\n  // TODO: Move to plugin folder and remove from core\n  getApi: () => Api\n  replyComment: ContextApi['replyComment']\n  editComment: ContextApi['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 type { ListFetchParams } from '@/types'\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.ctx.fetch({\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.ctx.getData().getLoading()) return\n        this.instance.click()\n      }\n      this.opt.ctx.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.ctx.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.ctx.editorResetState() // 防止评论框被吞\n\n        opt.ctx.fetch({\n          offset: o,\n          onSuccess: () => {\n            opt.ctx.listGotoFirst()\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 { Paginator } from './paginator'\nimport ReadMorePaginator from './paginator/read-more'\nimport UpDownPaginator from './paginator/up-down'\nimport $t from '@/i18n'\nimport type { ArtalkConfig, ContextApi } from '@/types'\n\nfunction createPaginatorByConf(conf: Pick<ArtalkConfig, 'pagination'>): Paginator {\n  if (conf.pagination.readMore) return new ReadMorePaginator()\n  return new UpDownPaginator()\n}\n\nfunction getPageDataByLastData(ctx: ContextApi): {\n  offset: number\n  total: number\n} {\n  const last = ctx.getData().getListLastFetch()\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 const initListPaginatorFunc = (ctx: ContextApi) => {\n  let paginator: Paginator | null = null\n\n  // Init paginator when conf loaded\n  ctx.watchConf(['pagination', 'locale'], (conf) => {\n    const list = ctx.get('list')\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(ctx)\n    const $paginator = paginator.create({\n      ctx,\n      pageSize: conf.pagination.pageSize,\n      total,\n\n      readMoreAutoLoad: conf.pagination.autoLoad,\n    })\n\n    // mount paginator dom\n    list.$commentsWrap.after($paginator)\n\n    // update paginator info\n    paginator?.update(offset, total)\n  })\n\n  // When list loaded\n  ctx.on('list-loaded', (comments) => {\n    // update paginator info\n    const { offset, total } = getPageDataByLastData(ctx)\n    paginator?.update(offset, total)\n  })\n\n  // When list fetch\n  ctx.on('list-fetch', (params) => {\n    // if clear comments when fetch new page data\n    if (ctx.getData().getComments().length > 0 && paginator?.getIsClearComments(params)) {\n      ctx.getData().clearComments()\n    }\n  })\n\n  // When list error\n  ctx.on('list-failed', () => {\n    paginator?.showErr?.($t('loadFail'))\n  })\n\n  // loading\n  ctx.on('list-fetch', (params) => {\n    paginator?.setLoading(true)\n  })\n  ctx.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 { ContextApi } from '@/types'\nimport Component from '@/lib/component'\nimport * as Utils from '@/lib/utils'\nimport { CommentNode } from '@/comment'\n\nexport default class List extends Component {\n  /** 列表评论集区域元素 */\n  $commentsWrap!: HTMLElement\n  public getCommentsWrapEl() {\n    return this.$commentsWrap\n  }\n\n  protected commentNodes: CommentNode[] = []\n  getCommentNodes() {\n    return this.commentNodes\n  }\n\n  constructor(ctx: ContextApi) {\n    super(ctx)\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(ctx)\n\n    // Bind events\n    this.initCrudEvents()\n  }\n\n  getListLayout({ forceFlatMode }: { forceFlatMode?: boolean } = {}) {\n    return new ListLayout({\n      $commentsWrap: this.$commentsWrap,\n      nestSortBy: this.ctx.conf.nestSort,\n      nestMax: this.ctx.conf.nestMax,\n      flatMode:\n        typeof forceFlatMode === 'boolean' ? forceFlatMode : (this.ctx.conf.flatMode as boolean),\n      // flatMode must be boolean because it had been handled when Artalk.init\n      createCommentNode: (d, r) => {\n        const node = createCommentNode(this.ctx, d, r, { forceFlatMode })\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.ctx.on('list-load', (comments) => {\n      // 导入数据\n      this.getListLayout().import(comments)\n    })\n\n    this.ctx.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.ctx.on('comment-inserted', (comment) => {\n      const replyComment = comment.rid\n        ? this.commentNodes.find((c) => c.getID() === comment.rid)?.getData()\n        : undefined\n      this.getListLayout().insert(comment, replyComment)\n    })\n\n    // When comment delete\n    this.ctx.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.ctx.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 { ContextApi, CommentData } from '@/types'\nimport { CommentNode } from '@/comment'\n\ninterface CreateCommentNodeOptions {\n  forceFlatMode?: boolean\n}\n\nexport function createCommentNode(\n  ctx: ContextApi,\n  comment: CommentData,\n  replyComment?: CommentData,\n  opts?: CreateCommentNodeOptions,\n): CommentNode {\n  const instance = new CommentNode(comment, {\n    onAfterRender: () => {\n      ctx.trigger('comment-rendered', instance)\n    },\n    onDelete: (c: CommentNode) => {\n      ctx.getData().deleteComment(c.getID())\n    },\n\n    replyTo: replyComment,\n\n    // TODO simplify reference\n    flatMode:\n      typeof opts?.forceFlatMode === 'boolean'\n        ? opts?.forceFlatMode\n        : (ctx.conf.flatMode as boolean),\n    gravatar: ctx.conf.gravatar,\n    nestMax: ctx.conf.nestMax,\n    heightLimit: ctx.conf.heightLimit,\n    avatarURLBuilder: ctx.conf.avatarURLBuilder,\n    scrollRelativeTo: ctx.conf.scrollRelativeTo,\n    vote: ctx.conf.vote,\n    voteDown: ctx.conf.voteDown,\n    uaBadge: ctx.conf.uaBadge,\n    dateFormatter: ctx.conf.dateFormatter,\n\n    // TODO: move to plugin folder and remove from core\n    getApi: () => ctx.getApi(),\n    replyComment: (c, $el) => ctx.replyComment(c, $el),\n    editComment: (c, $el) => ctx.editComment(c, $el),\n  })\n\n  // 渲染元素\n  instance.render()\n\n  return instance\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 type { Layer as LayerApi } from '@/types/layer'\n\nexport interface LayerOptions {\n  onShow: () => void\n  onHide: () => void\n}\n\nexport class Layer implements LayerApi {\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 { 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 { ContextApi } from '@/types'\n\nexport class LayerManager {\n  private wrap: LayerWrap\n\n  constructor(ctx: ContextApi) {\n    this.wrap = new LayerWrap()\n    document.body.appendChild(this.wrap.getWrap())\n\n    ctx.on('unmounted', () => {\n      this.wrap.getWrap().remove()\n    })\n\n    // 记录页面原始 CSS 属性\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","import type { LocalUser } from '@/types'\n\nconst LOCAL_USER_KEY = 'ArtalkUser'\n\ninterface UserOpts {\n  onUserChanged?: (user: LocalUser) => void\n}\n\nclass User {\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 User\n","import CheckerLauncher from './components/checker'\nimport Editor from './editor/editor'\nimport SidebarLayer from './layer/sidebar-layer'\n\nimport List from './list/list'\n\nimport * as I18n from './i18n'\nimport { PlugManager } from './plugins/editor-kit'\nimport { LayerManager } from './layer/layer-manager'\nimport User from './lib/user'\nimport type { ContextApi } from '@/types'\n\n/**\n * Services\n *\n * @description Call these services by `ctx.get('serviceName')` or `ctx.serviceName`\n */\nconst services = {\n  // I18n\n  i18n(ctx: ContextApi) {\n    I18n.setLocale(ctx.conf.locale)\n\n    ctx.watchConf(['locale'], (conf) => {\n      I18n.setLocale(conf.locale)\n    })\n  },\n\n  // User Store\n  user(ctx: ContextApi) {\n    const user = new User({\n      onUserChanged: (data) => {\n        ctx.trigger('user-changed', data)\n      },\n    })\n    return user\n  },\n\n  // 弹出层\n  layerManager(ctx: ContextApi) {\n    return new LayerManager(ctx)\n  },\n\n  // CheckerLauncher\n  checkerLauncher(ctx: ContextApi) {\n    const checkerLauncher = new CheckerLauncher({\n      getCtx: () => ctx,\n      getApi: () => ctx.getApi(),\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: () => `${ctx.conf.server}/api/v2/captcha/?t=${+new Date()}`,\n    })\n    return checkerLauncher\n  },\n\n  // 编辑器\n  editor(ctx: ContextApi) {\n    const editor = new Editor(ctx)\n    ctx.$root.appendChild(editor.$el)\n    return editor\n  },\n\n  // 评论列表\n  list(ctx: ContextApi): List {\n    const list = new List(ctx)\n    ctx.$root.appendChild(list.$el)\n    return list\n  },\n\n  // 侧边栏 Layer\n  sidebarLayer(ctx: ContextApi) {\n    const sidebarLayer = new SidebarLayer(ctx)\n    return sidebarLayer\n  },\n\n  // Extra Service\n  // -----------------------------------------\n  // Only for type check\n  // Not inject to ctx immediately,\n  // but can be injected by other occasions\n\n  editorPlugs(): PlugManager | undefined {\n    return undefined\n  },\n}\n\nexport default services\n\n// type tricks for dependency injection\ntype TServiceImps = typeof services\ntype TObjectWithFuncs = { [k: string]: (...args: any) => any }\ntype TKeysOnlyReturn<T extends TObjectWithFuncs, V> = {\n  [K in keyof T]: ReturnType<T[K]> extends V ? K : never\n}[keyof T]\ntype TOmitConditions = TKeysOnlyReturn<TServiceImps, void>\ntype TServiceInjectors = Omit<TServiceImps, TOmitConditions>\nexport type TInjectedServices = {\n  [K in keyof TServiceInjectors]: ReturnType<TServiceInjectors[K]>\n}\n","import type { ContextApi, ArtalkPlugin, ArtalkConfig } 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: ContextApi) => {\n  ctx.watchConf(['site', 'pageKey', 'pageTitle', 'countEl', 'pvEl', 'statPageKeyAttr'], (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: typeof ctx.conf.pvAdd === 'boolean' ? ctx.conf.pvAdd : true,\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","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: ctx.getConf().markedOptions,\n      imgLazyLoad: ctx.getConf().imgLazyLoad,\n    })\n  })\n\n  ctx.watchConf(['markedReplacers'], (conf) => {\n    conf.markedReplacers && marked.setReplacers(conf.markedReplacers)\n  })\n}\n","import type PlugKit from './_kit'\nimport EditorPlug from './_plug'\nimport $t from '@/i18n'\n\nconst LocalStorageKey = 'ArtalkContent'\n\nexport default class LocalStorage extends EditorPlug {\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.useGlobalCtx().getData().insertComment(commentNew)\n  }\n}\n","import EditorPlug 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 EditorPlug {\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.useGlobalCtx().on('editor-submit', onEditorSubmit)\n    })\n    this.kit.useUnmounted(() => {\n      this.kit.useGlobalCtx().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.useGlobalCtx().trigger('editor-submitted')\n  }\n}\n","import './emoticons.scss'\n\nimport EditorPlug 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 EditorPlug {\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 EditorPlug 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 EditorPlug {\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 EditorPlug from './_plug'\nimport type PlugKit from './_kit'\nimport * as marked from '@/lib/marked'\nimport $t from '@/i18n'\n\nexport default class Preview extends EditorPlug {\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 EditorPlug 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 { ArtalkConfig } from '@/types'\n\n/** The default enabled plugs */\nconst EDITOR_PLUGS: (typeof EditorPlug)[] = [\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<ArtalkConfig, 'imgUpload' | 'emoticons' | 'preview' | 'editorTravel'>,\n): (typeof EditorPlug)[] {\n  // The reference map of config and plugs\n  // (for check if the plug is enabled)\n  const confRefs = new Map<typeof EditorPlug, 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 EditorPlug from './_plug'\nimport type PlugKit from './_kit'\n\nexport default class HeaderEvent extends EditorPlug {\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 EditorPlug from './_plug'\nimport type PlugKit from './_kit'\nimport $t from '@/i18n'\nimport type { UserInfoApiResponseData } from '@/types'\n\nexport default class HeaderUser extends EditorPlug {\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.useGlobalCtx().getData().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.useGlobalCtx().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 EditorPlug from './_plug'\nimport type PlugKit from './_kit'\n\nexport default class HeaderLink extends EditorPlug {\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 EditorPlug from './_plug'\nimport type PlugKit from './_kit'\nimport $t from '@/i18n'\n\nexport default class Textarea extends EditorPlug {\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 EditorPlug from './_plug'\nimport type PlugKit from './_kit'\nimport $t from '@/i18n'\n\nexport default class SubmitBtn extends EditorPlug {\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 EditorPlug 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 * as Ui from '@/lib/ui'\nimport $t from '@/i18n'\n\nexport default class StateReply extends EditorPlug {\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 EditorPlug 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 EditorPlug {\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.useGlobalCtx().getData().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 EditorPlug from './_plug'\nimport type PlugKit from './_kit'\nimport * as Utils from '@/lib/utils'\nimport $t from '@/i18n'\n\nexport default class Closable extends EditorPlug {\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 { PlugManager } from '../editor-kit'\nimport type EditorPlug 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 plugs: PlugManager) {}\n\n  /** Use the editor */\n  useEditor() {\n    return this.plugs.editor\n  }\n\n  /**\n   * Use the context of global\n   *\n   * @deprecated The calls to this function should be reduced as much as possible\n   */\n  useGlobalCtx() {\n    return this.plugs.editor.ctx\n  }\n\n  /** Use the config of Artalk */\n  useConf() {\n    return this.plugs.editor.ctx.conf\n  }\n\n  /** Use the http api client */\n  useApi() {\n    return this.plugs.editor.ctx.getApi()\n  }\n\n  /** Use the user manager */\n  useUser() {\n    return this.plugs.editor.ctx.get('user')\n  }\n\n  /** Use the ui of editor */\n  useUI() {\n    return this.plugs.editor.getUI()\n  }\n\n  /** Use the events in editor scope */\n  useEvents() {\n    return this.plugs.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 EditorPlug>(plug: T) {\n    return this.plugs.get(plug)\n  }\n}\n","import { getEnabledPlugs } from './editor'\nimport EditorPlug from './editor/_plug'\nimport PlugKit from './editor/_kit'\nimport EventManager from '@/lib/event-manager'\nimport type { EditorApi, ArtalkPlugin } from '@/types'\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': EditorPlug\n  'panel-hide': EditorPlug\n  'panel-close': undefined\n\n  'editor-close': undefined\n  'editor-open': undefined\n}\n\nexport const EditorKit: ArtalkPlugin = (ctx) => {\n  const editor = ctx.get('editor')\n\n  const editorPlugs = new PlugManager(editor)\n  ctx.inject('editorPlugs', editorPlugs)\n}\n\nexport class PlugManager {\n  private plugs: EditorPlug[] = []\n  private openedPlug: EditorPlug | null = null\n  private events = new EventManager<EditorEventPayloadMap>()\n\n  getPlugs() {\n    return this.plugs\n  }\n  getEvents() {\n    return this.events\n  }\n\n  private clear() {\n    this.plugs = []\n    this.events = new EventManager()\n    if (this.openedPlug) this.closePlugPanel()\n  }\n\n  constructor(public editor: EditorApi) {\n    let confLoaded = false // config not loaded at first time\n    this.editor.ctx.watchConf(\n      ['imgUpload', 'emoticons', 'preview', 'editorTravel', 'locale'],\n      (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.plugs.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\n    this.events.on('panel-close', () => this.closePlugPanel())\n  }\n\n  private loadPluginUI() {\n    // handle ui, clear and reset the plug btns and plug panels\n    this.editor.getUI().$plugPanelWrap.innerHTML = ''\n    this.editor.getUI().$plugPanelWrap.style.display = 'none'\n    this.editor.getUI().$plugBtnWrap.innerHTML = ''\n\n    // load the plug UI\n    this.plugs.forEach((plug) => this.loadPluginItem(plug))\n  }\n\n  /** Load the plug btn and plug panel on editor ui */\n  private loadPluginItem(plug: EditorPlug) {\n    const $btn = plug.$btn\n    if (!$btn) return\n    this.editor.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.editor\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.openPlugPanel(plug)\n\n          // add active class for current plug panel\n          $btn.classList.add('active')\n        } else {\n          // then close the plug\n          this.closePlugPanel()\n        }\n      })\n\n    // initialization of plug panel\n    const $panel = plug.$panel\n    if ($panel) {\n      $panel.style.display = 'none'\n      this.editor.getUI().$plugPanelWrap.appendChild($panel)\n    }\n  }\n\n  get<T extends typeof EditorPlug>(plug: T) {\n    return this.plugs.find((p) => p instanceof plug) as InstanceType<T> | undefined\n  }\n\n  /** Open the editor plug panel */\n  openPlugPanel(plug: EditorPlug) {\n    this.plugs.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.editor.getUI().$plugPanelWrap.style.display = ''\n    this.openedPlug = plug\n  }\n\n  /** Close the editor plug panel */\n  closePlugPanel() {\n    if (!this.openedPlug) return\n\n    this.editor.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.plugs.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  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      ctx\n        .get('list')\n        .getListLayout({ forceFlatMode: true })\n        .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 type { ArtalkPlugin } from '@/types'\nimport { version as ARTALK_VERSION } from '~/package.json'\nimport type List from '~/src/list/list'\nimport * as Ui from '@/lib/ui'\nimport * as Utils from '@/lib/utils'\nimport $t from '@/i18n'\n\nlet IgnoreVersionCheck = false\n\nexport const VersionCheck: ArtalkPlugin = (ctx) => {\n  ctx.watchConf(['apiVersion', 'versionCheck'], (conf) => {\n    const list = ctx.get('list')\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('frontend') : $t('backend'),\n    })} <span class=\"atk-info\">` +\n      `${$t('currentVersion')}: ${$t('frontend')} ${feVer} / ${$t('backend')} ${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.$el.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  // 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.$root, ctx.get('layerManager').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(ctx.conf.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 { 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 type { ArtalkPlugin } from '@/types'\n\nexport const DefaultPlugins: ArtalkPlugin[] = [\n  Markdown,\n  EditorKit,\n  AdminOnlyElem,\n  ...ListPlugins,\n  Notifies,\n  PvCountWidget,\n  VersionCheck,\n  DarkMode,\n]\n","import type { ArtalkPlugin } from '@/types'\n\nexport const AdminOnlyElem: ArtalkPlugin = (ctx) => {\n  const scanApply = () => {\n    applyAdminOnlyEls(\n      ctx.get('user').getData().is_admin,\n      getAdminOnlyEls({\n        $root: ctx.$root,\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 { 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  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: ctx.conf.pagination.pageSize,\n      flatMode: ctx.conf.flatMode as boolean, // always be boolean because had been handled in Artalk.init\n      paramsModifier: ctx.conf.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: ctx.getConf().pageKey,\n      site_name: ctx.getConf().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  ctx.on('list-fetch', (p) => {\n    const list = ctx.get('list')\n\n    if (p.offset === 0)\n      // only show loading when fetch first page\n      Ui.setLoading(true, list.$el)\n    // else if not first page, show loading in paginator (code not there)\n  })\n\n  ctx.on('list-fetched', () => {\n    const list = ctx.get('list')\n    Ui.setLoading(false, list.$el)\n  })\n}\n","import type { ArtalkPlugin } from '@/types'\nimport * as Utils from '@/lib/utils'\n\nexport const Unread: ArtalkPlugin = (ctx) => {\n  ctx.on('comment-rendered', (comment) => {\n    // comment unread highlight\n    if (ctx.conf.listUnreadHighlight === true) {\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 { ContextApi, ArtalkPlugin, PageData } from '@/types'\nimport $t from '@/i18n'\n\nexport const WithEditor: ArtalkPlugin = (ctx) => {\n  let $closeCommentBtn: HTMLElement | undefined\n\n  // on Artalk mounted\n  // (after all components had mounted)\n  ctx.on('mounted', () => {\n    const list = ctx.get('list')\n\n    $closeCommentBtn = list.$el.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    const editor = ctx.get('editor')\n\n    // if page comment is closed\n    if (page?.admin_only === true) {\n      // then close editor\n      editor.getPlugs()?.getEvents().trigger('editor-close')\n      $closeCommentBtn && ($closeCommentBtn.innerText = $t('openComment'))\n    } else {\n      // the open editor\n      editor.getPlugs()?.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: ContextApi, 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 refreshCountNumEl = () => {\n    const list = ctx.get('list')\n\n    const $count = list.$el.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  let $openSidebarBtn: HTMLElement | null = null\n\n  const syncByUser = () => {\n    if (!$openSidebarBtn) return\n    const user = ctx.get('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    const list = ctx.get('list')\n\n    $openSidebarBtn = list.$el.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  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    const list = ctx.get('list')\n\n    $unreadBadge = list.$el.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 reloadUseParamsEditor = (func: (p: any) => void) => {\n    ctx.conf.listFetchParamsModifier = func\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 list = ctx.get('list')\n\n    const $count = list.$el.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  ctx.on('list-loaded', (comments) => {\n    const list = ctx.get('list')!\n\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(list.ctx.conf.noComment || list.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  ctx.on('mounted', () => {\n    const list = ctx.get('list')\n\n    const $copyright = list.$el.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  let timer: number | null = null\n\n  ctx.on('mounted', () => {\n    timer = window.setInterval(() => {\n      const list = ctx.get('list')\n\n      list.$el.querySelectorAll<HTMLElement>('[data-atk-comment-date]').forEach((el) => {\n        const date = new Date(Number(el.getAttribute('data-atk-comment-date')))\n        el.innerText = ctx.getConf().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 * as Ui from '../../lib/ui'\nimport type { ArtalkPlugin, ContextApi } from '@/types'\nimport { showErrorDialog } from '@/components/error-dialog'\n\nexport const ErrorDialog: ArtalkPlugin = (ctx) => {\n  ctx.on('list-fetch', () => {\n    const list = ctx.get('list')\n\n    // clear the original error when a new fetch is triggered\n    Ui.setError(list.$el, null)\n  })\n\n  ctx.on('list-failed', (err) => {\n    showErrorDialog({\n      $err: ctx.get('list').$el,\n      errMsg: err.msg,\n      errData: err.data,\n      retryFn: () => ctx.fetch({ offset: 0 }),\n    })\n  })\n}\n","import type { ArtalkPlugin } from '@/types'\n\nexport const ReachBottom: ArtalkPlugin = (ctx) => {\n  let observer: IntersectionObserver | null = null\n\n  const setupObserver = ($target: HTMLElement) => {\n    const scrollEvtAt = (ctx.conf.scrollRelativeTo && ctx.conf.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    const list = ctx.get('list')\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 handler = () => {\n    const list = ctx.get('list')\n\n    const $relative = ctx.conf.scrollRelativeTo && ctx.conf.scrollRelativeTo()\n    ;($relative || window).scroll({\n      top: Utils.getOffset(list.$el, $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 } 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 { DefaultPlugins } from './plugins'\nimport type { ArtalkConfig, ArtalkPlugin, ContextApi } from '@/types'\nimport { handleConfFormServer } from '@/config'\nimport { showErrorDialog } from '@/components/error-dialog'\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 load(ctx: ContextApi) {\n  const loadedPlugins = new Set<ArtalkPlugin>()\n  const loadPlugins = (plugins: Set<ArtalkPlugin>) => {\n    plugins.forEach((plugin) => {\n      if (typeof plugin === 'function' && !loadedPlugins.has(plugin)) {\n        plugin(ctx, PluginOptions.get(plugin))\n        loadedPlugins.add(plugin)\n      }\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      onLoadErr(ctx, err)\n      throw err\n    })\n\n  // Initial config\n  let conf: Partial<ArtalkConfig> = {\n    apiVersion: data.version?.version, // version info\n  }\n\n  // Reference conf from backend\n  if (ctx.conf.useBackendConf) {\n    if (!data.frontend_conf)\n      throw new Error(\n        'The remote backend does not respond to the frontend conf, but `useBackendConf` conf is enabled',\n      )\n    conf = { ...conf, ...handleConfFormServer(data.frontend_conf) }\n  }\n\n  // Apply conf modifier\n  ctx.conf.remoteConfModifier && ctx.conf.remoteConfModifier(conf)\n\n  // Dynamically load network plugins\n  conf.pluginURLs &&\n    (await loadNetworkPlugins(conf.pluginURLs, ctx.conf.server)\n      .then((plugins) => {\n        loadPlugins(plugins)\n      })\n      .catch((err) => {\n        console.error('Failed to load plugin', err)\n      }))\n\n  // After all plugins are loaded\n  ctx.trigger('created')\n\n  // Apply conf updating\n  ctx.updateConf(conf)\n\n  // Trigger mounted event\n  ctx.trigger('mounted')\n\n  // Load comment list\n  if (!ctx.conf.remoteConfModifier) {\n    // only auto fetch when no remoteConfModifier\n    ctx.fetch({ offset: 0 })\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\nexport function onLoadErr(ctx: ContextApi, err: any) {\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: ctx.conf.site,\n      create_urls: `${window.location.protocol}//${window.location.host}`,\n    }\n    sidebarOpenView = `sites|${JSON.stringify(viewLoadParam)}`\n  }\n\n  showErrorDialog({\n    $err: ctx.get('list').$el,\n    errMsg: err.msg || String(err),\n    errData: err.data,\n    retryFn: () => load(ctx),\n    onOpenSidebar: ctx.get('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 './style/main.scss'\n\nimport type { EventHandler } from './lib/event-manager'\nimport Context from './context'\nimport { handelCustomConf, convertApiOptions } from './config'\nimport Services from './service'\nimport * as Stat from './plugins/stat'\nimport { Api } from './api'\nimport type { TInjectedServices } from './service'\nimport { GlobalPlugins, PluginOptions, load } from './load'\nimport type { ArtalkConfig, EventPayloadMap, ArtalkPlugin, ContextApi } from '@/types'\n\n/**\n * Artalk\n *\n * @see https://artalk.js.org\n */\nexport default class Artalk {\n  public ctx!: ContextApi\n\n  constructor(conf: Partial<ArtalkConfig>) {\n    // Init Config\n    const handledConf = handelCustomConf(conf, true)\n\n    // Init Context\n    this.ctx = new Context(handledConf)\n\n    // Init Services\n    Object.entries(Services).forEach(([name, initService]) => {\n      const obj = initService(this.ctx)\n      obj && this.ctx.inject(name as keyof TInjectedServices, obj) // auto inject deps to ctx\n    })\n\n    if (import.meta.env.DEV && import.meta.env.VITEST) {\n      global.devLoadArtalk = () => load(this.ctx)\n    } else {\n      load(this.ctx)\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.$root\n  }\n\n  /** Update config of Artalk */\n  public update(conf: Partial<ArtalkConfig>) {\n    this.ctx.updateConf(conf)\n    return this\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.trigger('unmounted')\n    while (this.ctx.$root.firstChild) {\n      this.ctx.$root.removeChild(this.ctx.$root.firstChild)\n    }\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: Partial<ArtalkConfig>): 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: Partial<ArtalkConfig>) {\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\n  /** @deprecated Please use `getEl()` instead */\n  public get $root() {\n    return this.ctx.$root\n  }\n\n  /** @description Please use `getConf()` instead */\n  public get conf() {\n    return this.ctx.getConf()\n  }\n}\n","import Artalk from './artalk'\nimport type * as ArtalkType from './types'\n\nexport type * from './types'\nexport { ArtalkType }\n\nexport default Artalk\n\n// Expose the static methods from the Artalk class\n// because direct export of static methods is not supported\n// for adapting to different environments like CommonJS and browser IIFE\n// for example, we can use `Artalk.init()` rather than `Artalk.default.init()`\n// therefore, we need to manually expose the static methods in the Artalk class.\nexport const init = Artalk.init\nexport const use = Artalk.use\nexport const loadCountWidget = Artalk.loadCountWidget\n"],"names":["HttpClient","constructor","apiConfig","__publicField","this","Map","fetchParams","fetch","credentials","headers","redirect","referrerPolicy","data","securityData","input","JSON","stringify","Object","keys","reduce","formData","key","property","append","Blob","FormData","toQueryString","cancelToken","abortControllers","has","abortController","get","signal","AbortController","set","abort","delete","_a","__async","_b","body","secure","path","type","query","format","baseUrl","params","__objRest","secureParams","baseApiParams","securityWorker","requestParams","mergeRequestParams","queryString","payloadFormatter","contentFormatters","responseFormat","customFetch","__spreadProps","__spreadValues","createAbortSignal","then","response","r","clone","error","ok","catch","e","assign","encodeQueryParam","value","encodeURIComponent","addQueryParam","addArrayQueryParam","map","v","join","rawQuery","filter","Array","isArray","addQueryParams","params1","params2","super","arguments","loginByEmail","request","method","registerByEmail","sendVerifyEmail","checkDataMerge","applyDataMerge","flushCache","warmUpCache","getCaptcha","getCaptchaStatus","verifyCaptcha","getComments","createComment","comment","getComment","id","updateComment","deleteComment","conf","getSocialLoginProviders","getDomain","getNotifies","markAllNotifyRead","options","markNotifyRead","commentId","notifyKey","getPages","fetchAllPages","getPageFetchStatus","logPv","page","updatePage","deletePage","fetchPage","sendEmail","email","getSettings","applySettings","settings","getSettingsTemplate","locale","getSites","createSite","site","updateSite","deleteSite","getStats","exportArtrans","importArtrans","uploadArtrans","upload","getUser","updateProfile","login","user","getUserStatus","createUser","updateUser","deleteUser","getUsers","getVersion","syncVotes","vote","targetId","Fetch","opts","init","exports","apiToken","getApiToken","Headers","Authorization","resp","json","retry","handlers","promise","item","action","handler","Promise","resolve","code","err","FetchException","message","msg","console","createError","status","Error","Api","ApiV2","baseURL","_opts","getUserFields","userInfo","name","escapes","unescapes","rescaped","runescaped","escapeHtmlChar","match","unescapeHtmlChar","escapeHtml","text","String","replace","unescapeHtml","html","she","encode","escape","decode","unescape","version","assignment_1","assignment","result","stack","prototype","slice","call","length","shift","hasOwnProperty","toString","lowercase","string","toLowerCase","asKey","accumulator","toMap_1","list","attributes","uris","require$$0","elements","voids","he","require$$1","require$$3","rstart","rend","rattrs","rtag","rtagend","require$$2","parser","chars","lastItem","createStack","last","parsePart","substr","index","indexOf","substring","test","parseEdge","parseEndTag","parseStartTag","same","regex","tag","tagName","rest","unary","attrs","low","u","doubleQuotedValue","singleQuotedValue","unquotedValue","push","start","i","pos","end","sanitizer","buffer","context","o","ignoring","ignore","allowedTags","out","forEach","classesOk","allowedClasses","attrsOk","allowedAttributes","lkey","split","className","trim","colon","questionmark","hash","allowedSchemes","some","matches","scheme","testUrl","unignore","transformText","depth","reset","defaults","a","iframe","img","insane","strict","configuration","insaneOptions","span","node","reg","class","style","sanitize","content","createCommonjsModule","fn","module","index$1","RegExp","line","source","block","defaultColors","toComment","cm","ref","colors","cache","re","m","word","color","factory","renderCode","hanabi","getRenderer","renderer","marked","Renderer","link","markedLinkRenderer","markedCodeRenderer","image","markedImageRenderer","orgLinkRenderer","args","isSameOriginLink","URL","origin","getLinkOrigin","href","window","location","lang","realLang","colorized","hljs","getLanguage","highlight","orgImageRenderer","imgLazyLoad","instance","replacers","markedOptions","gfm","breaks","async","getInstance","src","markedContent","parse","_","alt","imgSrc","simpleMarked","dest","replacer","mergeDeep","objects","isObject","obj","prev","pVal","oVal","concat","DataManager","events","getLoading","loading","setLoading","val","getListLastFetch","listLastFetch","setListLastFetch","comments","fetchComments","trigger","findComment","find","c","clearComments","loadComments","partialComments","insertComment","notifies","updateNotifies","getPage","pageData","createElement","htmlStr","div","document","innerHTML","firstElementChild","htmlEncode","str","temp","innerText","getQueryParam","exec","search","decodeURIComponent","getOffset","el","relativeTo","getOffsetRecursive","element","rect","getBoundingClientRect","scrollLeft","pageXOffset","documentElement","scrollTop","pageYOffset","top","left","elOffset","relativeToOffset","padWithZeros","vNumber","width","numAsString","timeAgo","date","$t","n","oldTime","getTime","diffValue","Date","days","Math","floor","leave1","hours","leave2","minutes","leave3","seconds","round","vDay","getDate","vMonth","getMonth","getFullYear","dateFormat","getCorrectUserAgent","uaRaw","navigator","userAgent","userAgentData","getHighEntropyValues","uaData","uaGot","majorPlatformVersion","Number","platformVersion","platform","isValidURL","urlRaw","url","protocol","getURLBasedOnApi","base","en","placeholder","noComment","send","signIn","signUp","save","nick","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","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","frontend","backend","loadFail","editing","editFail","deleting","deleteFail","reqGot","reqAborted","updateMsg","currentVersion","open","openName","GLOBAL_LOCALES_KEY","internal","findLocaleSet","p1","p2","toUpperCase","LocaleConf","LocaleDict","setLocale","t","token","Utils.htmlEncode","EventManager","on","off","evt","payload","once","pageKey","pageTitle","server","sendBtn","darkMode","editorTravel","flatMode","nestMax","nestSort","emoticons","uaBadge","listSort","countEl","pvEl","statPageKeyAttr","gravatar","mirror","pagination","pageSize","autoLoad","heightLimit","children","scrollable","imgUpload","reqTimeout","versionCheck","useBackendConf","handelCustomConf","customConf","full","Defaults","findEl","querySelector","pathname","title","language","matchMedia","convertApiOptions","ctx","siteName","timeout","getData","checkHasBasicUserInfo","getApiHandlers","watchConf","effect","lastVal","newVal","getConf","res","b","Context","getCommentNodes","$root","classList","add","mounted","inject","depName","getApi","apiHandlers","h","remove","findIndex","splice","createApiHandlers","checkCaptcha","checkAdmin","createNewApiHandlers","replyComment","commentData","$comment","editor","setReply","editComment","setEditComment","reload","offset","listGotoFirst","editorShowLoading","showLoading","editorHideLoading","hideLoading","editorShowNotify","showNotify","editorResetState","resetState","showSidebar","sidebarLayer","show","hideSidebar","hide","checkerLauncher","I18n.t","setDarkMode","updateConf","nConf","getEl","getMarked","marked.getInstance","parentElem","$loading","Utils.createElement","transparentBg","background","appendChild","display","$spinner","setTimeout","isConnected","scrollIntoView","elem","enableAnim","containerRect","clientHeight","scrollY","innerHeight","height","scrollOptions","behavior","scroll","playFadeInAnim","after","onAnimEnded","removeEventListener","addEventListener","playFadeAnim","setError","errorTextEl","HTMLElement","iframeBody","checker","$iframeWrap","$iframe","Ui.showLoading","getOpts","getCaptchaIframeURL","onload","Ui.hideLoading","$closeBtn","hideInteractInput","stop","queryStatus","ms","isPass","captcha","is_pass","triggerSuccess","onclick","CaptchaChecker","inputVal","render.iframeBody","imgEl","setAttribute","img_data","render.imgBody","onSuccess","formEl","onError","click","AdminChecker","inputType","update","is_admin","onReload","Dialog","contentEl","$el","$actions","$content","setYes","btn","onBtnClick","setNo","currentTarget","wrapPromise","reject","cancelFn","onCancel","successFn","CheckerLauncher","p","fire","postFire","layer","getCtx","create","close","destroy","checkerStore","checkerCtx","$input","btnTextOrg","focus","onkeyup","keyCode","preventDefault","dialog","btnEl","btnTextRestore","btnText","tf","onfocus","clearTimeout","onMount","Component","Sel","$header","$name","$email","$link","$textareaWrap","$textarea","$bottom","$submitBtn","$notifyWrap","$bottomLeft","$stateWrap","$plugBtnWrap","$plugPanelWrap","EditorPlug","kit","useBtn","$btn","usePanel","$panel","useContentTransformer","func","contentTransformer","usePanelShow","useEvents","aPlug","usePanelHide","useEditorStateEffect","stateName","effectFn","editorStateEffectWhen","editorStateEffect","Mover","move","afterEl","isMoved","editorEl","useUI","$travelPlace","replaceWith","back","useGlobalCtx","EditorStateManager","stateCurt","state","stateUnmountFn","getPlugs","moveAfterEl","_d","_c","$relative","scrollRelativeTo","Ui.scrollIntoView","getUI","plugin","_e","Editor","ui","entries","k","sel","render","getState","getHeaderInputEls","getContentFinal","getContentRaw","plugs","getTransformedContent","getContentMarked","setContent","getEvents","insertContent","selection","createRange","selectionStart","sStart","sEnd","selectionEnd","sT","switch","wrapElem","notifyElem","s","w","notifyRemove","timeoutFn","Ui.showNotify","submit","next","beforeSubmit","SidebarLayer","refreshWhenShow","transform","initLayer","createIframe","view","iFrameSrc","getDarkMode","includes","iframeLoad","authCheck","animTimer","is_login","setOnAfterHide","Utils.getURLBasedOnApi","time","urlParams","URLSearchParams","createNestStrategy","import","srcData","sortBy","nodeList","rid","root","rootNode","level","parent","loadChildren","parentNode","child","childNode","sortFunc","vote_up","sortLevels","nodes","sort","ListNest.makeNestCommentNodeList","nestSortBy","rootC","createCommentNode","$commentsWrap","getRender","parentC","replyD","childD","childC","putChild","checkHeightLimit","insert","prepend","findCommentNode","getParents","heightLimitRemoveForChildren","insertMode","is_collapsed","is_allow_reply","visible","$listCommentsWrap","ListLayout","getStrategy","check","rules","max","imgCheck","maxHeight","lock","_check","Utils.getHeight","parseFloat","getComputedStyle","opt","contains","HEIGHT_LIMIT_SCROLL_CSS","applyScrollableHeightLimit","HEIGHT_LIMIT_CSS","overflow","$expandBtn","stopPropagation","disposeHeightLimit","afterExpandBtnClick","applyHeightLimit","imgs","querySelectorAll","from","renderNick","$headerNick","$nickA","Utils.isValidURL","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","setUnread","setOpenable","setOpenURL","setOpenAction","CommentActions","actionBtn","votes","up","down","btnElem","modify","setData","onDelete","origHash","modifyHash","dispatchEvent","Event","CommentNode","nestCurt","actionInstance","renderInstance","CommentUI","newEl","onAfterRender","getParent","getNestCurt","getIsRoot","getID","getChildrenWrapEl","$childComment","flattenParents","emailHash","email_encrypted","dateFormatter","Utils.timeAgo","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","ua","ReadMoreBtn","origText","$text","hasMore","total","onClick","checkDisabled","showErr","errMsg","ReadMorePaginator","readMoreAutoLoad","onReachedBottom","getHasMore","getIsClearComments","dispose","Pagination","oninput","onkeydown","keydown","$prevBtn","$nextBtn","maxPage","ceil","setInput","inputTimer","isNaN","change","onChange","which","UpDownPaginator","PaginationComponent","getPageDataByLastData","count","roots_count","initListPaginatorFunc","paginator","createPaginatorByConf","$paginator","List","initCrudEvents","getCommentsWrapEl","commentNodes","getListLayout","forceFlatMode","d","bodyOrgOverflow","bodyOrgPaddingRight","getScrollbarHelper","paddingRight","unlock","barPaddingRight","parseInt","getPropertyValue","inner","outer","position","visibility","w1","offsetWidth","w2","clientWidth","removeChild","Ui.getScrollBarWidth","Layer","onAfterHide","setAllowMaskClose","allow","allowMaskClose","getAllowMaskClose","onShow","onHide","LayerWrap","$wrap","$mask","createItem","createItemElement","hideWrap","showWrap","getMask","items","getWrap","l","LayerManager","wrap","LOCAL_USER_KEY","User","localUser","localStorage","getItem","isAdmin","setItem","onUserChanged","logout","services","i18n","I18n.setLocale","layerManager","editorPlugs","initCountWidget","loadStatCount","containers","loadCommentCount","cacheData","pvAdd","pvCount","pages","page_key","page_title","site_name","pv","incrementPvCount","loadPvCount","els","Set","selector","retrieveElements","pageKeys","pageKeyAttr","getAttribute","getPageKeys","stats","page_keys","defaultPageKey","updateElementsText","LocalStorageKey","SubmitAddPreset","reqAdd","useApi","getSubmitAddParams","useUser","useConf","useEditor","Utils.getCorrectUserAgent","postSubmitAdd","commentNew","Submit","defaultPreset","onEditorSubmit","do","useMounted","useUnmounted","registerCustom","customs","custom","activeCond","nComment","pre","req","post","Emoticons","raw","transEmoticonImageText","loadEmoticonsData","isImgLoaded","initEmoticonsList","changeListHeight","parentElement","isListLoaded","loadingTask","handleData","Ui.setError","pushGrp","grp","remoteLoad","all","grpData","isOwOFormat","convertOwO","solveNullKey","solveSameKey","tmp","values","container","owoData","grpName","nGrp","iconStr","icon","$grpWrap","$grp","$item","$grpSwitcher","openGrp","AllowImgExts","Upload","initDragImg","$imgUploadInput","accept","onchange","files","file","uploadImg","uploadFromFileList","onDragover","onDrop","dataTransfer","onPaste","clipboardData","fileExt","insertPrefix","uploadPlaceholderTxt","customUploaderFn","imgUploader","public_url","imgURL","Preview","isPlugPanelShow","updateContent","EDITOR_PLUGS","onContentUpdated","localContent","$inputs","inputEventFns","changeEventFns","field","timer","abortFn","onInput","fetchUserInfo","placeholders","api","CANCEL_TOKEN","abortRequest","onUserInfoFetched","finally","onLinkChange","onLinkInputChange","onKeydown","adaptiveHeightByContent","diff","offsetHeight","scrollHeight","cancelReply","submitPlug","useDeps","page_url","$sendReplyBtn","cancelEdit","saveData","$editCancelBtn","updateSubmitBtnText","restoreSubmitBtnText","originalSubmitBtnText","onOpen","onClose","PlugKit","plug","PlugManager","confLoaded","clear","confRefs","getEnabledPlugs","Plug","loadPluginUI","closePlugPanel","openedPlug","loadPluginItem","openPlugPanel","plugPanel","rawContent","showErrorDialog","errEl","retryFn","$retryBtn","onOpenSidebar","$openSidebar","$err","IgnoreVersionCheck","darkModeMedia","updateClassnames","$els","DarkModeClassName","DefaultPlugins","Marked","setOptions","initMarked","markedReplacers","scanApply","$sidebarEl","getAdminOnlyEls","_params","limit","paramsModifier","listFetchParamsModifier","reqParams","flat_mode","listUnreadHighlight","notify","comment_id","read_link","commentID","Utils.getQueryParam","$closeCommentBtn","admin_only","adminPageEditSave","$count","$openSidebarBtn","syncByUser","$btnText","$unreadBadge","reloadUseParamsEditor","initDropdown","$dropdownOn","$dropdownWrap","dropdownList","curtActive","onItemClick","$dropdown","renderDropdown","sort_by","view_only_admin","removeDropdown","lastID","locker","extractCommentID","hashChangeHandler","listLoadedHandler","reply_comment","isNoComment","$noComment","$copyright","ARTALK_VERSION","setInterval","clearInterval","errData","observer","clearObserver","disconnect","childNodes","$target","scrollEvtAt","IntersectionObserver","isIntersecting","threshold","observe","setupObserver","warn","Utils.getOffset","apiVersion","feVer","beVer","comp","pa","pb","na","nb","Utils.versionCompare","ignoreBtn","darkModeAutoHandler","sync","GlobalPlugins","PluginOptions","WeakMap","load","loadedPlugins","loadPlugins","plugins","sidebarOpenView","err_no_site","viewLoadParam","create_name","create_urls","host","onLoadErr","frontend_conf","ExcludedKeys","startsWith","handleConfFormServer","remoteConfModifier","pluginURLs","scripts","apiBase","networkPlugins","tasks","script","head","onerror","ArtalkPlugins","loadNetworkPlugins","Artalk","handledConf","Services","initService","firstChild","use","loadCountWidget"],"mappings":"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","x_google_ignoreList":[3,4,5,6,7,8,9,10,11,12,14]}