halo-theme-hao/templates/assets/libs/artalk/Artalk.js

6413 lines
194 KiB
JavaScript
Raw Permalink Normal View History

! function(e, t) {
"object" == typeof exports && "undefined" != typeof module ? t(exports) : "function" == typeof define && define
.amd ? define(["exports"], t) : t((e = "undefined" != typeof globalThis ? globalThis : e || self).Artalk = {})
}(this, (function(e) {
"use strict";
var t, n, i, s, r = Object.defineProperty,
o = Object.defineProperties,
a = Object.getOwnPropertyDescriptors,
l = Object.getOwnPropertySymbols,
c = Object.prototype.hasOwnProperty,
d = Object.prototype.propertyIsEnumerable,
h = (e, t, n) => t in e ? r(e, t, {
enumerable: !0,
configurable: !0,
writable: !0,
value: n
}) : e[t] = n,
u = (e, t) => {
for (var n in t || (t = {})) c.call(t, n) && h(e, n, t[n]);
if (l)
for (var n of l(t)) d.call(t, n) && h(e, n, t[n]);
return e
},
p = (e, t) => o(e, a(t)),
g = (e, t, n) => (h(e, "symbol" != typeof t ? t + "" : t, n), n),
m = (e, t, n) => {
if (t.has(e)) throw TypeError("Cannot add the same private member more than once");
t instanceof WeakSet ? t.add(e) : t.set(e, n)
},
f = (e, t, n) => (((e, t, n) => {
if (!t.has(e)) throw TypeError("Cannot " + n)
})(e, t, "access private method"), n),
k = (e, t, n) => new Promise(((i, s) => {
var r = e => {
try {
a(n.next(e))
} catch (t) {
s(t)
}
},
o = e => {
try {
a(n.throw(e))
} catch (t) {
s(t)
}
},
a = e => e.done ? i(e.value) : Promise.resolve(e.value).then(r, o);
a((n = n.apply(e, t)).next())
}));
function y(e = "") {
const t = document.createElement("div");
return t.innerHTML = e.trim(), t.firstElementChild || t
}
function v(e) {
return parseFloat(getComputedStyle(e, null).height.replace("px", ""))
}
function $(e) {
const t = document.createElement("div");
t.innerText = e;
return t.innerHTML
}
function b(e) {
const t = RegExp(`[?&]${e}=([^&]*)`).exec(window.location.search);
return t && decodeURIComponent(t[1].replace(/\+/g, " "))
}
function w(e, t) {
const n = e => {
const t = e.getBoundingClientRect(),
n = window.pageXOffset || document.documentElement.scrollLeft,
i = window.pageYOffset || document.documentElement.scrollTop;
return {
top: t.top + i,
left: t.left + n
}
},
i = n(e);
if (!t) return i;
const s = n(t);
return {
top: i.top - s.top,
left: i.left - s.left
}
}
function x(e, t) {
let n = e.toString();
for (; n.length < t;) n = `0${n}`;
return n
}
function C(e, t = (e => e)) {
try {
const n = e.getTime(),
i = (new Date).getTime() - n,
s = Math.floor(i / 864e5);
if (0 === s) {
const e = i % 864e5,
n = Math.floor(e / 36e5);
if (0 === n) {
const n = e % 36e5,
i = Math.floor(n / 6e4);
if (0 === i) {
const e = n % 6e4,
i = Math.round(e / 1e3);
return i < 10 ? t("now") : `${i} ${t("seconds")}`
}
return `${i} ${t("minutes")}`
}
return `${n} ${t("hours")}`
}
return s < 0 ? t("now") : s < 8 ? `${s} ${t("days")}` : function(e) {
const t = x(e.getDate(), 2),
n = x(e.getMonth() + 1, 2);
return `${x(e.getFullYear(),2)}-${n}-${t}`
}(e)
} catch (n) {
return console.error(n), " - "
}
}
function S() {
return k(this, null, (function*() {
const e = navigator.userAgent;
if (!navigator.userAgentData || !navigator.userAgentData.getHighEntropyValues) return e;
const t = navigator.userAgentData;
let n = null;
try {
n = yield t.getHighEntropyValues(["platformVersion"])
} catch (s) {
return console.error(s), e
}
const i = Number(n.platformVersion.split(".")[0]);
return "Windows" === t.platform && i >= 13 ? e.replace(/Windows NT 10.0/,
"Windows NT 11.0") : "macOS" === t.platform && i >= 11 ? e.replace(
/(Mac OS X \d+_\d+_\d+|Mac OS X)/,
`Mac OS X ${n.platformVersion.replace(/\./g,"_")}`) : e
}))
}
function E(e) {
let t;
try {
t = new URL(e)
} catch (n) {
return !1
}
return "http:" === t.protocol || "https:" === t.protocol
}
function T(e) {
return t = e.base, n = e.path, `${t.replace(/\/$/,"")}/${n.replace(/^\//,"")}`;
var t, n
}
var _ = "undefined" != typeof globalThis ? globalThis : "undefined" != typeof window ? window :
"undefined" != typeof global ? global : "undefined" != typeof self ? self : {};
function L(e) {
return e && e.__esModule && Object.prototype.hasOwnProperty.call(e, "default") ? e.default : e
}! function() {
function e(e, t) {
if (!(e instanceof t)) throw new TypeError("Cannot call a class as a function")
}
function t(e, t) {
for (var n = 0; n < t.length; n++) {
var i = t[n];
i.enumerable = i.enumerable || !1, i.configurable = !0, "value" in i && (i.writable = !0),
Object.defineProperty(e, i.key, i)
}
}
function n(e, n, i) {
return n && t(e.prototype, n), i && t(e, i), Object.defineProperty(e, "prototype", {
writable: !1
}), e
}
function i(e, t) {
if ("function" != typeof t && null !== t) throw new TypeError(
"Super expression must either be null or a function");
e.prototype = Object.create(t && t.prototype, {
constructor: {
value: e,
writable: !0,
configurable: !0
}
}), Object.defineProperty(e, "prototype", {
writable: !1
}), t && r(e, t)
}
function s(e) {
return (s = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function(e) {
return e.__proto__ || Object.getPrototypeOf(e)
})(e)
}
function r(e, t) {
return (r = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function(e, t) {
return e.__proto__ = t, e
})(e, t)
}
function o() {
if ("undefined" == typeof Reflect || !Reflect.construct) return !1;
if (Reflect.construct.sham) return !1;
if ("function" == typeof Proxy) return !0;
try {
return Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], (function() {}))), !0
} catch (e) {
return !1
}
}
function a(e) {
if (void 0 === e) throw new ReferenceError(
"this hasn't been initialised - super() hasn't been called");
return e
}
function l(e, t) {
if (t && ("object" == typeof t || "function" == typeof t)) return t;
if (void 0 !== t) throw new TypeError("Derived constructors may only return object or undefined");
return a(e)
}
function c(e) {
var t = o();
return function() {
var n, i = s(e);
if (t) {
var r = s(this).constructor;
n = Reflect.construct(i, arguments, r)
} else n = i.apply(this, arguments);
return l(this, n)
}
}
function d(e, t) {
for (; !Object.prototype.hasOwnProperty.call(e, t) && null !== (e = s(e)););
return e
}
function h() {
return h = "undefined" != typeof Reflect && Reflect.get ? Reflect.get.bind() : function(e, t, n) {
var i = d(e, t);
if (i) {
var s = Object.getOwnPropertyDescriptor(i, t);
return s.get ? s.get.call(arguments.length < 3 ? e : n) : s.value
}
}, h.apply(this, arguments)
}
var u = function() {
function t() {
e(this, t), Object.defineProperty(this, "listeners", {
value: {},
writable: !0,
configurable: !0
})
}
return n(t, [{
key: "addEventListener",
value: function(e, t, n) {
e in this.listeners || (this.listeners[e] = []), this.listeners[e]
.push({
callback: t,
options: n
})
}
}, {
key: "removeEventListener",
value: function(e, t) {
if (e in this.listeners)
for (var n = this.listeners[e], i = 0, s = n.length; i < s; i++)
if (n[i].callback === t) return void n.splice(i, 1)
}
}, {
key: "dispatchEvent",
value: function(e) {
if (e.type in this.listeners) {
for (var t = this.listeners[e.type].slice(), n = 0, i = t
.length; n < i; n++) {
var s = t[n];
try {
s.callback.call(this, e)
} catch (r) {
Promise.resolve().then((function() {
throw r
}))
}
s.options && s.options.once && this.removeEventListener(e.type,
s.callback)
}
return !e.defaultPrevented
}
}
}]), t
}(),
p = function(t) {
i(o, t);
var r = c(o);
function o() {
var t;
return e(this, o), (t = r.call(this)).listeners || u.call(a(t)), Object.defineProperty(a(t),
"aborted", {
value: !1,
writable: !0,
configurable: !0
}), Object.defineProperty(a(t), "onabort", {
value: null,
writable: !0,
configurable: !0
}), Object.defineProperty(a(t), "reason", {
value: void 0,
writable: !0,
configurable: !0
}), t
}
return n(o, [{
key: "toString",
value: function() {
return "[object AbortSignal]"
}
}, {
key: "dispatchEvent",
value: function(e) {
"abort" === e.type && (this.aborted = !0, "function" == typeof this
.onabort && this.onabort.call(this, e)), h(s(o.prototype),
"dispatchEvent", this).call(this, e)
}
}]), o
}(u),
g = function() {
function t() {
e(this, t), Object.defineProperty(this, "signal", {
value: new p,
writable: !0,
configurable: !0
})
}
return n(t, [{
key: "abort",
value: function(e) {
var t;
try {
t = new Event("abort")
} catch (i) {
"undefined" != typeof document ? document.createEvent ? (t =
document.createEvent("Event")).initEvent("abort", !1, !1) :
(t = document.createEventObject()).type = "abort" : t = {
type: "abort",
bubbles: !1,
cancelable: !1
}
}
var n = e;
if (void 0 === n)
if ("undefined" == typeof document)(n = new Error(
"This operation was aborted")).name = "AbortError";
else try {
n = new DOMException("signal is aborted without reason")
} catch (s) {
(n = new Error("This operation was aborted")).name =
"AbortError"
}
this.signal.reason = n, this.signal.dispatchEvent(t)
}
}, {
key: "toString",
value: function() {
return "[object AbortController]"
}
}]), t
}();
function m(e) {
return e.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL ? (console.log(
"__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL=true is set, will force install polyfill"), !
0) : "function" == typeof e.Request && !e.Request.prototype.hasOwnProperty("signal") || !e
.AbortController
}
function f(e) {
"function" == typeof e && (e = {
fetch: e
});
var t = e,
n = t.fetch,
i = t.Request,
s = void 0 === i ? n.Request : i,
r = t.AbortController,
o = t.__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL,
a = void 0 !== o && o;
if (!m({
fetch: n,
Request: s,
AbortController: r,
__FORCE_INSTALL_ABORTCONTROLLER_POLYFILL: a
})) return {
fetch: n,
Request: l
};
var l = s;
(l && !l.prototype.hasOwnProperty("signal") || a) && ((l = function(e, t) {
var n;
t && t.signal && (n = t.signal, delete t.signal);
var i = new s(e, t);
return n && Object.defineProperty(i, "signal", {
writable: !1,
enumerable: !1,
configurable: !0,
value: n
}), i
}).prototype = s.prototype);
var c = n;
return {
fetch: function(e, t) {
var n = l && l.prototype.isPrototypeOf(e) ? e.signal : t ? t.signal : void 0;
if (n) {
var i;
try {
i = new DOMException("Aborted", "AbortError")
} catch (r) {
(i = new Error("Aborted")).name = "AbortError"
}
if (n.aborted) return Promise.reject(i);
var s = new Promise((function(e, t) {
n.addEventListener("abort", (function() {
return t(i)
}), {
once: !0
})
}));
return t && t.signal && delete t.signal, Promise.race([s, c(e, t)])
}
return c(e, t)
},
Request: l
}
}
"undefined" != typeof Symbol && Symbol.toStringTag && (g.prototype[Symbol.toStringTag] =
"AbortController", p.prototype[Symbol.toStringTag] = "AbortSignal"),
function(e) {
if (m(e))
if (e.fetch) {
var t = f(e),
n = t.fetch,
i = t.Request;
e.fetch = n, e.Request = i, Object.defineProperty(e, "AbortController", {
writable: !0,
enumerable: !1,
configurable: !0,
value: g
}), Object.defineProperty(e, "AbortSignal", {
writable: !0,
enumerable: !1,
configurable: !0,
value: p
})
} else console.warn("fetch() is not available, cannot install abortcontroller-polyfill")
}("undefined" != typeof self ? self : _)
}();
const A = {
placeholder: "Leave a comment",
noComment: "No Comment",
send: "Send",
save: "Save",
nick: "Nickname",
email: "Email",
link: "Website",
emoticon: "Emoji",
preview: "Preview",
image: "Image",
uploadFail: "Upload Failed",
commentFail: "Failed to comment",
restoredMsg: "Content has been restored",
onlyAdminCanReply: "Only admin can reply",
uploadLoginMsg: "Please fill in your name and email to upload",
counter: "{count} Comments",
sortLatest: "Latest",
sortOldest: "Oldest",
sortBest: "Best",
sortAuthor: "Author",
openComment: "Open Comment",
closeComment: "Close Comment",
listLoadFailMsg: "Failed to load comments",
listRetry: "Click to retry",
loadMore: "Load More",
admin: "Admin",
reply: "Reply",
voteUp: "Up",
voteDown: "Down",
voteFail: "Vote Failed",
readMore: "Read More",
actionConfirm: "Confirm",
collapse: "Collapse",
collapsed: "Collapsed",
collapsedMsg: "This comment has been collapsed",
expand: "Expand",
approved: "Approved",
pending: "Pending",
pendingMsg: "Pending, visible only to commenter.",
edit: "Edit",
editCancel: "Cancel Edit",
delete: "Delete",
deleteConfirm: "Confirm",
pin: "Pin",
unpin: "Unpin",
seconds: "seconds ago",
minutes: "minutes ago",
hours: "hours ago",
days: "days ago",
now: "just now",
adminCheck: "Enter admin password:",
captchaCheck: "Enter the CAPTCHA to continue:",
confirm: "Confirm",
cancel: "Cancel",
msgCenter: "Messages",
ctrlCenter: "Admin",
frontend: "Frontend",
backend: "Backend",
loading: "Loading",
loadFail: "Load Failed",
editing: "Editing",
editFail: "Edit Failed",
deleting: "Deleting",
deleteFail: "Delete Failed",
reqGot: "Request got",
reqAborted: "Request timed out or terminated unexpectedly",
updateMsg: "Please update Artalk {name} to get the full experience",
currentVersion: "Current Version",
ignore: "Ignore",
open: "Open"
},
O = "ArtalkI18n",
P = {
en: A,
"en-US": A,
"zh-CN": {
placeholder: "键入内容...",
noComment: "「此时无声胜有声」",
send: "发送评论",
save: "保存评论",
nick: "昵称",
email: "邮箱",
link: "网址",
emoticon: "表情",
preview: "预览",
image: "图片",
uploadFail: "上传失败",
commentFail: "评论失败",
restoredMsg: "内容已自动恢复",
onlyAdminCanReply: "仅管理员可评论",
uploadLoginMsg: "填入你的名字邮箱才能上传哦",
counter: "{count} 条评论",
sortLatest: "最新",
sortOldest: "最早",
sortBest: "最热",
sortAuthor: "作者",
openComment: "打开评论",
closeComment: "关闭评论",
listLoadFailMsg: "无法获取评论列表数据",
listRetry: "点击重新获取",
loadMore: "加载更多",
admin: "管理员",
reply: "回复",
voteUp: "赞同",
voteDown: "反对",
voteFail: "投票失败",
readMore: "阅读更多",
actionConfirm: "确认操作",
collapse: "折叠",
collapsed: "已折叠",
collapsedMsg: "该评论已被系统或管理员折叠",
expand: "展开",
approved: "已审",
pending: "待审",
pendingMsg: "审核中,仅本人可见。",
edit: "编辑",
editCancel: "取消编辑",
delete: "删除",
deleteConfirm: "确认删除",
pin: "置顶",
unpin: "取消置顶",
seconds: "秒前",
minutes: "分钟前",
hours: "小时前",
days: "天前",
now: "刚刚",
adminCheck: "键入密码来验证管理员身份:",
captchaCheck: "键入验证码继续:",
confirm: "确认",
cancel: "取消",
msgCenter: "通知中心",
ctrlCenter: "控制中心",
frontend: "前端",
backend: "后端",
loading: "加载中",
loadFail: "加载失败",
editing: "修改中",
editFail: "修改失败",
deleting: "删除中",
deleteFail: "删除失败",
reqGot: "请求响应",
reqAborted: "请求超时或意外终止",
updateMsg: "请更新 Artalk {name} 以获得完整体验",
currentVersion: "当前版本",
ignore: "忽略",
open: "打开"
}
};
function R(e) {
return e = e.replace(/^([a-zA-Z]+)(-[a-zA-Z]+)?$/, ((e, t, n) => t.toLowerCase() + (n || "")
.toUpperCase())), P[e] ? P[e] : window[O] && window[O][e] ? window[O][e] : P.en
}
let M = "en",
I = R(M);
function U(e) {
e !== M && (M = e, I = "string" == typeof e ? R(e) : e)
}
function D(e, t = {}) {
let n = (null == I ? void 0 : I[e]) || e;
return n = n.replace(/\{\s*(\w+?)\s*\}/g, ((e, n) => t[n] || "")), n
}
function B(e, t, n, i) {
return k(this, null, (function*() {
var s, r;
if (e.apiToken) {
const t = new Headers(n.headers);
t.set("Authorization", `Bearer ${e.apiToken}`), n.headers = t
}
const o = yield function(e, t, n) {
var i;
const s = new AbortController;
null == (i = n.signal) || i.addEventListener("abort", (() => s.abort()));
let r = fetch(e, p(u({}, n), {
signal: s.signal
}));
if (t > 0) {
const e = setTimeout((() => s.abort()), t);
r.finally((() => {
clearTimeout(e)
}))
}
return r = r.catch((e => {
throw "AbortError" === (e || {}).name ? new Error(D(
"reqAborted")) : e
})), r
}(t, i || e.timeout || 15e3, n), a = o.status, l = [401, 400].includes(a);
if (!o.ok && !l) throw new Error(`${D("reqGot")} ${a}`);
let c = yield o.json();
const d = (i, s) => {
B(e, t, n).then((e => {
i(e)
})).catch((e => {
s(e)
}))
};
if ((null == (s = c.data) ? void 0 : s.need_captcha) ? c = yield new Promise(((t,
n) => {
e.onNeedCheckCaptcha && e.onNeedCheckCaptcha({
data: {
imgData: c.data.img_data,
iframe: c.data.iframe
},
recall: () => {
d(t, n)
},
reject: () => {
n(c)
}
})
})): ((null == (r = c.data) ? void 0 : r.need_login) || l) && (c =
yield new Promise(((t, n) => {
e.onNeedCheckAdmin && e.onNeedCheckAdmin({
recall: () => {
d(t, n)
},
reject: () => {
n(c)
}
})
}))), !c.success) throw c;
return c
}))
}
function q(e) {
const t = new FormData;
return Object.keys(e).forEach((n => t.append(n, String(e[n])))), t
}
class F {
constructor(e) {
this.options = e
}
POST(e, t) {
return k(this, null, (function*() {
return function(e, t, n) {
return k(this, null, (function*() {
const i = {
method: "POST"
};
return n = u({
site_name: e.siteName || ""
}, n || {}), i.body = q(n), (yield B(e, t, i))
.data || {}
}))
}(this.options, this.options.baseURL + e, t)
}))
}
Fetch(e, t, n) {
return k(this, null, (function*() {
return B(this.options, this.options.baseURL + e, t, n)
}))
}
withUserInfo(e) {
const t = this.options.userInfo;
return (null == t ? void 0 : t.name) && (e.name = t.name), (null == t ? void 0 : t.email) && (e
.email = t.email), e
}
}
const z = {
comment: class extends F {
get(e, t, n, i) {
const s = {
page_key: this.options.pageKey,
site_name: this.options.siteName,
limit: t,
offset: e
};
return n && (s.flat_mode = n), this.withUserInfo(s), i && i(s), this.POST("/get", s)
}
add(e) {
return k(this, null, (function*() {
const t = {
name: e.nick,
email: e.email,
link: e.link,
content: e.content,
rid: e.rid,
page_key: e.page_key,
ua: yield S()
};
e.page_title && (t.page_title = e.page_title), e.site_name && (t
.site_name = e.site_name);
return (yield this.POST("/add", t)).comment
}))
}
commentEdit(e) {
return k(this, null, (function*() {
const t = u({}, e);
return (yield this.POST("/admin/comment-edit", t)).comment
}))
}
commentDel(e, t) {
const n = {
id: String(e),
site_name: t || ""
};
return this.POST("/admin/comment-del", n)
}
vote(e, t) {
return k(this, null, (function*() {
const n = {
target_id: e,
type: t
};
this.withUserInfo(n);
return yield this.POST("/vote", n)
}))
}
},
page: class extends F {
pageGet(e, t, n) {
return k(this, null, (function*() {
const i = {
site_name: e || "",
offset: t || 0,
limit: n || 15
};
return yield this.POST("/admin/page-get", i)
}))
}
pageEdit(e) {
return k(this, null, (function*() {
const t = {
id: e.id,
key: e.key,
title: e.title,
admin_only: e.admin_only,
site_name: e.site_name || this.options.siteName
};
return (yield this.POST("/admin/page-edit", t)).page
}))
}
pageDel(e, t) {
const n = {
key: String(e),
site_name: t || ""
};
return this.POST("/admin/page-del", n)
}
pageFetch(e, t, n) {
return k(this, null, (function*() {
const i = {};
e && (i.id = e), t && (i.site_name = t), n && (i.get_status = n);
return yield this.POST("/admin/page-fetch", i)
}))
}
pv() {
return k(this, null, (function*() {
const e = {
page_key: this.options.pageKey || "",
page_title: this.options.pageTitle || ""
};
return (yield this.POST("/pv", e)).pv
}))
}
stat(e, t, n) {
return k(this, null, (function*() {
const i = {
type: e
};
t && (i.page_keys = Array.isArray(t) ? t.join(",") : t), n && (i
.limit = n);
return yield this.POST("/stat", i)
}))
}
},
site: class extends F {
siteGet() {
return k(this, null, (function*() {
return (yield this.POST("/admin/site-get", {})).sites
}))
}
siteAdd(e, t) {
return k(this, null, (function*() {
const n = {
name: e,
urls: t,
site_name: ""
};
return (yield this.POST("/admin/site-add", n)).site
}))
}
siteEdit(e) {
return k(this, null, (function*() {
const t = {
id: e.id,
name: e.name || "",
urls: e.urls || ""
};
return (yield this.POST("/admin/site-edit", t)).site
}))
}
siteDel(e, t = !1) {
const n = {
id: e,
del_content: t
};
return this.POST("/admin/site-del", n)
}
export () {
return k(this, null, (function*() {
var e;
return (null == (e = (yield this.Fetch("/admin/export", {
method: "POST"
}, 0)).data) ? void 0 : e.data) || ""
}))
}
},
user: class extends F {
login(e, t, n) {
return k(this, null, (function*() {
const i = {
name: e,
email: t,
password: n
};
return yield this.POST("/login", i)
}))
}
userGet(e, t) {
const n = new AbortController,
i = {
name: e,
email: t
};
return {
req: this.Fetch("/user-get", {
method: "POST",
body: q(i),
signal: n.signal
}).then((e => ({
user: e.data.user,
is_login: e.data.is_login,
unread: e.data.unread || [],
unread_count: e.data.unread_count || 0
}))),
abort: () => {
n.abort()
}
}
}
loginStatus() {
return k(this, null, (function*() {
return (yield this.POST("/login-status", this.withUserInfo({}))) ||
{
is_login: !1,
is_admin: !1
}
}))
}
logout() {
return k(this, null, (function*() {
return this.POST("/logout")
}))
}
markRead(e, t, n = !1) {
const i = {
comment_id: e,
notify_key: t
};
return n && (delete i.comment_id, delete i.notify_key, i.read_all = !0, this
.withUserInfo(i)), this.POST("/mark-read", i)
}
userList(e, t, n) {
return k(this, null, (function*() {
const i = {
offset: e || 0,
limit: t || 15
};
n && (i.type = n);
return yield this.POST("/admin/user-get", i)
}))
}
userAdd(e, t) {
return k(this, null, (function*() {
const n = {
name: e.name || "",
email: e.email || "",
password: t || "",
link: e.link || "",
is_admin: e.is_admin || !1,
site_names: e.site_names_raw || "",
receive_email: e.receive_email || !0,
badge_name: e.badge_name || "",
badge_color: e.badge_color || ""
};
return (yield this.POST("/admin/user-add", n)).user
}))
}
userEdit(e, t) {
return k(this, null, (function*() {
const n = {
id: e.id,
name: e.name || "",
email: e.email || "",
password: t || "",
link: e.link || "",
is_admin: e.is_admin || !1,
site_names: e.site_names_raw || "",
receive_email: e.receive_email || !0,
badge_name: e.badge_name || "",
badge_color: e.badge_color || ""
};
return (yield this.POST("/admin/user-edit", n)).user
}))
}
userDel(e) {
return this.POST("/admin/user-del", {
id: String(e)
})
}
},
system: class extends F {
conf() {
return k(this, null, (function*() {
const e = yield this.POST("/conf");
return {
frontend_conf: e.frontend_conf,
version: e.version
}
}))
}
getSettings() {
return k(this, null, (function*() {
return yield this.POST("/admin/setting-get")
}))
}
saveSettings(e) {
return k(this, null, (function*() {
return yield this.POST("/admin/setting-save", {
data: e
})
}))
}
version() {
return k(this, null, (function*() {
const e = yield fetch(`${this.options.baseURL}/version`, {
method: "POST"
});
return yield e.json()
}))
}
},
captcha: class extends F {
captchaGet() {
return k(this, null, (function*() {
return (yield this.POST("/captcha/refresh")).img_data || ""
}))
}
captchaCheck(e) {
return k(this, null, (function*() {
return (yield this.POST("/captcha/check", {
value: e
})).img_data || ""
}))
}
captchaStatus() {
return k(this, null, (function*() {
return (yield this.POST("/captcha/status")) || {
is_pass: !1
}
}))
}
},
admin: class extends F {
cacheFlushAll() {
return this.POST("/admin/cache-flush", {
flush_all: !0
})
}
cacheWarmUp() {
return this.POST("/admin/cache-warm", {})
}
},
upload: class extends F {
imgUpload(e) {
return k(this, null, (function*() {
const t = {
page_key: this.options.pageKey
};
this.withUserInfo(t);
const n = q(t);
n.set("file", e);
const i = {
method: "POST",
body: n
};
return (yield this.Fetch("/img-upload", i)).data || {}
}))
}
}
};
class W {
constructor(e) {
Object.entries(z).forEach((([t, n]) => {
this[t] = new n(e)
}))
}
}
function j() {
return {
async: !1,
baseUrl: null,
breaks: !1,
extensions: null,
gfm: !0,
headerIds: !1,
headerPrefix: "",
highlight: null,
hooks: null,
langPrefix: "language-",
mangle: !1,
pedantic: !1,
renderer: null,
sanitize: !1,
sanitizer: null,
silent: !1,
smartypants: !1,
tokenizer: null,
walkTokens: null,
xhtml: !1
}
}
let N = {
async: !1,
baseUrl: null,
breaks: !1,
extensions: null,
gfm: !0,
headerIds: !1,
headerPrefix: "",
highlight: null,
hooks: null,
langPrefix: "language-",
mangle: !1,
pedantic: !1,
renderer: null,
sanitize: !1,
sanitizer: null,
silent: !1,
smartypants: !1,
tokenizer: null,
walkTokens: null,
xhtml: !1
};
function H(e) {
N = e
}
const Q = /[&<>"']/,
V = new RegExp(Q.source, "g"),
G = /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/,
K = new RegExp(G.source, "g"),
Z = {
"&": "&amp;",
"<": "&lt;",
">": "&gt;",
'"': "&quot;",
"'": "&#39;"
},
Y = e => Z[e];
function X(e, t) {
if (t) {
if (Q.test(e)) return e.replace(V, Y)
} else if (G.test(e)) return e.replace(K, Y);
return e
}
const J = /&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/gi;
function ee(e) {
return e.replace(J, ((e, t) => "colon" === (t = t.toLowerCase()) ? ":" : "#" === t.charAt(0) ? "x" === t
.charAt(1) ? String.fromCharCode(parseInt(t.substring(2), 16)) : String.fromCharCode(+t
.substring(1)) : ""))
}
const te = /(^|[^\[])\^/g;
function ne(e, t) {
e = "string" == typeof e ? e : e.source, t = t || "";
const n = {
replace: (t, i) => (i = (i = "object" == typeof i && "source" in i ? i.source : i).replace(te,
"$1"), e = e.replace(t, i), n),
getRegex: () => new RegExp(e, t)
};
return n
}
const ie = /[^\w:]/g,
se = /^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;
function re(e, t, n) {
if (e) {
let e;
try {
e = decodeURIComponent(ee(n)).replace(ie, "").toLowerCase()
} catch (i) {
return null
}
if (0 === e.indexOf("javascript:") || 0 === e.indexOf("vbscript:") || 0 === e.indexOf("data:"))
return null
}
t && !se.test(n) && (n = function(e, t) {
oe[" " + e] || (ae.test(e) ? oe[" " + e] = e + "/" : oe[" " + e] = ue(e, "/", !0));
e = oe[" " + e];
const n = -1 === e.indexOf(":");
return "//" === t.substring(0, 2) ? n ? t : e.replace(le, "$1") + t : "/" === t.charAt(0) ?
n ? t : e.replace(ce, "$1") + t : e + t
}(t, n));
try {
n = encodeURI(n).replace(/%25/g, "%")
} catch (i) {
return null
}
return n
}
const oe = {},
ae = /^[^:]+:\/*[^/]*$/,
le = /^([^:]+:)[\s\S]*$/,
ce = /^([^:]+:\/*[^/]*)[\s\S]*$/;
const de = {
exec: () => null
};
function he(e, t) {
const n = e.replace(/\|/g, ((e, t, n) => {
let i = !1,
s = t;
for (; --s >= 0 && "\\" === n[s];) i = !i;
return i ? "|" : " |"
})).split(/ \|/);
let i = 0;
if (n[0].trim() || n.shift(), n.length > 0 && !n[n.length - 1].trim() && n.pop(), t)
if (n.length > t) n.splice(t);
else
for (; n.length < t;) n.push("");
for (; i < n.length; i++) n[i] = n[i].trim().replace(/\\\|/g, "|");
return n
}
function ue(e, t, n) {
const i = e.length;
if (0 === i) return "";
let s = 0;
for (; s < i;) {
const r = e.charAt(i - s - 1);
if (r !== t || n) {
if (r === t || !n) break;
s++
} else s++
}
return e.slice(0, i - s)
}
function pe(e, t, n, i) {
const s = t.href,
r = t.title ? X(t.title) : null,
o = e[1].replace(/\\([\[\]])/g, "$1");
if ("!" !== e[0].charAt(0)) {
i.state.inLink = !0;
const e = {
type: "link",
raw: n,
href: s,
title: r,
text: o,
tokens: i.inlineTokens(o)
};
return i.state.inLink = !1, e
}
return {
type: "image",
raw: n,
href: s,
title: r,
text: X(o)
}
}
class ge {
constructor(e) {
g(this, "options"), g(this, "rules"), g(this, "lexer"), this.options = e || N
}
space(e) {
const t = this.rules.block.newline.exec(e);
if (t && t[0].length > 0) return {
type: "space",
raw: t[0]
}
}
code(e) {
const t = this.rules.block.code.exec(e);
if (t) {
const e = t[0].replace(/^ {1,4}/gm, "");
return {
type: "code",
raw: t[0],
codeBlockStyle: "indented",
text: this.options.pedantic ? e : ue(e, "\n")
}
}
}
fences(e) {
const t = this.rules.block.fences.exec(e);
if (t) {
const e = t[0],
n = function(e, t) {
const n = e.match(/^(\s+)(?:```)/);
if (null === n) return t;
const i = n[1];
return t.split("\n").map((e => {
const t = e.match(/^\s+/);
if (null === t) return e;
const [n] = t;
return n.length >= i.length ? e.slice(i.length) : e
})).join("\n")
}(e, t[3] || "");
return {
type: "code",
raw: e,
lang: t[2] ? t[2].trim().replace(this.rules.inline._escapes, "$1") : t[2],
text: n
}
}
}
heading(e) {
const t = this.rules.block.heading.exec(e);
if (t) {
let e = t[2].trim();
if (/#$/.test(e)) {
const t = ue(e, "#");
this.options.pedantic ? e = t.trim() : t && !/ $/.test(t) || (e = t.trim())
}
return {
type: "heading",
raw: t[0],
depth: t[1].length,
text: e,
tokens: this.lexer.inline(e)
}
}
}
hr(e) {
const t = this.rules.block.hr.exec(e);
if (t) return {
type: "hr",
raw: t[0]
}
}
blockquote(e) {
const t = this.rules.block.blockquote.exec(e);
if (t) {
const e = t[0].replace(/^ *>[ \t]?/gm, ""),
n = this.lexer.state.top;
this.lexer.state.top = !0;
const i = this.lexer.blockTokens(e);
return this.lexer.state.top = n, {
type: "blockquote",
raw: t[0],
tokens: i,
text: e
}
}
}
list(e) {
let t = this.rules.block.list.exec(e);
if (t) {
let n = t[1].trim();
const i = n.length > 1,
s = {
type: "list",
raw: "",
ordered: i,
start: i ? +n.slice(0, -1) : "",
loose: !1,
items: []
};
n = i ? `\\d{1,9}\\${n.slice(-1)}` : `\\${n}`, this.options.pedantic && (n = i ? n :
"[*+-]");
const r = new RegExp(`^( {0,3}${n})((?:[\t ][^\\n]*)?(?:\\n|$))`);
let o = "",
a = "",
l = !1;
for (; e;) {
let n = !1;
if (!(t = r.exec(e))) break;
if (this.rules.block.hr.test(e)) break;
o = t[0], e = e.substring(o.length);
let i = t[2].split("\n", 1)[0].replace(/^\t+/, (e => " ".repeat(3 * e.length))),
c = e.split("\n", 1)[0],
d = 0;
this.options.pedantic ? (d = 2, a = i.trimLeft()) : (d = t[2].search(/[^ ]/), d = d >
4 ? 1 : d, a = i.slice(d), d += t[1].length);
let h = !1;
if (!i && /^ *$/.test(c) && (o += c + "\n", e = e.substring(c.length + 1), n = !0), !
n) {
const t = new RegExp(
`^ {0,${Math.min(3,d-1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ \t][^\\n]*)?(?:\\n|$))`
),
n = new RegExp(
`^ {0,${Math.min(3,d-1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`
),
s = new RegExp(`^ {0,${Math.min(3,d-1)}}(?:\`\`\`|~~~)`),
r = new RegExp(`^ {0,${Math.min(3,d-1)}}#`);
for (; e;) {
const l = e.split("\n", 1)[0];
if (c = l, this.options.pedantic && (c = c.replace(/^ {1,4}(?=( {4})*[^ ])/g,
" ")), s.test(c)) break;
if (r.test(c)) break;
if (t.test(c)) break;
if (n.test(e)) break;
if (c.search(/[^ ]/) >= d || !c.trim()) a += "\n" + c.slice(d);
else {
if (h) break;
if (i.search(/[^ ]/) >= 4) break;
if (s.test(i)) break;
if (r.test(i)) break;
if (n.test(i)) break;
a += "\n" + c
}
h || c.trim() || (h = !0), o += l + "\n", e = e.substring(l.length + 1), i = c
.slice(d)
}
}
s.loose || (l ? s.loose = !0 : /\n *\n *$/.test(o) && (l = !0));
let u, p = null;
this.options.gfm && (p = /^\[[ xX]\] /.exec(a), p && (u = "[ ] " !== p[0], a = a
.replace(/^\[[ xX]\] +/, ""))), s.items.push({
type: "list_item",
raw: o,
task: !!p,
checked: u,
loose: !1,
text: a,
tokens: []
}), s.raw += o
}
s.items[s.items.length - 1].raw = o.trimRight(), s.items[s.items.length - 1].text = a
.trimRight(), s.raw = s.raw.trimRight();
for (let e = 0; e < s.items.length; e++)
if (this.lexer.state.top = !1, s.items[e].tokens = this.lexer.blockTokens(s.items[e]
.text, []), !s.loose) {
const t = s.items[e].tokens.filter((e => "space" === e.type)),
n = t.length > 0 && t.some((e => /\n.*\n/.test(e.raw)));
s.loose = n
} if (s.loose)
for (let e = 0; e < s.items.length; e++) s.items[e].loose = !0;
return s
}
}
html(e) {
const t = this.rules.block.html.exec(e);
if (t) {
const e = {
type: "html",
block: !0,
raw: t[0],
pre: !this.options.sanitizer && ("pre" === t[1] || "script" === t[1] || "style" ===
t[1]),
text: t[0]
};
if (this.options.sanitize) {
const n = this.options.sanitizer ? this.options.sanitizer(t[0]) : X(t[0]),
i = e;
i.type = "paragraph", i.text = n, i.tokens = this.lexer.inline(n)
}
return e
}
}
def(e) {
const t = this.rules.block.def.exec(e);
if (t) {
const e = t[1].toLowerCase().replace(/\s+/g, " "),
n = t[2] ? t[2].replace(/^<(.*)>$/, "$1").replace(this.rules.inline._escapes, "$1") :
"",
i = t[3] ? t[3].substring(1, t[3].length - 1).replace(this.rules.inline._escapes,
"$1") : t[3];
return {
type: "def",
tag: e,
raw: t[0],
href: n,
title: i
}
}
}
table(e) {
const t = this.rules.block.table.exec(e);
if (t) {
const e = {
type: "table",
raw: t[0],
header: he(t[1]).map((e => ({
text: e,
tokens: []
}))),
align: t[2].replace(/^ *|\| *$/g, "").split(/ *\| */),
rows: t[3] && t[3].trim() ? t[3].replace(/\n[ \t]*$/, "").split("\n") : []
};
if (e.header.length === e.align.length) {
let t, n, i, s, r = e.align.length;
for (t = 0; t < r; t++) {
const n = e.align[t];
n && (/^ *-+: *$/.test(n) ? e.align[t] = "right" : /^ *:-+: *$/.test(n) ? e.align[
t] = "center" : /^ *:-+ *$/.test(n) ? e.align[t] = "left" : e.align[t] =
null)
}
for (r = e.rows.length, t = 0; t < r; t++) e.rows[t] = he(e.rows[t], e.header.length)
.map((e => ({
text: e,
tokens: []
})));
for (r = e.header.length, n = 0; n < r; n++) e.header[n].tokens = this.lexer.inline(e
.header[n].text);
for (r = e.rows.length, n = 0; n < r; n++)
for (s = e.rows[n], i = 0; i < s.length; i++) s[i].tokens = this.lexer.inline(s[i]
.text);
return e
}
}
}
lheading(e) {
const t = this.rules.block.lheading.exec(e);
if (t) return {
type: "heading",
raw: t[0],
depth: "=" === t[2].charAt(0) ? 1 : 2,
text: t[1],
tokens: this.lexer.inline(t[1])
}
}
paragraph(e) {
const t = this.rules.block.paragraph.exec(e);
if (t) {
const e = "\n" === t[1].charAt(t[1].length - 1) ? t[1].slice(0, -1) : t[1];
return {
type: "paragraph",
raw: t[0],
text: e,
tokens: this.lexer.inline(e)
}
}
}
text(e) {
const t = this.rules.block.text.exec(e);
if (t) return {
type: "text",
raw: t[0],
text: t[0],
tokens: this.lexer.inline(t[0])
}
}
escape(e) {
const t = this.rules.inline.escape.exec(e);
if (t) return {
type: "escape",
raw: t[0],
text: X(t[1])
}
}
tag(e) {
const t = this.rules.inline.tag.exec(e);
if (t) return !this.lexer.state.inLink && /^<a /i.test(t[0]) ? this.lexer.state.inLink = !0 :
this.lexer.state.inLink && /^<\/a>/i.test(t[0]) && (this.lexer.state.inLink = !1), !this
.lexer.state.inRawBlock && /^<(pre|code|kbd|script)(\s|>)/i.test(t[0]) ? this.lexer
.state.inRawBlock = !0 : this.lexer.state.inRawBlock &&
/^<\/(pre|code|kbd|script)(\s|>)/i.test(t[0]) && (this.lexer.state.inRawBlock = !1), {
type: this.options.sanitize ? "text" : "html",
raw: t[0],
inLink: this.lexer.state.inLink,
inRawBlock: this.lexer.state.inRawBlock,
block: !1,
text: this.options.sanitize ? this.options.sanitizer ? this.options.sanitizer(t[
0]) : X(t[0]) : t[0]
}
}
link(e) {
const t = this.rules.inline.link.exec(e);
if (t) {
const e = t[2].trim();
if (!this.options.pedantic && /^</.test(e)) {
if (!/>$/.test(e)) return;
const t = ue(e.slice(0, -1), "\\");
if ((e.length - t.length) % 2 == 0) return
} else {
const e = function(e, t) {
if (-1 === e.indexOf(t[1])) return -1;
let n = 0;
for (let i = 0; i < e.length; i++)
if ("\\" === e[i]) i++;
else if (e[i] === t[0]) n++;
else if (e[i] === t[1] && (n--, n < 0)) return i;
return -1
}(t[2], "()");
if (e > -1) {
const n = (0 === t[0].indexOf("!") ? 5 : 4) + t[1].length + e;
t[2] = t[2].substring(0, e), t[0] = t[0].substring(0, n).trim(), t[3] = ""
}
}
let n = t[2],
i = "";
if (this.options.pedantic) {
const e = /^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(n);
e && (n = e[1], i = e[3])
} else i = t[3] ? t[3].slice(1, -1) : "";
return n = n.trim(), /^</.test(n) && (n = this.options.pedantic && !/>$/.test(e) ? n.slice(
1) : n.slice(1, -1)), pe(t, {
href: n ? n.replace(this.rules.inline._escapes, "$1") : n,
title: i ? i.replace(this.rules.inline._escapes, "$1") : i
}, t[0], this.lexer)
}
}
reflink(e, t) {
let n;
if ((n = this.rules.inline.reflink.exec(e)) || (n = this.rules.inline.nolink.exec(e))) {
let e = (n[2] || n[1]).replace(/\s+/g, " ");
if (e = t[e.toLowerCase()], !e) {
const e = n[0].charAt(0);
return {
type: "text",
raw: e,
text: e
}
}
return pe(n, e, n[0], this.lexer)
}
}
emStrong(e, t, n = "") {
let i = this.rules.inline.emStrong.lDelim.exec(e);
if (!i) return;
if (i[3] && n.match(/[\p{L}\p{N}]/u)) return;
if (!(i[1] || i[2] || "") || !n || this.rules.inline.punctuation.exec(n)) {
const n = [...i[0]].length - 1;
let s, r, o = n,
a = 0;
const l = "*" === i[0][0] ? this.rules.inline.emStrong.rDelimAst : this.rules.inline
.emStrong.rDelimUnd;
for (l.lastIndex = 0, t = t.slice(-1 * e.length + n); null != (i = l.exec(t));) {
if (s = i[1] || i[2] || i[3] || i[4] || i[5] || i[6], !s) continue;
if (r = [...s].length, i[3] || i[4]) {
o += r;
continue
}
if ((i[5] || i[6]) && n % 3 && !((n + r) % 3)) {
a += r;
continue
}
if (o -= r, o > 0) continue;
r = Math.min(r, r + o + a);
const t = [...e].slice(0, n + i.index + r + 1).join("");
if (Math.min(n, r) % 2) {
const e = t.slice(1, -1);
return {
type: "em",
raw: t,
text: e,
tokens: this.lexer.inlineTokens(e)
}
}
const l = t.slice(2, -2);
return {
type: "strong",
raw: t,
text: l,
tokens: this.lexer.inlineTokens(l)
}
}
}
}
codespan(e) {
const t = this.rules.inline.code.exec(e);
if (t) {
let e = t[2].replace(/\n/g, " ");
const n = /[^ ]/.test(e),
i = /^ /.test(e) && / $/.test(e);
return n && i && (e = e.substring(1, e.length - 1)), e = X(e, !0), {
type: "codespan",
raw: t[0],
text: e
}
}
}
br(e) {
const t = this.rules.inline.br.exec(e);
if (t) return {
type: "br",
raw: t[0]
}
}
del(e) {
const t = this.rules.inline.del.exec(e);
if (t) return {
type: "del",
raw: t[0],
text: t[2],
tokens: this.lexer.inlineTokens(t[2])
}
}
autolink(e, t) {
const n = this.rules.inline.autolink.exec(e);
if (n) {
let e, i;
return "@" === n[2] ? (e = X(this.options.mangle ? t(n[1]) : n[1]), i = "mailto:" + e) : (
e = X(n[1]), i = e), {
type: "link",
raw: n[0],
text: e,
href: i,
tokens: [{
type: "text",
raw: e,
text: e
}]
}
}
}
url(e, t) {
let n;
if (n = this.rules.inline.url.exec(e)) {
let e, i;
if ("@" === n[2]) e = X(this.options.mangle ? t(n[0]) : n[0]), i = "mailto:" + e;
else {
let t;
do {
t = n[0], n[0] = this.rules.inline._backpedal.exec(n[0])[0]
} while (t !== n[0]);
e = X(n[0]), i = "www." === n[1] ? "http://" + n[0] : n[0]
}
return {
type: "link",
raw: n[0],
text: e,
href: i,
tokens: [{
type: "text",
raw: e,
text: e
}]
}
}
}
inlineText(e, t) {
const n = this.rules.inline.text.exec(e);
if (n) {
let e;
return e = this.lexer.state.inRawBlock ? this.options.sanitize ? this.options.sanitizer ?
this.options.sanitizer(n[0]) : X(n[0]) : n[0] : X(this.options.smartypants ? t(n[0]) :
n[0]), {
type: "text",
raw: n[0],
text: e
}
}
}
}
const me = {
newline: /^(?: *(?:\n|$))+/,
code: /^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,
fences: /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,
hr: /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,
heading: /^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,
blockquote: /^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,
list: /^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/,
html: "^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|<![A-Z][\\s\\S]*?(?:>\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$))",
def: /^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/,
table: de,
lheading: /^((?:(?!^bull ).|\n(?!\n|bull ))+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
_paragraph: /^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,
text: /^[^\n]+/,
_label: /(?!\s*\])(?:\\.|[^\[\]\\])+/,
_title: /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/
};
me.def = ne(me.def).replace("label", me._label).replace("title", me._title).getRegex(), me.bullet =
/(?:[*+-]|\d{1,9}[.)])/, me.listItemStart = ne(/^( *)(bull) */).replace("bull", me.bullet).getRegex(),
me.list = ne(me.list).replace(/bull/g, me.bullet).replace("hr",
"\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))").replace("def", "\\n+(?=" + me.def
.source + ")").getRegex(), me._tag =
"address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",
me._comment = /<!--(?!-?>)[\s\S]*?(?:-->|$)/, me.html = ne(me.html, "i").replace("comment", me._comment)
.replace("tag", me._tag).replace("attribute",
/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(), me
.lheading = ne(me.lheading).replace(/bull/g, me.bullet).getRegex(), me.paragraph = ne(me._paragraph)
.replace("hr", me.hr).replace("heading", " {0,3}#{1,6} ").replace("|lheading", "").replace("|table", "")
.replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n")
.replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace("html",
"</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", me._tag).getRegex(),
me.blockquote = ne(me.blockquote).replace("paragraph", me.paragraph).getRegex(), me.normal = u({}, me),
me.gfm = p(u({}, me.normal), {
table: "^ *([^\\n ].*\\|.*)\\n {0,3}(?:\\| *)?(:?-+:? *(?:\\| *:?-+:? *)*)(?:\\| *)?(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)"
}), me.gfm.table = ne(me.gfm.table).replace("hr", me.hr).replace("heading", " {0,3}#{1,6} ").replace(
"blockquote", " {0,3}>").replace("code", " {4}[^\\n]").replace("fences",
" {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list", " {0,3}(?:[*+-]|1[.)]) ").replace(
"html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", me._tag)
.getRegex(), me.gfm.paragraph = ne(me._paragraph).replace("hr", me.hr).replace("heading",
" {0,3}#{1,6} ").replace("|lheading", "").replace("table", me.gfm.table).replace("blockquote",
" {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list",
" {0,3}(?:[*+-]|1[.)]) ").replace("html",
"</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", me._tag).getRegex(),
me.pedantic = p(u({}, me.normal), {
html: ne(
"^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:\"[^\"]*\"|'[^']*'|\\s[^'\"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))"
).replace("comment", me._comment).replace(/tag/g,
"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b"
).getRegex(),
def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,
heading: /^(#{1,6})(.*)(?:\n+|$)/,
fences: de,
lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,
paragraph: ne(me.normal._paragraph).replace("hr", me.hr).replace("heading", " *#{1,6} *[^\n]")
.replace("lheading", me.lheading).replace("blockquote", " {0,3}>").replace("|fences", "")
.replace("|list", "").replace("|html", "").getRegex()
});
const fe = {
escape: /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,
autolink: /^<(scheme:[^\s\x00-\x1f<>]*|email)>/,
url: de,
tag: "^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>",
link: /^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/,
reflink: /^!?\[(label)\]\[(ref)\]/,
nolink: /^!?\[(ref)\](?:\[\])?/,
reflinkSearch: "reflink|nolink(?!\\()",
emStrong: {
lDelim: /^(?:\*+(?:((?!\*)[punct])|[^\s*]))|^_+(?:((?!_)[punct])|([^\s_]))/,
rDelimAst: /^[^_*]*?__[^_*]*?\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\*)[punct](\*+)(?=[\s]|$)|[^punct\s](\*+)(?!\*)(?=[punct\s]|$)|(?!\*)[punct\s](\*+)(?=[^punct\s])|[\s](\*+)(?!\*)(?=[punct])|(?!\*)[punct](\*+)(?!\*)(?=[punct])|[^punct\s](\*+)(?=[^punct\s])/,
rDelimUnd: /^[^_*]*?\*\*[^_*]*?_[^_*]*?(?=\*\*)|[^_]+(?=[^_])|(?!_)[punct](_+)(?=[\s]|$)|[^punct\s](_+)(?!_)(?=[punct\s]|$)|(?!_)[punct\s](_+)(?=[^punct\s])|[\s](_+)(?!_)(?=[punct])|(?!_)[punct](_+)(?!_)(?=[punct])/
},
code: /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,
br: /^( {2,}|\\)\n(?!\s*$)/,
del: de,
text: /^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,
punctuation: /^((?![*_])[\spunctuation])/
};
function ke(e) {
return e.replace(/---/g, "—").replace(/--/g, "").replace(/(^|[-\u2014/(\[{"\s])'/g, "$1").replace(
/'/g, "").replace(/(^|[-\u2014/(\[{\u2018\s])"/g, "$1“").replace(/"/g, "”").replace(/\.{3}/g,
"…")
}
function ye(e) {
let t = "";
for (let n = 0; n < e.length; n++) {
t += "&#" + (Math.random() > .5 ? "x" + e.charCodeAt(n).toString(16) : e.charCodeAt(n).toString()) +
";"
}
return t
}
fe._punctuation = "\\p{P}$+<=>`^|~", fe.punctuation = ne(fe.punctuation, "u").replace(/punctuation/g, fe
._punctuation).getRegex(), fe.blockSkip = /\[[^[\]]*?\]\([^\(\)]*?\)|`[^`]*?`|<[^<>]*?>/g, fe
.anyPunctuation = /\\[punct]/g, fe._escapes = /\\([punct])/g, fe._comment = ne(me._comment).replace(
"(?:--\x3e|$)", "--\x3e").getRegex(), fe.emStrong.lDelim = ne(fe.emStrong.lDelim, "u").replace(
/punct/g, fe._punctuation).getRegex(), fe.emStrong.rDelimAst = ne(fe.emStrong.rDelimAst, "gu")
.replace(/punct/g, fe._punctuation).getRegex(), fe.emStrong.rDelimUnd = ne(fe.emStrong.rDelimUnd, "gu")
.replace(/punct/g, fe._punctuation).getRegex(), fe.anyPunctuation = ne(fe.anyPunctuation, "gu").replace(
/punct/g, fe._punctuation).getRegex(), fe._escapes = ne(fe._escapes, "gu").replace(/punct/g, fe
._punctuation).getRegex(), fe._scheme = /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/, fe._email =
/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/,
fe.autolink = ne(fe.autolink).replace("scheme", fe._scheme).replace("email", fe._email).getRegex(), fe
._attribute = /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/, fe.tag =
ne(fe.tag).replace("comment", fe._comment).replace("attribute", fe._attribute).getRegex(), fe._label =
/(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/, fe._href =
/<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/, fe._title =
/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/, fe.link = ne(fe.link).replace("label", fe
._label).replace("href", fe._href).replace("title", fe._title).getRegex(), fe.reflink = ne(fe
.reflink).replace("label", fe._label).replace("ref", me._label).getRegex(), fe.nolink = ne(fe
.nolink).replace("ref", me._label).getRegex(), fe.reflinkSearch = ne(fe.reflinkSearch, "g").replace(
"reflink", fe.reflink).replace("nolink", fe.nolink).getRegex(), fe.normal = u({}, fe), fe.pedantic =
p(u({}, fe.normal), {
strong: {
start: /^__|\*\*/,
middle: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
endAst: /\*\*(?!\*)/g,
endUnd: /__(?!_)/g
},
em: {
start: /^_|\*/,
middle: /^()\*(?=\S)([\s\S]*?\S)\*(?!\*)|^_(?=\S)([\s\S]*?\S)_(?!_)/,
endAst: /\*(?!\*)/g,
endUnd: /_(?!_)/g
},
link: ne(/^!?\[(label)\]\((.*?)\)/).replace("label", fe._label).getRegex(),
reflink: ne(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label", fe._label).getRegex()
}), fe.gfm = p(u({}, fe.normal), {
escape: ne(fe.escape).replace("])", "~|])").getRegex(),
_extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,
url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,
_backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,
del: /^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,
text: /^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/
}), fe.gfm.url = ne(fe.gfm.url, "i").replace("email", fe.gfm._extended_email).getRegex(), fe.breaks = p(
u({}, fe.gfm), {
br: ne(fe.br).replace("{2,}", "*").getRegex(),
text: ne(fe.gfm.text).replace("\\b_", "\\b_| {2,}\\n").replace(/\{2,\}/g, "*").getRegex()
});
class ve {
constructor(e) {
g(this, "tokens"), g(this, "options"), g(this, "state"), g(this, "tokenizer"), g(this,
"inlineQueue"), this.tokens = [], this.tokens.links = Object.create(null), this
.options = e || N, this.options.tokenizer = this.options.tokenizer || new ge, this
.tokenizer = this.options.tokenizer, this.tokenizer.options = this.options, this.tokenizer
.lexer = this, this.inlineQueue = [], this.state = {
inLink: !1,
inRawBlock: !1,
top: !0
};
const t = {
block: me.normal,
inline: fe.normal
};
this.options.pedantic ? (t.block = me.pedantic, t.inline = fe.pedantic) : this.options.gfm && (t
.block = me.gfm, this.options.breaks ? t.inline = fe.breaks : t.inline = fe.gfm), this
.tokenizer.rules = t
}
static get rules() {
return {
block: me,
inline: fe
}
}
static lex(e, t) {
return new ve(t).lex(e)
}
static lexInline(e, t) {
return new ve(t).inlineTokens(e)
}
lex(e) {
let t;
for (e = e.replace(/\r\n|\r/g, "\n"), this.blockTokens(e, this.tokens); t = this.inlineQueue
.shift();) this.inlineTokens(t.src, t.tokens);
return this.tokens
}
blockTokens(e, t = []) {
let n, i, s, r;
for (e = this.options.pedantic ? e.replace(/\t/g, " ").replace(/^ +$/gm, "") : e.replace(
/^( *)(\t+)/gm, ((e, t, n) => t + " ".repeat(n.length))); e;)
if (!(this.options.extensions && this.options.extensions.block && this.options.extensions
.block.some((i => !!(n = i.call({
lexer: this
}, e, t)) && (e = e.substring(n.raw.length), t.push(n), !0)))))
if (n = this.tokenizer.space(e)) e = e.substring(n.raw.length), 1 === n.raw.length && t
.length > 0 ? t[t.length - 1].raw += "\n" : t.push(n);
else if (n = this.tokenizer.code(e)) e = e.substring(n.raw.length), i = t[t.length - 1],
!i || "paragraph" !== i.type && "text" !== i.type ? t.push(n) : (i.raw += "\n" + n.raw, i
.text += "\n" + n.text, this.inlineQueue[this.inlineQueue.length - 1].src = i.text);
else if (n = this.tokenizer.fences(e)) e = e.substring(n.raw.length), t.push(n);
else if (n = this.tokenizer.heading(e)) e = e.substring(n.raw.length), t.push(n);
else if (n = this.tokenizer.hr(e)) e = e.substring(n.raw.length), t.push(n);
else if (n = this.tokenizer.blockquote(e)) e = e.substring(n.raw.length), t.push(n);
else if (n = this.tokenizer.list(e)) e = e.substring(n.raw.length), t.push(n);
else if (n = this.tokenizer.html(e)) e = e.substring(n.raw.length), t.push(n);
else if (n = this.tokenizer.def(e)) e = e.substring(n.raw.length), i = t[t.length - 1], !i ||
"paragraph" !== i.type && "text" !== i.type ? this.tokens.links[n.tag] || (this.tokens
.links[n.tag] = {
href: n.href,
title: n.title
}) : (i.raw += "\n" + n.raw, i.text += "\n" + n.raw, this.inlineQueue[this.inlineQueue
.length - 1].src = i.text);
else if (n = this.tokenizer.table(e)) e = e.substring(n.raw.length), t.push(n);
else if (n = this.tokenizer.lheading(e)) e = e.substring(n.raw.length), t.push(n);
else {
if (s = e, this.options.extensions && this.options.extensions.startBlock) {
let t = 1 / 0;
const n = e.slice(1);
let i;
this.options.extensions.startBlock.forEach((e => {
i = e.call({
lexer: this
}, n), "number" == typeof i && i >= 0 && (t = Math.min(t, i))
})), t < 1 / 0 && t >= 0 && (s = e.substring(0, t + 1))
}
if (this.state.top && (n = this.tokenizer.paragraph(s))) i = t[t.length - 1], r &&
"paragraph" === i.type ? (i.raw += "\n" + n.raw, i.text += "\n" + n.text, this
.inlineQueue.pop(), this.inlineQueue[this.inlineQueue.length - 1].src = i.text) : t
.push(n), r = s.length !== e.length, e = e.substring(n.raw.length);
else if (n = this.tokenizer.text(e)) e = e.substring(n.raw.length), i = t[t.length - 1],
i && "text" === i.type ? (i.raw += "\n" + n.raw, i.text += "\n" + n.text, this
.inlineQueue.pop(), this.inlineQueue[this.inlineQueue.length - 1].src = i.text) : t
.push(n);
else if (e) {
const t = "Infinite loop on byte: " + e.charCodeAt(0);
if (this.options.silent) {
console.error(t);
break
}
throw new Error(t)
}
}
return this.state.top = !0, t
}
inline(e, t = []) {
return this.inlineQueue.push({
src: e,
tokens: t
}), t
}
inlineTokens(e, t = []) {
let n, i, s, r, o, a, l = e;
if (this.tokens.links) {
const e = Object.keys(this.tokens.links);
if (e.length > 0)
for (; null != (r = this.tokenizer.rules.inline.reflinkSearch.exec(l));) e.includes(r[0]
.slice(r[0].lastIndexOf("[") + 1, -1)) && (l = l.slice(0, r.index) + "[" + "a"
.repeat(r[0].length - 2) + "]" + l.slice(this.tokenizer.rules.inline
.reflinkSearch.lastIndex))
}
for (; null != (r = this.tokenizer.rules.inline.blockSkip.exec(l));) l = l.slice(0, r.index) +
"[" + "a".repeat(r[0].length - 2) + "]" + l.slice(this.tokenizer.rules.inline.blockSkip
.lastIndex);
for (; null != (r = this.tokenizer.rules.inline.anyPunctuation.exec(l));) l = l.slice(0, r
.index) + "++" + l.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);
for (; e;)
if (o || (a = ""), o = !1, !(this.options.extensions && this.options.extensions.inline &&
this.options.extensions.inline.some((i => !!(n = i.call({
lexer: this
}, e, t)) && (e = e.substring(n.raw.length), t.push(n), !0)))))
if (n = this.tokenizer.escape(e)) e = e.substring(n.raw.length), t.push(n);
else if (n = this.tokenizer.tag(e)) e = e.substring(n.raw.length), i = t[t.length - 1],
i && "text" === n.type && "text" === i.type ? (i.raw += n.raw, i.text += n.text) : t.push(
n);
else if (n = this.tokenizer.link(e)) e = e.substring(n.raw.length), t.push(n);
else if (n = this.tokenizer.reflink(e, this.tokens.links)) e = e.substring(n.raw.length), i = t[
t.length - 1], i && "text" === n.type && "text" === i.type ? (i.raw += n.raw, i.text +=
n.text) : t.push(n);
else if (n = this.tokenizer.emStrong(e, l, a)) e = e.substring(n.raw.length), t.push(n);
else if (n = this.tokenizer.codespan(e)) e = e.substring(n.raw.length), t.push(n);
else if (n = this.tokenizer.br(e)) e = e.substring(n.raw.length), t.push(n);
else if (n = this.tokenizer.del(e)) e = e.substring(n.raw.length), t.push(n);
else if (n = this.tokenizer.autolink(e, ye)) e = e.substring(n.raw.length), t.push(n);
else if (this.state.inLink || !(n = this.tokenizer.url(e, ye))) {
if (s = e, this.options.extensions && this.options.extensions.startInline) {
let t = 1 / 0;
const n = e.slice(1);
let i;
this.options.extensions.startInline.forEach((e => {
i = e.call({
lexer: this
}, n), "number" == typeof i && i >= 0 && (t = Math.min(t, i))
})), t < 1 / 0 && t >= 0 && (s = e.substring(0, t + 1))
}
if (n = this.tokenizer.inlineText(s, ke)) e = e.substring(n.raw.length), "_" !== n.raw
.slice(-1) && (a = n.raw.slice(-1)), o = !0, i = t[t.length - 1], i && "text" === i
.type ? (i.raw += n.raw, i.text += n.text) : t.push(n);
else if (e) {
const t = "Infinite loop on byte: " + e.charCodeAt(0);
if (this.options.silent) {
console.error(t);
break
}
throw new Error(t)
}
} else e = e.substring(n.raw.length), t.push(n);
return t
}
}
class $e {
constructor(e) {
g(this, "options"), this.options = e || N
}
code(e, t, n) {
var i;
const s = null == (i = (t || "").match(/^\S*/)) ? void 0 : i[0];
if (this.options.highlight) {
const t = this.options.highlight(e, s);
null != t && t !== e && (n = !0, e = t)
}
return e = e.replace(/\n$/, "") + "\n", s ? '<pre><code class="' + this.options.langPrefix + X(
s) + '">' + (n ? e : X(e, !0)) + "</code></pre>\n" : "<pre><code>" + (n ? e : X(e, !
0)) + "</code></pre>\n"
}
blockquote(e) {
return `<blockquote>\n${e}</blockquote>\n`
}
html(e, t) {
return e
}
heading(e, t, n, i) {
if (this.options.headerIds) {
return `<h${t} id="${this.options.headerPrefix+i.slug(n)}">${e}</h${t}>\n`
}
return `<h${t}>${e}</h${t}>\n`
}
hr() {
return this.options.xhtml ? "<hr/>\n" : "<hr>\n"
}
list(e, t, n) {
const i = t ? "ol" : "ul";
return "<" + i + (t && 1 !== n ? ' start="' + n + '"' : "") + ">\n" + e + "</" + i + ">\n"
}
listitem(e, t, n) {
return `<li>${e}</li>\n`
}
checkbox(e) {
return "<input " + (e ? 'checked="" ' : "") + 'disabled="" type="checkbox"' + (this.options
.xhtml ? " /" : "") + "> "
}
paragraph(e) {
return `<p>${e}</p>\n`
}
table(e, t) {
return t && (t = `<tbody>${t}</tbody>`), "<table>\n<thead>\n" + e + "</thead>\n" + t +
"</table>\n"
}
tablerow(e) {
return `<tr>\n${e}</tr>\n`
}
tablecell(e, t) {
const n = t.header ? "th" : "td";
return (t.align ? `<${n} align="${t.align}">` : `<${n}>`) + e + `</${n}>\n`
}
strong(e) {
return `<strong>${e}</strong>`
}
em(e) {
return `<em>${e}</em>`
}
codespan(e) {
return `<code>${e}</code>`
}
br() {
return this.options.xhtml ? "<br/>" : "<br>"
}
del(e) {
return `<del>${e}</del>`
}
link(e, t, n) {
const i = re(this.options.sanitize, this.options.baseUrl, e);
if (null === i) return n;
let s = '<a href="' + (e = i) + '"';
return t && (s += ' title="' + t + '"'), s += ">" + n + "</a>", s
}
image(e, t, n) {
const i = re(this.options.sanitize, this.options.baseUrl, e);
if (null === i) return n;
let s = `<img src="${e=i}" alt="${n}"`;
return t && (s += ` title="${t}"`), s += this.options.xhtml ? "/>" : ">", s
}
text(e) {
return e
}
}
class be {
strong(e) {
return e
}
em(e) {
return e
}
codespan(e) {
return e
}
del(e) {
return e
}
html(e) {
return e
}
text(e) {
return e
}
link(e, t, n) {
return "" + n
}
image(e, t, n) {
return "" + n
}
br() {
return ""
}
}
class we {
constructor() {
g(this, "seen"), this.seen = {}
}
serialize(e) {
return e.toLowerCase().trim().replace(/<[!\/a-z].*?>/gi, "").replace(
/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g, "").replace(/\s/g, "-")
}
getNextSafeSlug(e, t) {
let n = e,
i = 0;
if (this.seen.hasOwnProperty(n)) {
i = this.seen[e];
do {
i++, n = e + "-" + i
} while (this.seen.hasOwnProperty(n))
}
return t || (this.seen[e] = i, this.seen[n] = 0), n
}
slug(e, t = {}) {
const n = this.serialize(e);
return this.getNextSafeSlug(n, t.dryrun)
}
}
class xe {
constructor(e) {
g(this, "options"), g(this, "renderer"), g(this, "textRenderer"), g(this, "slugger"), this
.options = e || N, this.options.renderer = this.options.renderer || new $e, this.renderer =
this.options.renderer, this.renderer.options = this.options, this.textRenderer = new be,
this.slugger = new we
}
static parse(e, t) {
return new xe(t).parse(e)
}
static parseInline(e, t) {
return new xe(t).parseInline(e)
}
parse(e, t = !0) {
let n = "";
for (let i = 0; i < e.length; i++) {
const s = e[i];
if (this.options.extensions && this.options.extensions.renderers && this.options.extensions
.renderers[s.type]) {
const e = s,
t = this.options.extensions.renderers[e.type].call({
parser: this
}, e);
if (!1 !== t || !["space", "hr", "heading", "code", "table", "blockquote", "list",
"html", "paragraph", "text"
].includes(e.type)) {
n += t || "";
continue
}
}
switch (s.type) {
case "space":
continue;
case "hr":
n += this.renderer.hr();
continue;
case "heading": {
const e = s;
n += this.renderer.heading(this.parseInline(e.tokens), e.depth, ee(this.parseInline(
e.tokens, this.textRenderer)), this.slugger);
continue
}
case "code": {
const e = s;
n += this.renderer.code(e.text, e.lang, !!e.escaped);
continue
}
case "table": {
const e = s;
let t = "",
i = "";
for (let n = 0; n < e.header.length; n++) i += this.renderer.tablecell(this
.parseInline(e.header[n].tokens), {
header: !0,
align: e.align[n]
});
t += this.renderer.tablerow(i);
let r = "";
for (let n = 0; n < e.rows.length; n++) {
const t = e.rows[n];
i = "";
for (let n = 0; n < t.length; n++) i += this.renderer.tablecell(this
.parseInline(t[n].tokens), {
header: !1,
align: e.align[n]
});
r += this.renderer.tablerow(i)
}
n += this.renderer.table(t, r);
continue
}
case "blockquote": {
const e = s,
t = this.parse(e.tokens);
n += this.renderer.blockquote(t);
continue
}
case "list": {
const e = s,
t = e.ordered,
i = e.start,
r = e.loose;
let o = "";
for (let n = 0; n < e.items.length; n++) {
const t = e.items[n],
i = t.checked,
s = t.task;
let a = "";
if (t.task) {
const e = this.renderer.checkbox(!!i);
r ? t.tokens.length > 0 && "paragraph" === t.tokens[0].type ? (t.tokens[0]
.text = e + " " + t.tokens[0].text, t.tokens[0].tokens && t.tokens[
0].tokens.length > 0 && "text" === t.tokens[0].tokens[0].type &&
(t.tokens[0].tokens[0].text = e + " " + t.tokens[0].tokens[0].text)
) : t.tokens.unshift({
type: "text",
text: e
}) : a += e
}
a += this.parse(t.tokens, r), o += this.renderer.listitem(a, s, !!i)
}
n += this.renderer.list(o, t, i);
continue
}
case "html": {
const e = s;
n += this.renderer.html(e.text, e.block);
continue
}
case "paragraph": {
const e = s;
n += this.renderer.paragraph(this.parseInline(e.tokens));
continue
}
case "text": {
let r = s,
o = r.tokens ? this.parseInline(r.tokens) : r.text;
for (; i + 1 < e.length && "text" === e[i + 1].type;) r = e[++i], o += "\n" + (r
.tokens ? this.parseInline(r.tokens) : r.text);
n += t ? this.renderer.paragraph(o) : o;
continue
}
default: {
const e = 'Token with "' + s.type + '" type was not found.';
if (this.options.silent) return console.error(e), "";
throw new Error(e)
}
}
}
return n
}
parseInline(e, t) {
t = t || this.renderer;
let n = "";
for (let i = 0; i < e.length; i++) {
const s = e[i];
if (this.options.extensions && this.options.extensions.renderers && this.options.extensions
.renderers[s.type]) {
const e = this.options.extensions.renderers[s.type].call({
parser: this
}, s);
if (!1 !== e || !["escape", "html", "link", "image", "strong", "em", "codespan", "br",
"del", "text"
].includes(s.type)) {
n += e || "";
continue
}
}
switch (s.type) {
case "escape": {
const e = s;
n += t.text(e.text);
break
}
case "html": {
const e = s;
n += t.html(e.text);
break
}
case "link": {
const e = s;
n += t.link(e.href, e.title, this.parseInline(e.tokens, t));
break
}
case "image": {
const e = s;
n += t.image(e.href, e.title, e.text);
break
}
case "strong": {
const e = s;
n += t.strong(this.parseInline(e.tokens, t));
break
}
case "em": {
const e = s;
n += t.em(this.parseInline(e.tokens, t));
break
}
case "codespan": {
const e = s;
n += t.codespan(e.text);
break
}
case "br":
n += t.br();
break;
case "del": {
const e = s;
n += t.del(this.parseInline(e.tokens, t));
break
}
case "text": {
const e = s;
n += t.text(e.text);
break
}
default: {
const e = 'Token with "' + s.type + '" type was not found.';
if (this.options.silent) return console.error(e), "";
throw new Error(e)
}
}
}
return n
}
}
class Ce {
constructor(e) {
g(this, "options"), this.options = e || N
}
preprocess(e) {
return e
}
postprocess(e) {
return e
}
}
g(Ce, "passThroughHooks", new Set(["preprocess", "postprocess"]));
t = new WeakSet, n = function(e, t) {
return (n, r, o) => {
"function" == typeof r && (o = r, r = null);
const a = u({}, r),
l = u(u({}, this.defaults), a);
!0 === this.defaults.async && !1 === a.async && (l.silent || console.warn(
"marked(): The async option was set to true by an extension. The async: false option sent to parse will be ignored."
), l.async = !0);
const c = f(this, i, s).call(this, !!l.silent, !!l.async, o);
if (null == n) return c(new Error("marked(): input parameter is undefined or null"));
if ("string" != typeof n) return c(new Error("marked(): input parameter is of type " +
Object.prototype.toString.call(n) + ", string expected"));
if (function(e, t) {
e && !e.silent && (t && console.warn(
"marked(): callback is deprecated since version 5.0.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/using_pro#async"
), (e.sanitize || e.sanitizer) && console.warn(
"marked(): sanitize and sanitizer parameters are deprecated since version 0.7.0, should not be used and will be removed in the future. Read more here: https://marked.js.org/#/USING_ADVANCED.md#options"
), (e.highlight || "language-" !== e.langPrefix) && console.warn(
"marked(): highlight and langPrefix parameters are deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-highlight."
), e.mangle && console.warn(
"marked(): mangle parameter is enabled by default, but is deprecated since version 5.0.0, and will be removed in the future. To clear this warning, install https://www.npmjs.com/package/marked-mangle, or disable by setting `{mangle: false}`."
), e.baseUrl && console.warn(
"marked(): baseUrl parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-base-url."
), e.smartypants && console.warn(
"marked(): smartypants parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-smartypants."
), e.xhtml && console.warn(
"marked(): xhtml parameter is deprecated since version 5.0.0, should not be used and will be removed in the future. Instead use https://www.npmjs.com/package/marked-xhtml."
), (e.headerIds || e.headerPrefix) && console.warn(
"marked(): headerIds and headerPrefix parameters enabled by default, but are deprecated since version 5.0.0, and will be removed in the future. To clear this warning, install https://www.npmjs.com/package/marked-gfm-heading-id, or disable by setting `{headerIds: false}`."
))
}(l, o), l.hooks && (l.hooks.options = l), o) {
const i = o,
s = l.highlight;
let r;
try {
l.hooks && (n = l.hooks.preprocess(n)), r = e(n, l)
} catch (d) {
return c(d)
}
const a = e => {
let n;
if (!e) try {
l.walkTokens && this.walkTokens(r, l.walkTokens), n = t(r, l), l
.hooks && (n = l.hooks.postprocess(n))
} catch (d) {
e = d
}
return l.highlight = s, e ? c(e) : i(null, n)
};
if (!s || s.length < 3) return a();
if (delete l.highlight, !r.length) return a();
let h = 0;
return this.walkTokens(r, (e => {
"code" === e.type && (h++, setTimeout((() => {
s(e.text, e.lang, ((t, n) => {
if (t) return a(t);
null != n && n !== e.text && (e
.text = n, e.escaped = !0),
h--, 0 === h && a()
}))
}), 0))
})), void(0 === h && a())
}
if (l.async) return Promise.resolve(l.hooks ? l.hooks.preprocess(n) : n).then((t => e(t,
l))).then((e => l.walkTokens ? Promise.all(this.walkTokens(e, l.walkTokens))
.then((() => e)) : e)).then((e => t(e, l))).then((e => l.hooks ? l.hooks
.postprocess(e) : e)).catch(c);
try {
l.hooks && (n = l.hooks.preprocess(n));
const i = e(n, l);
l.walkTokens && this.walkTokens(i, l.walkTokens);
let s = t(i, l);
return l.hooks && (s = l.hooks.postprocess(s)), s
} catch (d) {
return c(d)
}
}
}, i = new WeakSet, s = function(e, t, n) {
return i => {
if (i.message += "\nPlease report this to https://github.com/markedjs/marked.", e) {
const e = "<p>An error occurred:</p><pre>" + X(i.message + "", !0) + "</pre>";
return t ? Promise.resolve(e) : n ? void n(null, e) : e
}
if (t) return Promise.reject(i);
if (!n) throw i;
n(i)
}
};
const Se = new class {
constructor(...e) {
m(this, t), m(this, i), g(this, "defaults", {
async: !1,
baseUrl: null,
breaks: !1,
extensions: null,
gfm: !0,
headerIds: !1,
headerPrefix: "",
highlight: null,
hooks: null,
langPrefix: "language-",
mangle: !1,
pedantic: !1,
renderer: null,
sanitize: !1,
sanitizer: null,
silent: !1,
smartypants: !1,
tokenizer: null,
walkTokens: null,
xhtml: !1
}), g(this, "options", this.setOptions), g(this, "parse", f(this, t, n).call(this, ve
.lex, xe.parse)), g(this, "parseInline", f(this, t, n).call(this, ve.lexInline, xe
.parseInline)), g(this, "Parser", xe), g(this, "parser", xe.parse), g(this,
"Renderer", $e), g(this, "TextRenderer", be), g(this, "Lexer", ve), g(this, "lexer",
ve.lex), g(this, "Tokenizer", ge), g(this, "Slugger", we), g(this, "Hooks", Ce),
this.use(...e)
}
walkTokens(e, t) {
var n, i;
let s = [];
for (const r of e) switch (s = s.concat(t.call(this, r)), r.type) {
case "table": {
const e = r;
for (const n of e.header) s = s.concat(this.walkTokens(n.tokens, t));
for (const n of e.rows)
for (const e of n) s = s.concat(this.walkTokens(e.tokens, t));
break
}
case "list": {
const e = r;
s = s.concat(this.walkTokens(e.items, t));
break
}
default: {
const e = r;
(null == (i = null == (n = this.defaults.extensions) ? void 0 : n.childTokens) ?
void 0 : i[e.type]) ? this.defaults.extensions.childTokens[e.type].forEach((
n => {
s = s.concat(this.walkTokens(e[n], t))
})): e.tokens && (s = s.concat(this.walkTokens(e.tokens, t)))
}
}
return s
}
use(...e) {
const t = this.defaults.extensions || {
renderers: {},
childTokens: {}
};
return e.forEach((e => {
const n = u({}, e);
if (n.async = this.defaults.async || n.async || !1, e.extensions && (e
.extensions.forEach((e => {
if (!e.name) throw new Error("extension name required");
if ("renderer" in e) {
const n = t.renderers[e.name];
t.renderers[e.name] = n ? function(...t) {
let i = e.renderer.apply(this, t);
return !1 === i && (i = n.apply(this, t)), i
} : e.renderer
}
if ("tokenizer" in e) {
if (!e.level || "block" !== e.level && "inline" !==
e.level) throw new Error(
"extension level must be 'block' or 'inline'"
);
const n = t[e.level];
n ? n.unshift(e.tokenizer) : t[e.level] = [e
.tokenizer
], e.start && ("block" === e.level ? t
.startBlock ? t.startBlock.push(e.start) : t
.startBlock = [e.start] : "inline" === e
.level && (t.startInline ? t.startInline
.push(e.start) : t.startInline = [e
.start
]))
}
"childTokens" in e && e.childTokens && (t.childTokens[e
.name] = e.childTokens)
})), n.extensions = t), e.renderer) {
const t = this.defaults.renderer || new $e(this.defaults);
for (const n in e.renderer) {
const i = e.renderer[n],
s = n,
r = t[s];
t[s] = (...e) => {
let n = i.apply(t, e);
return !1 === n && (n = r.apply(t, e)), n || ""
}
}
n.renderer = t
}
if (e.tokenizer) {
const t = this.defaults.tokenizer || new ge(this.defaults);
for (const n in e.tokenizer) {
const i = e.tokenizer[n],
s = n,
r = t[s];
t[s] = (...e) => {
let n = i.apply(t, e);
return !1 === n && (n = r.apply(t, e)), n
}
}
n.tokenizer = t
}
if (e.hooks) {
const t = this.defaults.hooks || new Ce;
for (const n in e.hooks) {
const i = e.hooks[n],
s = n,
r = t[s];
Ce.passThroughHooks.has(n) ? t[s] = e => {
if (this.defaults.async) return Promise.resolve(i.call(t,
e)).then((e => r.call(t, e)));
const n = i.call(t, e);
return r.call(t, n)
} : t[s] = (...e) => {
let n = i.apply(t, e);
return !1 === n && (n = r.apply(t, e)), n
}
}
n.hooks = t
}
if (e.walkTokens) {
const t = this.defaults.walkTokens,
i = e.walkTokens;
n.walkTokens = function(e) {
let n = [];
return n.push(i.call(this, e)), t && (n = n.concat(t.call(this,
e))), n
}
}
this.defaults = u(u({}, this.defaults), n)
})), this
}
setOptions(e) {
return this.defaults = u(u({}, this.defaults), e), this
}
};
function Ee(e, t, n) {
return Se.parse(e, t, n)
}
Ee.options = Ee.setOptions = function(e) {
return Se.setOptions(e), Ee.defaults = Se.defaults, H(Ee.defaults), Ee
}, Ee.getDefaults = j, Ee.defaults = N, Ee.use = function(...e) {
return Se.use(...e), Ee.defaults = Se.defaults, H(Ee.defaults), Ee
}, Ee.walkTokens = function(e, t) {
return Se.walkTokens(e, t)
}, Ee.parseInline = Se.parseInline, Ee.Parser = xe, Ee.parser = xe.parse, Ee.Renderer = $e, Ee
.TextRenderer = be, Ee.Lexer = ve, Ee.lexer = ve.lex, Ee.Tokenizer = ge, Ee.Slugger = we, Ee.Hooks = Ce,
Ee.parse = Ee, Ee.options, Ee.setOptions, Ee.use, Ee.walkTokens, Ee.parseInline;
var Te = {
"&": "&amp;",
"<": "&lt;",
">": "&gt;",
'"': "&quot;",
"'": "&#39;"
},
_e = {
"&amp;": "&",
"&lt;": "<",
"&gt;": ">",
"&quot;": '"',
"&#39;": "'"
},
Le = /(&amp;|&lt;|&gt;|&quot;|&#39;)/g,
Ae = /[&<>"']/g;
function Oe(e) {
return Te[e]
}
function Pe(e) {
return _e[e]
}
function Re(e) {
return null == e ? "" : String(e).replace(Ae, Oe)
}
function Me(e) {
return null == e ? "" : String(e).replace(Le, Pe)
}
Re.options = Me.options = {};
var Ie = {
encode: Re,
escape: Re,
decode: Me,
unescape: Me,
version: "1.0.0-browser"
};
var Ue = function e(t) {
for (var n, i, s = Array.prototype.slice.call(arguments, 1); s.length;)
for (i in n = s.shift()) n.hasOwnProperty(i) && ("[object Object]" === Object.prototype.toString
.call(t[i]) ? t[i] = e(t[i], n[i]) : t[i] = n[i]);
return t
},
De = function(e) {
return "string" == typeof e ? e.toLowerCase() : e
};
function Be(e, t) {
return e[t] = !0, e
}
var qe = function(e) {
return e.reduce(Be, {})
},
Fe = {
uris: qe(["background", "base", "cite", "href", "longdesc", "src", "usemap"])
},
ze = {
voids: qe(["area", "br", "col", "hr", "img", "wbr", "input", "base", "basefont", "link", "meta"])
},
We = Ie,
je = De,
Ne = ze,
He = /^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/,
Qe = /^<\s*\/\s*([\w:-]+)[^>]*>/,
Ve = /([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,
Ge = /^</,
Ke = /^<\s*\//;
var Ze = Ie,
Ye = De,
Xe = Fe,
Je = ze;
var et = Ue,
tt = function(e, t) {
for (var n, i = function() {
var e = [];
return e.lastItem = function() {
return e[e.length - 1]
}, e
}(), s = e; e;) r();
function r() {
n = !0,
function() {
"\x3c!--" === e.substr(0, 4) ? (i = e.indexOf("--\x3e")) >= 0 && (t.comment && t
.comment(e.substring(4, i)), e = e.substring(i + 3), n = !1) : Ke.test(e) ? o(
Qe, l) : Ge.test(e) && o(He, a);
var i;
! function() {
if (!n) return;
var i, s = e.indexOf("<");
s >= 0 ? (i = e.substring(0, s), e = e.substring(s)) : (i = e, e = "");
t.chars && t.chars(i)
}()
}();
var i = e === s;
s = e, i && (e = "")
}
function o(t, i) {
var s = e.match(t);
s && (e = e.substring(s[0].length), s[0].replace(t, i), n = !1)
}
function a(e, n, s, r) {
var o = {},
a = je(n),
l = Ne.voids[a] || !!r;
s.replace(Ve, (function(e, t, n, i, s) {
o[t] = void 0 === n && void 0 === i && void 0 === s ? void 0 : We.decode(n ||
i || s || "")
})), l || i.push(a), t.start && t.start(a, o, l)
}
function l(e, n) {
var s, r = 0,
o = je(n);
if (o)
for (r = i.length - 1; r >= 0 && i[r] !== o; r--);
if (r >= 0) {
for (s = i.length - 1; s >= r; s--) t.end && t.end(i[s]);
i.length = r
}
}
l()
},
nt = function(e, t) {
var n, i = t || {};
return a(), {
start: function(e, t, o) {
var a = Ye(e);
if (n.ignoring) return void r(a);
if (-1 === (i.allowedTags || []).indexOf(a)) return void r(a);
if (i.filter && !i.filter({
tag: a,
attrs: t
})) return void r(a);
s("<"), s(a), Object.keys(t).forEach((function(e) {
var n = t[e],
r = (i.allowedClasses || {})[a] || [],
o = (i.allowedAttributes || {})[a] || [],
l = Ye(e);
("class" === l && -1 === o.indexOf(l) ? (n = n.split(" ").filter((
function(e) {
return r && -1 !== r.indexOf(e)
})).join(" ").trim()).length : -1 !== o.indexOf(l) && (!
0 !== Xe.uris[l] || function(e) {
var t = e[0];
if ("#" === t || "/" === t) return !0;
var n = e.indexOf(":");
if (-1 === n) return !0;
var s = e.indexOf("?");
if (-1 !== s && n > s) return !0;
var r = e.indexOf("#");
return -1 !== r && n > r || i.allowedSchemes.some(o);
function o(t) {
return 0 === e.indexOf(t + ":")
}
}(n))) && (s(" "), s(e), "string" == typeof n && (s('="'), s(Ze
.encode(n)), s('"')))
})), s(o ? "/>" : ">")
},
end: function(e) {
var t = Ye(e); - 1 !== (i.allowedTags || []).indexOf(t) && !1 === n.ignoring ? (s(
"</"), s(t), s(">")) : o(t)
},
chars: function(e) {
!1 === n.ignoring && s(i.transformText ? i.transformText(e) : e)
}
};
function s(t) {
e.push(t)
}
function r(e) {
Je.voids[e] || (!1 === n.ignoring ? n = {
ignoring: e,
depth: 1
} : n.ignoring === e && n.depth++)
}
function o(e) {
n.ignoring === e && --n.depth <= 0 && a()
}
function a() {
n = {
ignoring: !1,
depth: 0
}
}
},
it = {
allowedAttributes: {
a: ["href", "name", "target", "title", "aria-label"],
iframe: ["allowfullscreen", "frameborder", "src"],
img: ["src", "alt", "title", "aria-label"]
},
allowedClasses: {},
allowedSchemes: ["http", "https", "mailto"],
allowedTags: ["a", "abbr", "article", "b", "blockquote", "br", "caption", "code", "del", "details",
"div", "em", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "i", "img", "ins", "kbd", "li",
"main", "mark", "ol", "p", "pre", "section", "span", "strike", "strong", "sub", "summary",
"sup", "table", "tbody", "td", "th", "thead", "tr", "u", "ul"
],
filter: null
};
function st(e, t, n) {
var i = [],
s = !0 === n ? t : et({}, it, t),
r = nt(i, s);
return tt(e, r), i.join("")
}
st.defaults = it;
const rt = L(st),
ot = {
allowedClasses: {},
allowedSchemes: ["http", "https", "mailto", "data"],
allowedTags: ["a", "abbr", "article", "b", "blockquote", "br", "caption", "code", "del", "details",
"div", "em", "h1", "h2", "h3", "h4", "h5", "h6", "hr", "i", "img", "ins", "kbd", "li",
"main", "mark", "ol", "p", "pre", "section", "span", "strike", "strong", "sub", "summary",
"sup", "table", "tbody", "td", "th", "thead", "tr", "u", "ul"
],
allowedAttributes: {
"*": ["title", "accesskey"],
a: ["href", "name", "target", "aria-label", "rel"],
img: ["src", "alt", "title", "atk-emoticon", "aria-label"],
code: ["class"],
span: ["class", "style"]
},
filter: e => ([
["code", /^hljs\W+language-(.*)$/],
["span", /^(hljs-.*)$/]
].forEach((([t, n]) => {
e.tag === t && e.attrs.class && !n.test(e.attrs.class) && delete e.attrs.class
})), "span" === e.tag && e.attrs.style && !/^color:(\W+)?#[0-9a-f]{3,6};?$/i.test(e.attrs
.style) && delete e.attrs.style, !0)
};
function at(e) {
return rt(e, ot)
}
var lt = {
exports: {}
};
lt.exports = function() {
function e(e, t) {
return e(t = {
exports: {}
}, t.exports), t.exports
}
var t = e((function(e) {
var t = e.exports = function() {
return new RegExp("(?:" + t.line().source + ")|(?:" + t.block().source +
")", "gm")
};
t.line = function() {
return /(?:^|\s)\/\/(.+?)$/gm
}, t.block = function() {
return /\/\*([\S\s]*?)\*\//gm
}
})),
n = ["23AC69", "91C132", "F19726", "E8552D", "1AAB8E", "E1147F", "2980C1", "1BA1E6", "9FA0A0",
"F19726", "E30B20", "E30B20", "A3338B"
];
function i(e) {
return '<span style="color: slategray">' + e + "</span>"
}
return function(e, s) {
void 0 === s && (s = {});
var r = s.colors;
void 0 === r && (r = n);
var o = 0,
a = {},
l = new RegExp("(" +
/[\u4E00-\u9FFF\u3400-\u4dbf\uf900-\ufaff\u3040-\u309f\uac00-\ud7af\u0400-\u04FF]+|\w+/
.source + "|" + /</.source + ")|(" + t().source + ")", "gmi");
return e.replace(l, (function(e, t, n) {
if (n) return i(n);
if ("<" === t) return "&lt;";
var s;
a[t] ? s = a[t] : (s = r[o], a[t] = s);
var l = '<span style="color: #' + s + '">' + t + "</span>";
return o = ++o % r.length, l
}))
}
}();
const ct = L(lt.exports);
function dt(e) {
return ct(e)
}
function ht() {
const e = new Ee.Renderer;
return e.link = ut(e, e.link), e.code = pt(), e
}
const ut = (e, t) => (n, i, s) => {
const r = null == n ? void 0 : n.startsWith(
`${window.location.protocol}//${window.location.hostname}`);
return t.call(e, n, i, s).replace(/^<a /,
`<a target="_blank" ${r?"":'rel="noreferrer noopener nofollow"'} `)
},
pt = () => (e, t) => {
const n = t || "plaintext";
let i = e;
return window.hljs ? n && window.hljs.getLanguage(n) && (i = window.hljs.highlight(n, e).value) :
i = dt(e),
`<pre rel="${n}">\n<code class="hljs language-${n}">${i.replace(/&amp;/g,"&")}</code>\n</pre>`
};
let gt, mt = [];
const ft = {
pedantic: !1,
gfm: !0,
breaks: !0,
smartLists: !0,
smartypants: !0,
xhtml: !1,
sanitize: !1,
silent: !0
};
function kt() {
return gt
}
function yt(e) {
var t;
let n = null == (t = kt()) ? void 0 : t.parse(e);
n || (n = function(e) {
return e.replace(/```\s*([^]+?.*?[^]+?[^]+?)```/g, ((e, t) =>
`<pre><code>${dt(t)}</code></pre>`)).replace(/!\[(.*?)\]\((.*?)\)/g, ((e, t, n) =>
`<img src="${n}" alt="${t}" />`)).replace(/\[(.*?)\]\((.*?)\)/g, ((e, t, n) =>
`<a href="${n}" target="_blank">${t}</a>`)).replace(/\n/g, "<br>")
}(e));
let i = at(n);
return mt.forEach((e => {
"function" == typeof e && (i = e(i))
})), i
}
function vt(...e) {
const t = e => e && "object" == typeof e && e.constructor === Object;
return e.reduce(((e, n) => (Object.keys(null != n ? n : {}).forEach((i => {
if ("__proto__" === i || "constructor" === i || "prototype" === i) return;
const s = e[i],
r = n[i];
Array.isArray(s) && Array.isArray(r) ? e[i] = s.concat(...r) : t(s) && t(
r) ? e[i] = vt(s, r) : e[i] = r
})), e)), {})
}
class $t {
constructor(e) {
g(this, "loading", !1), g(this, "listLastFetch"), g(this, "comments", []), g(this, "unreads",
[]), g(this, "page"), this.events = e
}
getLoading() {
return this.loading
}
setLoading(e) {
this.loading = e
}
getListLastFetch() {
return this.listLastFetch
}
setListLastFetch(e) {
this.listLastFetch = e
}
getComments() {
return this.comments
}
fetchComments(e) {
this.events.trigger("list-fetch", e)
}
findComment(e) {
return this.comments.find((t => t.id === e))
}
clearComments() {
this.comments = [], this.events.trigger("list-loaded", this.comments)
}
loadComments(e) {
this.events.trigger("list-load", e), this.comments.push(...e), this.events.trigger(
"list-loaded", this.comments)
}
insertComment(e) {
this.comments.push(e), this.events.trigger("comment-inserted", e), this.events.trigger(
"list-loaded", this.comments)
}
updateComment(e) {
this.comments = this.comments.map((t => t.id === e.id ? e : t)), this.events.trigger(
"comment-updated", e), this.events.trigger("list-loaded", this.comments)
}
deleteComment(e) {
const t = this.comments.find((t => t.id === e));
if (!t) throw new Error(`Comment ${e} not found`);
this.comments = this.comments.filter((t => t.id !== e)), this.events.trigger("comment-deleted",
t), this.events.trigger("list-loaded", this.comments)
}
getUnreads() {
return this.unreads
}
updateUnreads(e) {
this.unreads = e, this.events.trigger("unreads-updated", this.unreads)
}
getPage() {
return this.page
}
updatePage(e) {
this.page = e, this.events.trigger("page-loaded", e)
}
}
class bt {
constructor() {
g(this, "events", [])
}
on(e, t, n = {}) {
this.events.push(u({
name: e,
handler: t
}, n))
}
off(e, t) {
t && (this.events = this.events.filter((n => !(n.name === e && n.handler === t))))
}
trigger(e, t) {
this.events.slice(0).filter((t => t.name === e && "function" == typeof t.handler)).forEach((
n => {
n.once && this.off(e, n.handler), n.handler(t)
}))
}
}
const wt = {
el: "",
pageKey: "",
pageTitle: "",
server: "",
site: "",
placeholder: "",
noComment: "",
sendBtn: "",
darkMode: !1,
editorTravel: !0,
flatMode: "auto",
nestMax: 2,
nestSort: "DATE_ASC",
emoticons: "https://cdn.jsdelivr.net/gh/ArtalkJS/Emoticons/grps/default.json",
vote: !0,
voteDown: !1,
uaBadge: !0,
listSort: !0,
preview: !0,
countEl: "#ArtalkCount",
pvEl: "#ArtalkPV",
gravatar: {
mirror: "https://cravatar.cn/avatar/",
params: "d=mp&s=240"
},
pagination: {
pageSize: 20,
readMore: !0,
autoLoad: !0
},
heightLimit: {
content: 300,
children: 400,
scrollable: !1
},
imgUpload: !0,
reqTimeout: 15e3,
versionCheck: !0,
useBackendConf: !0,
locale: "zh-CN"
};
function xt(e, t = !1) {
const n = t ? vt(wt, e) : e;
if (n.el && "string" == typeof n.el) try {
const e = document.querySelector(n.el);
if (!e) throw Error(`Target element "${n.el}" was not found.`);
n.el = e
} catch (i) {
throw console.error(i), new Error("Please check your Artalk `el` config.")
}
return "" === n.pageKey && (n.pageKey = `${window.location.pathname}`), "" === n.pageTitle && (n
.pageTitle = `${document.title}`), n.server && (n.server = n.server.replace(/\/$/, "").replace(
/\/api\/?$/, "")), "auto" === n.locale && (n.locale = navigator.language), "auto" === n
.flatMode && (n.flatMode = window.matchMedia("(max-width: 768px)").matches), "number" == typeof n
.nestMax && Number(n.nestMax) <= 1 && (n.flatMode = !0), n
}
function Ct(e, t) {
return {
baseURL: `${e.server}/api`,
siteName: e.site || "",
pageKey: e.pageKey || "",
pageTitle: e.pageTitle || "",
timeout: e.reqTimeout,
apiToken: null == t ? void 0 : t.get("user").getData().token,
userInfo: (null == t ? void 0 : t.get("user").checkHasBasicUserInfo()) ? {
name: null == t ? void 0 : t.get("user").getData().nick,
email: null == t ? void 0 : t.get("user").getData().email
} : void 0,
onNeedCheckAdmin(e) {
null == t || t.checkAdmin({
onSuccess: () => {
e.recall()
},
onCancel: () => {
e.reject()
}
})
},
onNeedCheckCaptcha(e) {
null == t || t.checkCaptcha({
imgData: e.data.imgData,
iframe: e.data.iframe,
onSuccess: () => {
e.recall()
},
onCancel: () => {
e.reject()
}
})
}
}
}
class St {
constructor(e) {
g(this, "conf"), g(this, "data"), g(this, "$root"), g(this, "events", new bt), this.conf = e,
this.$root = e.el, this.$root.classList.add("artalk"), this.$root.innerHTML = "", this
.data = new $t(this.events)
}
inject(e, t) {
this[e] = t
}
get(e) {
return this[e]
}
getApi() {
return new W(Ct(this.conf, this))
}
getData() {
return this.data
}
replyComment(e, t) {
this.editor.setReply(e, t)
}
editComment(e, t) {
this.editor.setEditComment(e, t)
}
fetch(e) {
this.data.fetchComments(e)
}
reload() {
this.data.fetchComments({
offset: 0
})
}
listGotoFirst() {
this.events.trigger("list-goto-first")
}
editorShowLoading() {
this.editor.showLoading()
}
editorHideLoading() {
this.editor.hideLoading()
}
editorShowNotify(e, t) {
this.editor.showNotify(e, t)
}
editorResetState() {
this.editor.resetState()
}
showSidebar(e) {
this.sidebarLayer.show(e)
}
hideSidebar() {
this.sidebarLayer.hide()
}
checkAdmin(e) {
this.checkerLauncher.checkAdmin(e)
}
checkCaptcha(e) {
this.checkerLauncher.checkCaptcha(e)
}
on(e, t) {
this.events.on(e, t)
}
off(e, t) {
this.events.off(e, t)
}
trigger(e, t) {
this.events.trigger(e, t)
}
$t(e, t = {}) {
return D(e, t)
}
setDarkMode(e) {
this.conf.darkMode = e, this.events.trigger("dark-mode-changed", e)
}
updateConf(e) {
this.conf = vt(this.conf, xt(e, !1)), this.events.trigger("conf-loaded", this.conf)
}
getConf() {
return this.conf
}
getEl() {
return this.$root
}
getMarked() {
return kt()
}
}
class Et {
constructor(e) {
g(this, "$el"), g(this, "$content"), g(this, "$actions"), this.$el = y(
'<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>'
), this.$actions = this.$el.querySelector(".atk-layer-dialog-actions"), this.$content =
this.$el.querySelector(".atk-layer-dialog-content"), this.$content.appendChild(e)
}
setYes(e) {
const t = y(`<button data-action="confirm">${D("confirm")}</button>`);
return t.onclick = this.onBtnClick(e), this.$actions.appendChild(t), this
}
setNo(e) {
const t = y(`<button data-action="cancel">${D("cancel")}</button>`);
return t.onclick = this.onBtnClick(e), this.$actions.appendChild(t), this
}
onBtnClick(e) {
return t => {
const n = e(t.currentTarget, this);
void 0 !== n && !0 !== n || this.$el.remove()
}
}
}
function Tt(e, t) {
let n = e.querySelector(":scope > .atk-loading");
n || (n = y(
'<div class="atk-loading atk-fade-in" 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>'),
(null == t ? void 0 : t.transparentBg) && (n.style.background = "transparent"), e.appendChild(n)
), n.style.display = "";
const i = n.querySelector(".atk-loading-spinner");
i && (i.style.display = "none", window.setTimeout((() => {
i.style.display = ""
}), 500))
}
function _t(e) {
const t = e.querySelector(":scope > .atk-loading");
t && (t.style.display = "none")
}
function Lt(e, t) {
e ? Tt(t) : _t(t)
}
function At(e, t = !0, n) {
let i;
if (n) {
const t = n.getBoundingClientRect();
i = e.getBoundingClientRect().top - t.top + n.scrollTop, i += v(n) / 2 - v(e) / 2
} else {
const t = e.getBoundingClientRect();
i = t.top + window.scrollY - (window.innerHeight / 2 - t.height / 2)
}
const s = {
top: i,
left: 0,
behavior: "instant"
};
n ? n.scroll(s) : window.scroll(s)
}
function Ot(e, t) {
! function(e, t, n = "in") {
e.classList.add(`atk-fade-${n}`);
const i = () => {
e.classList.remove(`atk-fade-${n}`), e.removeEventListener("animationend", i), t && t()
};
e.addEventListener("animationend", i)
}(e, t, "in")
}
function Pt(e, t, n = '<span class="atk-error-title">Artalk Error</span>') {
let i = e.querySelector(".atk-error-layer");
if (null === t) return void(null !== i && i.remove());
i || (i = y(`<div class="atk-error-layer">${n}<span class="atk-error-text"></span></div>`), e
.appendChild(i));
const s = i.querySelector(".atk-error-text");
s.innerHTML = "", null !== t && (t instanceof HTMLElement ? s.appendChild(t) : s.innerText = t)
}
function Rt(e) {
const t = y('<div class="atk-checker-iframe-wrap"></div>'),
n = y('<iframe class="atk-fade-in" referrerpolicy="strict-origin-when-cross-origin"></iframe>');
n.style.display = "none", Tt(t, {
transparentBg: !0
}), n.src = `${e.getOpts().getIframeURLBase()||""}/api/captcha/get?t=${+new Date}`, n.onload =
() => {
n.style.display = "", _t(t)
}, t.append(n);
const i = y('<div class="atk-close-btn"><i class="atk-icon atk-icon-close"></i></div>');
t.append(i), e.hideInteractInput();
let s = !1;
return function t() {
return k(this, null, (function*() {
var n;
if (yield(n = 1e3, new Promise((e => {
window.setTimeout((() => {
e(null)
}), n)
}))), s) return;
let i = !1;
try {
i = (yield e.getApi().captcha.captchaStatus()).is_pass
} catch (r) {
i = !1
}
i ? e.triggerSuccess() : t()
}))
}(), i.onclick = () => {
s = !0, e.cancel()
}, t
}
const Mt = {
request: (e, t) => e.getApi().captcha.captchaCheck(t),
body: e => e.get("iframe") ? Rt(e) : function(e) {
const t = y(
`<span><img class="atk-captcha-img" src="${e.get("img_data")||""}">${D("captchaCheck")}</span>`
);
return t.querySelector(".atk-captcha-img").onclick = () => {
const n = t.querySelector(".atk-captcha-img");
e.getApi().captcha.captchaGet().then((e => {
n.setAttribute("src", e)
})).catch((e => {
console.error("Failed to get captcha image ", e)
}))
}, t
}(e),
onSuccess(e, t, n, i) {
e.set("val", n)
},
onError(e, t, n, i) {
i.querySelector(".atk-captcha-img").click(), i.querySelector('input[type="text"]').value = ""
}
},
It = {
inputType: "password",
request(e, t) {
const n = {
name: e.getUser().getData().nick,
email: e.getUser().getData().email,
password: t
};
return (() => k(this, null, (function*() {
return (yield e.getApi().user.login(n.name, n.email, n.password)).token
})))()
},
body: e => y(`<span>${D("adminCheck")}</span>`),
onSuccess(e, t, n, i) {
e.getUser().update({
isAdmin: !0,
token: t
}), e.getOpts().onReload()
},
onError(e, t, n, i) {}
};
class Ut {
constructor(e) {
this.opts = e
}
checkCaptcha(e) {
this.fire(Mt, e, (t => {
t.set("img_data", e.imgData), t.set("iframe", e.iframe)
}))
}
checkAdmin(e) {
this.fire(It, e)
}
fire(e, t, n) {
const i = this.opts.getCtx().get("layerManager").create(`checker-${(new Date).getTime()}`);
i.show();
const s = {};
let r = !1;
const o = {
set: (e, t) => {
s[e] = t
},
get: e => s[e],
getOpts: () => this.opts,
getUser: () => this.opts.getCtx().get("user"),
getApi: () => this.opts.getApi(),
hideInteractInput: () => {
r = !0
},
triggerSuccess: () => {
this.close(e, i), e.onSuccess && e.onSuccess(o, "", "", a), t.onSuccess && t
.onSuccess("", d.$el)
},
cancel: () => {
this.close(e, i), t.onCancel && t.onCancel()
}
};
n && n(o);
const a = y();
a.appendChild(e.body(o));
const l = y(
`<input id="check" type="${e.inputType||"text"}" autocomplete="off" required placeholder="">`
);
let c;
a.appendChild(l), setTimeout((() => l.focus()), 80), l.onkeyup = e => {
"Enter" !== e.key && 13 !== e.keyCode || (e.preventDefault(), i.getEl().querySelector(
'button[data-action="confirm"]').click())
};
const d = new Et(a);
d.setYes((n => {
const s = l.value.trim();
c || (c = n.innerText);
const r = () => {
n.innerText = c || "", n.classList.remove("error")
};
return n.innerText = `${D("loading")}...`, e.request(o, s).then((n => {
this.close(e, i), e.onSuccess && e.onSuccess(o, n, s, a), t
.onSuccess && t.onSuccess(s, d.$el)
})).catch((t => {
var i;
i = String(t.msg || String(t)), n.innerText = i, n.classList
.add("error"), e.onError && e.onError(o, t, s, a);
const c = setTimeout((() => r()), 3e3);
l.onfocus = () => {
r(), clearTimeout(c)
}
})), !1
})), d.setNo((() => (this.close(e, i), t.onCancel && t.onCancel(), !1))), r && (l.style
.display = "none", d.$el.querySelector(".atk-layer-dialog-actions").style.display =
"none"), i.getEl().append(d.$el), t.onMount && t.onMount(d.$el)
}
close(e, t) {
t.destroy()
}
}
class Dt {
constructor(e) {
g(this, "$el"), g(this, "conf"), this.ctx = e, this.conf = e.conf
}
}
const Bt = {
$header: ".atk-header",
$nick: '.atk-header [name="nick"]',
$email: '.atk-header [name="email"]',
$link: '.atk-header [name="link"]',
$textareaWrap: ".atk-textarea-wrap",
$textarea: ".atk-textarea",
$bottom: ".atk-bottom",
$submitBtn: ".atk-send-btn",
$notifyWrap: ".atk-notify-wrap",
$plugBtnWrap: ".atk-plug-btn-wrap",
$plugPanelWrap: ".atk-plug-panel-wrap"
};
class qt {
constructor(e) {
this.kit = e
}
useBtn(e = "<div></div>") {
return this.$btn = y(`<span class="atk-plug-btn">${e}</span>`), this.$btn
}
usePanel(e = "<div></div>") {
return this.$panel = y(e), this.$panel
}
useContentTransformer(e) {
this.contentTransformer = e
}
usePanelShow(e) {
this.kit.useEvents().on("panel-show", (t => {
t === this && e()
}))
}
usePanelHide(e) {
this.kit.useEvents().on("panel-hide", (t => {
t === this && e()
}))
}
useEditorStateEffect(e, t) {
this.editorStateEffectWhen = e, this.editorStateEffect = t
}
}
class Ft extends qt {
constructor() {
super(...arguments), g(this, "isMoved", !1)
}
move(e) {
if (this.isMoved) return;
this.isMoved = !0;
const t = this.kit.useUI().$el;
t.after(y('<div class="atk-editor-travel-placeholder"></div>'));
const n = y("<div></div>");
e.after(n), n.replaceWith(t), t.classList.add("atk-fade-in"), t.classList.add(
"editor-traveling")
}
back() {
var e;
this.isMoved && (this.isMoved = !1, null == (e = this.kit.useGlobalCtx().$root.querySelector(
".atk-editor-travel-placeholder")) || e.replaceWith(this.kit.useUI().$el), this.kit
.useUI().$el.classList.remove("editor-traveling"))
}
}
class zt {
constructor(e) {
g(this, "stateCurt", "normal"), g(this, "stateUnmountFn", null), this.editor = e
}
get() {
return this.stateCurt
}
switch (e, t) {
var n, i, s, r, o;
if (this.stateUnmountFn && (this.stateUnmountFn(), this.stateUnmountFn = null, null == (i = null ==
(n = this.editor.getPlugs()) ? void 0 : n.get(Ft)) || i.back()), "normal" !== e && t) {
let n = t.$comment;
this.editor.conf.flatMode || (n = n.querySelector(".atk-footer")), null == (r = null == (s =
this.editor.getPlugs()) ? void 0 : s.get(Ft)) || r.move(n);
const i = this.editor.ctx.conf.scrollRelativeTo && this.editor.ctx.conf.scrollRelativeTo();
At(this.editor.getUI().$el, !0, i);
const a = null == (o = this.editor.getPlugs()) ? void 0 : o.getPlugs().find((t => t
.editorStateEffectWhen === e));
a && a.editorStateEffect && (this.stateUnmountFn = a.editorStateEffect(t.comment))
}
this.stateCurt = e
}
}
class Wt extends Dt {
constructor(e) {
super(e), g(this, "ui"), g(this, "state"), this.ui = function() {
const e = y(
'<div class="atk-main-editor">\n <div class="atk-header">\n <input name="nick" class="atk-nick" 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-plug-btn-wrap"></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'
),
t = {
$el: e
};
return Object.entries(Bt).forEach((([n, i]) => {
t[n] = e.querySelector(i)
})), t
}(), this.$el = this.ui.$el, this.state = new zt(this)
}
getUI() {
return this.ui
}
getPlugs() {
return this.ctx.get("editorPlugs")
}
getState() {
return this.state.get()
}
getHeaderInputEls() {
return {
nick: this.ui.$nick,
email: this.ui.$email,
link: this.ui.$link
}
}
getContentFinal() {
let e = this.getContentRaw();
const t = this.getPlugs();
return t && (e = t.getTransformedContent(e)), e
}
getContentRaw() {
return this.ui.$textarea.value || ""
}
getContentMarked() {
return yt(this.getContentFinal())
}
setContent(e) {
var t;
this.ui.$textarea.value = e, null == (t = this.getPlugs()) || t.getEvents().trigger(
"content-updated", e)
}
insertContent(e) {
if (document.selection) this.ui.$textarea.focus(), document.selection.createRange().text = e,
this.ui.$textarea.focus();
else if (this.ui.$textarea.selectionStart || 0 === this.ui.$textarea.selectionStart) {
const t = this.ui.$textarea.selectionStart,
n = this.ui.$textarea.selectionEnd,
i = this.ui.$textarea.scrollTop;
this.setContent(this.ui.$textarea.value.substring(0, t) + e + this.ui.$textarea.value
.substring(n, this.ui.$textarea.value.length)), this.ui.$textarea.focus(), this.ui
.$textarea.selectionStart = t + e.length, this.ui.$textarea.selectionEnd = t + e.length,
this.ui.$textarea.scrollTop = i
} else this.ui.$textarea.focus(), this.ui.$textarea.value += e
}
focus() {
this.ui.$textarea.focus()
}
reset() {
this.setContent(""), this.resetState()
}
resetState() {
this.state.switch("normal")
}
setReply(e, t) {
this.state.switch("reply", {
comment: e,
$comment: t
})
}
setEditComment(e, t) {
this.state.switch("edit", {
comment: e,
$comment: t
})
}
showNotify(e, t) {
! function(e, t, n) {
const i = y(
`<div class="atk-notify atk-fade-in" style="background-color: ${{s:"#57d59f",e:"#ff6f6c",w:"#ffc721",i:"#2ebcfc"}[n]}"><span class="atk-notify-content"></span></div>`
);
i.querySelector(".atk-notify-content").innerHTML = $(t).replace("\n", "<br/>"), e
.appendChild(i);
const s = () => {
i.classList.add("atk-fade-out"), setTimeout((() => {
i.remove()
}), 200)
};
let r;
r = window.setTimeout((() => {
s()
}), 3e3), i.addEventListener("click", (() => {
s(), window.clearTimeout(r)
}))
}(this.ui.$notifyWrap, e, t)
}
showLoading() {
Tt(this.ui.$el)
}
hideLoading() {
_t(this.ui.$el)
}
submit() {
this.ctx.trigger("editor-submit")
}
}
class jt extends Dt {
constructor(e) {
super(e), g(this, "layer"), g(this, "$header"), g(this, "$closeBtn"), g(this, "$iframeWrap"), g(
this, "$iframe"), g(this, "firstShow", !0), this.$el = y(
'<div class="atk-sidebar-layer">\n <div class="atk-sidebar-inner">\n <div class="atk-sidebar-header">\n <div class="atk-sidebar-close"><i class="atk-icon atk-icon-close"></i></div>\n </div>\n <div class="atk-sidebar-iframe-wrap"></div>\n </div>\n</div>\n'
), this.$header = this.$el.querySelector(".atk-sidebar-header"), this.$closeBtn = this
.$header.querySelector(".atk-sidebar-close"), this.$iframeWrap = this.$el.querySelector(
".atk-sidebar-iframe-wrap"), this.$closeBtn.onclick = () => {
this.hide()
}, this.ctx.on("user-changed", (() => {
this.firstShow = !0
}))
}
show() {
return k(this, arguments, (function*(e = {}) {
if (this.$el.style.transform = "", this.initLayer(), this.layer.show(), this
.authCheck({
onSuccess: () => this.show(e)
}), this.firstShow) this.$iframeWrap.innerHTML = "", this.$iframe = this
.createIframe(e.view), this.$iframeWrap.append(this.$iframe), this
.firstShow = !1;
else {
const e = this.$iframe,
t = e.src.includes("darkMode=1");
this.conf.darkMode && !t && this.iframeLoad(e,
`${this.$iframe.src}&darkMode=1`), !this.conf.darkMode && t && this
.iframeLoad(e, this.$iframe.src.replace("&darkMode=1", ""))
}
setTimeout((() => {
this.$el.style.transform = "translate(0, 0)"
}), 100), setTimeout((() => {
this.ctx.getData().updateUnreads([])
}), 0), this.ctx.trigger("sidebar-show")
}))
}
hide() {
var e;
this.$el.style.transform = "", null == (e = this.layer) || e.hide(), this.ctx.trigger(
"sidebar-hide")
}
authCheck(e) {
return k(this, null, (function*() {
const t = yield this.ctx.getApi().user.loginStatus();
t.is_admin && !t.is_login && (this.firstShow = !0, this.ctx.checkAdmin({
onSuccess: () => {
setTimeout((() => {
e.onSuccess()
}), 500)
},
onCancel: () => {
this.hide()
}
}))
}))
}
initLayer() {
this.layer || (this.layer = this.ctx.get("layerManager").create("sidebar", this.$el), this.layer
.setOnAfterHide((() => {
this.ctx.editorResetState()
})))
}
createIframe(e) {
const t = y('<iframe referrerpolicy="strict-origin-when-cross-origin"></iframe>'),
n = T({
base: this.ctx.conf.server,
path: "/sidebar/"
}),
i = {
pageKey: this.conf.pageKey,
site: this.conf.site || "",
user: JSON.stringify(this.ctx.get("user").getData()),
time: +new Date
};
e && (i.view = e), this.conf.darkMode && (i.darkMode = "1"), "string" == typeof this.conf
.locale && (i.locale = this.conf.locale);
const s = new URLSearchParams(i);
return this.iframeLoad(t, `${n}?${s.toString()}`), t
}
iframeLoad(e, t) {
e.src = t, Tt(this.$iframeWrap), e.onload = () => {
_t(this.$iframeWrap)
}
}
}
class Nt {
constructor(e) {
this.options = e
}
import(e) {
this.options.flatMode ? e.forEach((t => {
this.putCommentFlatMode(t, e, "append")
})) : this.importCommentsNestMode(e)
}
insert(e) {
this.options.flatMode ? this.insertCommentFlatMode(e) : this.insertCommentNest(e)
}
importCommentsNestMode(e) {
const t = function(e, t = "DATE_DESC", n = 2) {
const i = [];
e.filter((e => 0 === e.rid)).forEach((t => {
const s = {
id: t.id,
comment: t,
children: [],
level: 1
};
s.parent = s, i.push(s),
function t(i) {
const s = e.filter((e => e.rid === i.id));
0 !== s.length && (i.level >= n && (i = i.parent), s.forEach((
e => {
const n = {
id: e.id,
comment: e,
children: [],
parent: i,
level: i.level + 1
};
i.children.push(n), t(n)
})))
}(s)
}));
const s = (n, i) => {
let s = n.id - i.id;
return "DATE_ASC" === t ? s = +new Date(n.comment.date) - +new Date(i.comment
.date) : "DATE_DESC" === t ? s = +new Date(i.comment.date) - +new Date(n
.comment.date) : "SRC_INDEX" === t ? s = e.indexOf(n.comment) - e
.indexOf(i.comment) : "VOTE_UP_DESC" === t && (s = i.comment.vote_up - n
.comment.vote_up), s
};
return function e(t) {
t.forEach((t => {
t.children = t.children.sort(s), e(t.children)
}))
}(i), i
}(e, this.options.nestSortBy, this.options.nestMax);
t.forEach((t => {
var n;
const i = this.options.createCommentNode(t.comment, e);
null == (n = this.options.$commentsWrap) || n.appendChild(i.getEl()), i
.getRender().playFadeAnim();
const s = (t, n) => {
n.children.forEach((n => {
const i = n.comment,
r = this.options.createCommentNode(i, e);
t.putChild(r), s(r, n)
}))
};
s(i, t), i.getRender().checkHeightLimit()
}))
}
putCommentFlatMode(e, t, n) {
var i, s;
e.is_collapsed && (e.is_allow_reply = !1);
const r = this.options.createCommentNode(e, t);
return e.visible && ("append" === n && (null == (i = this.options.$commentsWrap) || i.append(r
.getEl())), "prepend" === n && (null == (s = this.options.$commentsWrap) || s
.prepend(r.getEl())), r.getRender().playFadeAnim()), r.getRender().checkHeightLimit(), r
}
insertCommentNest(e) {
var t;
const n = this.options.createCommentNode(e, this.options.getCommentDataList());
if (0 === e.rid) null == (t = this.options.$commentsWrap) || t.prepend(n.getEl());
else {
const t = this.options.findCommentNode(e.rid);
t && (t.putChild(n, "DATE_ASC" === this.options.nestSortBy ? "append" : "prepend"), n
.getParents().forEach((e => {
e.getRender().heightLimitRemoveForChildren()
})))
}
n.getRender().checkHeightLimit(), At(n.getEl()), n.getRender().playFadeAnim()
}
insertCommentFlatMode(e) {
At(this.putCommentFlatMode(e, this.options.getCommentDataList(), "prepend").getEl())
}
}
function Ht(e, t) {
t.forEach((({
el: t,
max: n,
imgContains: i
}) => {
const s = () => {
t && (e.scrollable ? function(e) {
if (!e.el) return;
if (e.el.classList.contains(Gt)) return;
e.el.classList.add(Gt), e.el.style.height = `${e.maxHeight}px`
}({
el: t,
maxHeight: n
}) : function(e) {
if (!e.el) return;
if (!e.maxHeight) return;
if (e.el.classList.contains(Qt)) return;
e.el.classList.add(Qt), e.el.style.height = `${e.maxHeight}px`, e.el
.style.overflow = "hidden";
const t = y(
`<div class="atk-height-limit-btn">${D("readMore")}</span>`);
t.onclick = t => {
t.stopPropagation(), Vt(e.el), e.postBtnClick && e
.postBtnClick(t)
}, e.el.append(t)
}({
el: t,
maxHeight: n,
postBtnClick: e.postExpandBtnClick
}))
},
r = () => {
t && v(t) > n && s()
};
r(), i && t && function(e, t) {
if (!e) return;
const n = e.getElementsByTagName("img");
if (!n.length) return;
let i = n.length;
for (let s = 0; s < n.length; s++) n[s].complete ? i-- : n[s].addEventListener(
"load", (() => {
i--, 0 === i && t()
})), 0 === i && t()
}(t, (() => r()))
}))
}
const Qt = "atk-height-limit";
function Vt(e) {
e && e.classList.contains(Qt) && (e.classList.remove(Qt), Array.from(e.children).forEach((e => {
e.classList.contains("atk-height-limit-btn") && e.remove()
})), e.style.height = "", e.style.overflow = "")
}
const Gt = "atk-height-limit-scroll";
function Kt(e) {
if (e.$headerNick = e.$el.querySelector(".atk-nick"), e.data.link) {
const t = y('<a target="_blank" rel="noreferrer noopener nofollow"></a>');
t.innerText = e.data.nick, t.href = E(e.data.link) ? e.data.link : `https://${e.data.link}`, e
.$headerNick.append(t)
} else e.$headerNick.innerText = e.data.nick
}
function Zt(e) {
e.$headerBadgeWrap = e.$el.querySelector(".atk-badge-wrap"), e.$headerBadgeWrap.innerHTML = "";
const t = e.data.badge_name,
n = e.data.badge_color;
if (t) {
const i = y('<span class="atk-badge"></span>');
i.innerText = t.replace("管理员", e.ctx.$t("admin")), i.style.backgroundColor = n || "", e
.$headerBadgeWrap.append(i)
}
if (e.data.is_pinned) {
const t = y(`<span class="atk-pinned-badge">${e.ctx.$t("pin")}</span>`);
e.$headerBadgeWrap.append(t)
}
}
function Yt(e) {
const t = e.$el.querySelector(".atk-date");
t.innerText = e.comment.getDateFormatted(), t.setAttribute("data-atk-comment-date", String(+new Date(e
.data.date)))
}
function Xt(e) {
if (!e.ctx.conf.uaBadge && !e.data.ip_region) return;
let t = e.$header.querySelector("atk-ua-wrap");
if (t || (t = y('<span class="atk-ua-wrap"></span>'), e.$header.append(t)), t.innerHTML = "", e.data
.ip_region) {
const n = y('<span class="atk-region-badge"></span>');
n.innerText = e.data.ip_region, t.append(n)
}
if (e.ctx.conf.uaBadge) {
const {
browser: n,
os: i
} = e.comment.getUserUA();
if (String(n).trim()) {
const e = y('<span class="atk-ua ua-browser"></span>');
e.innerText = n, t.append(e)
}
if (String(i).trim()) {
const e = y('<span class="atk-ua ua-os"></span>');
e.innerText = i, t.append(e)
}
}
}
class Jt {
constructor(e) {
g(this, "opts"), g(this, "$el"), g(this, "isLoading", !1), g(this, "msgRecTimer"), g(this,
"msgRecTimerFunc"), g(this, "isConfirming", !1), g(this, "confirmRecTimer"), this.$el =
y('<span class="atk-common-action-btn"></span>'), this.opts = "object" != typeof e ? {
text: e
} : e, this.$el.innerText = this.getText(), this.opts.adminOnly && this.$el.setAttribute(
"atk-only-admin-show", "")
}
get isMessaging() {
return !!this.msgRecTimer
}
appendTo(e) {
return e.append(this.$el), this
}
getText() {
return "string" == typeof this.opts.text ? this.opts.text : this.opts.text()
}
setClick(e) {
this.$el.onclick = t => {
if (t.stopPropagation(), !this.isLoading) {
if (this.opts.confirm && !this.isMessaging) {
const e = () => {
this.isConfirming = !1, this.$el.classList.remove("atk-btn-confirm"),
this.$el.innerText = this.getText()
};
if (!this.isConfirming) return this.isConfirming = !0, this.$el.classList.add(
"atk-btn-confirm"), this.$el.innerText = this.opts.confirmText || D(
"actionConfirm"), void(this.confirmRecTimer = window.setTimeout((
() => e()), 5e3));
this.confirmRecTimer && window.clearTimeout(this.confirmRecTimer), e()
}
if (this.msgRecTimer) return this.fireMsgRecTimer(), void this.clearMsgRecTimer();
e()
}
}
}
updateText(e) {
e && (this.opts.text = e), this.setLoading(!1), this.$el.innerText = this.getText()
}
setLoading(e, t) {
this.isLoading !== e && (this.isLoading = e, e ? (this.$el.classList.add("atk-btn-loading"),
this.$el.innerText = t || `${D("loading")}...`) : (this.$el.classList.remove(
"atk-btn-loading"), this.$el.innerText = this.getText()))
}
setError(e) {
this.setMsg(e, "atk-btn-error")
}
setWarn(e) {
this.setMsg(e, "atk-btn-warn")
}
setSuccess(e) {
this.setMsg(e, "atk-btn-success")
}
setMsg(e, t, n, i) {
this.setLoading(!1), t && this.$el.classList.add(t), this.$el.innerText = e, this
.setMsgRecTimer((() => {
this.$el.innerText = this.getText(), t && this.$el.classList.remove(t), i && i()
}), n || 2500)
}
setMsgRecTimer(e, t) {
this.fireMsgRecTimer(), this.clearMsgRecTimer(), this.msgRecTimerFunc = e, this.msgRecTimer =
window.setTimeout((() => {
e(), this.clearMsgRecTimer()
}), t)
}
fireMsgRecTimer() {
this.msgRecTimerFunc && this.msgRecTimerFunc()
}
clearMsgRecTimer() {
this.msgRecTimer && window.clearTimeout(this.msgRecTimer), this.msgRecTimer = void 0, this
.msgRecTimerFunc = void 0
}
}
function en(e) {
e.ctx.conf.vote && (e.voteBtnUp = new Jt((() => `${e.ctx.$t("voteUp")} (${e.data.vote_up||0})`))
.appendTo(e.$actions), e.voteBtnUp.setClick((() => {
e.comment.getActions().vote("up")
})), e.ctx.conf.voteDown && (e.voteBtnDown = new Jt((() =>
`${e.ctx.$t("voteDown")} (${e.data.vote_down||0})`)).appendTo(e.$actions), e.voteBtnDown
.setClick((() => {
e.comment.getActions().vote("down")
}))))
}
function tn(e) {
if (!e.data.is_allow_reply) return;
const t = y(`<span>${e.ctx.$t("reply")}</span>`);
e.$actions.append(t), t.addEventListener("click", (t => {
t.stopPropagation(), e.cConf.onReplyBtnClick ? e.cConf.onReplyBtnClick() : e.ctx
.replyComment(e.data, e.$el)
}))
}
function nn(e) {
const t = new Jt({
text: () => e.data.is_collapsed ? e.ctx.$t("expand") : e.ctx.$t("collapse"),
adminOnly: !0
});
t.appendTo(e.$actions), t.setClick((() => {
e.comment.getActions().adminEdit("collapsed", t)
}))
}
function sn(e) {
const t = new Jt({
text: () => e.data.is_pending ? e.ctx.$t("pending") : e.ctx.$t("approved"),
adminOnly: !0
});
t.appendTo(e.$actions), t.setClick((() => {
e.comment.getActions().adminEdit("pending", t)
}))
}
function rn(e) {
const t = new Jt({
text: () => e.data.is_pinned ? e.ctx.$t("unpin") : e.ctx.$t("pin"),
adminOnly: !0
});
t.appendTo(e.$actions), t.setClick((() => {
e.comment.getActions().adminEdit("pinned", t)
}))
}
function on(e) {
const t = new Jt({
text: e.ctx.$t("edit"),
adminOnly: !0
});
t.appendTo(e.$actions), t.setClick((() => {
e.ctx.editComment(e.data, e.$el)
}))
}
function an(e) {
const t = new Jt({
text: e.ctx.$t("delete"),
confirm: !0,
confirmText: e.ctx.$t("deleteConfirm"),
adminOnly: !0
});
t.appendTo(e.$actions), t.setClick((() => {
e.comment.getActions().adminDelete(t)
}))
}
const ln = {
Avatar: function(e) {
const t = e.$el.querySelector(".atk-avatar"),
n = y("<img />"),
i = e.conf.avatarURLBuilder;
if (n.src = i ? i(e.data) : e.comment.getGravatarURL(), e.data.link) {
const i = y('<a target="_blank" rel="noreferrer noopener nofollow"></a>');
i.href = E(e.data.link) ? e.data.link : `https://${e.data.link}`, i.append(n), t.append(
i)
} else t.append(n)
},
Header: function(e) {
Object.entries({
renderNick: Kt,
renderVerifyBadge: Zt,
renderDate: Yt,
renderUABadge: Xt
}).forEach((([t, n]) => {
n(e)
}))
},
Content: function(e) {
if (!e.data.is_collapsed) return e.$content.innerHTML = e.comment.getContentMarked(), void e
.$content.classList.remove("atk-hide", "atk-collapsed");
e.$content.classList.add("atk-hide", "atk-type-collapsed");
const t = y(
`\n <div class="atk-collapsed">\n <span class="atk-text">${e.ctx.$t("collapsedMsg")}</span>\n <span class="atk-show-btn">${e.ctx.$t("expand")}</span>\n </div>`
);
e.$body.insertAdjacentElement("beforeend", t);
const n = t.querySelector(".atk-show-btn");
n.addEventListener("click", (t => {
t.stopPropagation(), e.$content.classList.contains("atk-hide") ? (e.$content
.innerHTML = e.comment.getContentMarked(), e.$content.classList
.remove("atk-hide"), Ot(e.$content), n.innerText = e.ctx.$t(
"collapse")) : (e.$content.innerHTML = "", e.$content.classList
.add("atk-hide"), n.innerText = e.ctx.$t("expand"))
}))
},
ReplyAt: function(e) {
e.cConf.isFlatMode || 0 === e.data.rid || e.cConf.replyTo && (e.$replyAt = y(
'<span class="atk-item atk-reply-at"><span class="atk-arrow"></span><span class="atk-nick"></span></span>'
), e.$replyAt.querySelector(".atk-nick").innerText = `${e.cConf.replyTo.nick}`,
e.$replyAt.onclick = () => {
e.comment.getActions().goToReplyComment()
}, e.$headerBadgeWrap.insertAdjacentElement("afterend", e.$replyAt))
},
ReplyTo: function(e) {
if (!e.cConf.isFlatMode) return;
if (!e.cConf.replyTo) return;
e.$replyTo = y(
`\n <div class="atk-reply-to">\n <div class="atk-meta">${e.ctx.$t("reply")} <span class="atk-nick"></span>:</div>\n <div class="atk-content"></div>\n </div>`
);
const t = e.$replyTo.querySelector(".atk-nick");
t.innerText = `@${e.cConf.replyTo.nick}`, t.onclick = () => {
e.comment.getActions().goToReplyComment()
};
let n = yt(e.cConf.replyTo.content);
e.cConf.replyTo.is_collapsed && (n = `[${$(e.ctx.$t("collapsed"))}]`), e.$replyTo
.querySelector(".atk-content").innerHTML = n, e.$body.prepend(e.$replyTo)
},
Pending: function(e) {
if (!e.data.is_pending) return;
const t = y(`<div class="atk-pending">${e.ctx.$t("pendingMsg")}</div>`);
e.$body.prepend(t)
},
Actions: function(e) {
Object.entries({
renderVote: en,
renderReply: tn,
renderCollapse: nn,
renderModerator: sn,
renderPin: rn,
renderEdit: on,
renderDel: an
}).forEach((([t, n]) => {
n(e)
}))
}
};
class cn {
constructor(e) {
g(this, "comment"), g(this, "$el"), g(this, "$main"), g(this, "$header"), g(this,
"$headerNick"), g(this, "$headerBadgeWrap"), g(this, "$body"), g(this, "$content"), g(this,
"$childrenWrap"), g(this, "$actions"), g(this, "voteBtnUp"), g(this, "voteBtnDown"), g(
this, "$replyTo"), g(this, "$replyAt"), this.comment = e
}
get ctx() {
return this.comment.ctx
}
get data() {
return this.comment.getData()
}
get conf() {
return this.comment.conf
}
get cConf() {
return this.comment.getConf()
}
render() {
var e;
return this.$el = y(
'<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'
), this.$main = this.$el.querySelector(".atk-main"), this.$header = this.$el
.querySelector(".atk-header"), this.$body = this.$el.querySelector(".atk-body"), this
.$content = this.$body.querySelector(".atk-content"), this.$actions = this.$el
.querySelector(".atk-actions"), this.$el.setAttribute("id", `atk-comment-${this.data.id}`),
e = this, Object.entries(ln).forEach((([t, n]) => {
n(e)
})), this.recoveryChildrenWrap(), this.$el
}
checkHeightLimit() {
const e = this.ctx.conf.heightLimit;
if (!e || !e.content || !e.children) return;
const t = e.content,
n = e.children;
Ht({
postExpandBtnClick: () => {
const e = this.comment.getChildren();
1 === e.length && Vt(e[0].getRender().$content)
},
scrollable: e.scrollable
}, [{
el: this.$content,
max: t,
imgContains: !0
}, {
el: this.$replyTo,
max: t,
imgContains: !0
}, {
el: this.$childrenWrap,
max: n,
imgContains: !1
}])
}
heightLimitRemoveForChildren() {
this.$childrenWrap && Vt(this.$childrenWrap)
}
playFadeAnim() {
Ot(this.comment.getRender().$el)
}
playFadeAnimForBody() {
Ot(this.comment.getRender().$body)
}
getChildrenWrap() {
return this.$childrenWrap
}
renderChildrenWrap() {
return this.$childrenWrap || (this.$childrenWrap = y(
'<div class="atk-comment-children"></div>'), this.$main.append(this.$childrenWrap)),
this.$childrenWrap
}
recoveryChildrenWrap() {
this.$childrenWrap && this.$main.append(this.$childrenWrap)
}
setUnread(e) {
e ? this.$el.classList.add("atk-unread") : this.$el.classList.remove("atk-unread")
}
setOpenable(e) {
e ? this.$el.classList.add("atk-openable") : this.$el.classList.remove("atk-openable")
}
setOpenURL(e) {
this.setOpenable(!0), this.$el.onclick = t => {
t.preventDefault(), window.open(e), this.cConf.openEvt && this.cConf.openEvt()
}
}
setOpenAction(e) {
this.setOpenable(!0), this.$el.onclick = t => {
t.preventDefault(), e()
}
}
}
class dn {
constructor(e) {
g(this, "comment"), this.comment = e
}
get ctx() {
return this.comment.ctx
}
get data() {
return this.comment.getData()
}
get cConf() {
return this.comment.getConf()
}
vote(e) {
const t = "up" === e ? this.comment.getRender().voteBtnUp : this.comment.getRender()
.voteBtnDown;
this.ctx.getApi().comment.vote(this.data.id, `comment_${e}`).then((e => {
var t, n;
this.data.vote_up = e.up, this.data.vote_down = e.down, null == (t = this
.comment.getRender().voteBtnUp) || t.updateText(), null == (n = this
.comment.getRender().voteBtnDown) || n.updateText()
})).catch((e => {
null == t || t.setError(this.ctx.$t("voteFail")), console.log(e)
}))
}
adminEdit(e, t) {
if (t.isLoading) return;
t.setLoading(!0, `${this.ctx.$t("editing")}...`);
const n = u({}, this.data);
"collapsed" === e ? n.is_collapsed = !n.is_collapsed : "pending" === e ? n.is_pending = !n
.is_pending : "pinned" === e && (n.is_pinned = !n.is_pinned), this.ctx.getApi().comment
.commentEdit(n).then((e => {
t.setLoading(!1), this.comment.setData(e)
})).catch((e => {
console.error(e), t.setError(this.ctx.$t("editFail"))
}))
}
adminDelete(e) {
e.isLoading || (e.setLoading(!0, `${this.ctx.$t("deleting")}...`), this.ctx.getApi().comment
.commentDel(this.data.id, this.data.site_name).then((() => {
e.setLoading(!1), this.cConf.onDelete && this.cConf.onDelete(this.comment)
})).catch((t => {
console.error(t), e.setError(this.ctx.$t("deleteFail"))
})))
}
goToReplyComment() {
const e = window.location.hash,
t = `#atk-comment-${this.data.rid}`;
window.location.hash = t, t === e && window.dispatchEvent(new Event("hashchange"))
}
}
class hn extends Dt {
constructor(e, t, n) {
super(e), g(this, "renderInstance"), g(this, "actionInstance"), g(this, "data"), g(this,
"cConf"), g(this, "parent"), g(this, "children", []), g(this, "nestCurt"), g(this,
"nestMax"), this.nestMax = e.conf.nestMax || 3, this.cConf = n, this.data = u({}, t),
this.data.date = this.data.date.replace(/-/g, "/"), this.parent = null, this.nestCurt = 1,
this.actionInstance = new dn(this), this.renderInstance = new cn(this)
}
render() {
const e = this.renderInstance.render();
this.$el && this.$el.replaceWith(e), this.$el = e, this.cConf.afterRender && this.cConf
.afterRender()
}
getActions() {
return this.actionInstance
}
getRender() {
return this.renderInstance
}
getData() {
return this.data
}
setData(e) {
this.data = e, this.render(), this.getRender().playFadeAnimForBody()
}
getParent() {
return this.parent
}
getChildren() {
return this.children
}
getNestCurt() {
return this.nestCurt
}
getIsRoot() {
return 0 === this.data.rid
}
getID() {
return this.data.id
}
putChild(e, t = "append") {
e.parent = this, e.nestCurt = this.nestCurt + 1, this.children.push(e);
const n = this.getChildrenEl();
"append" === t ? n.append(e.getEl()) : "prepend" === t && n.prepend(e.getEl()), e.getRender()
.playFadeAnim(), e.getRender().checkHeightLimit()
}
getChildrenEl() {
let e = this.getRender().getChildrenWrap();
return e || (e = this.nestCurt < this.nestMax ? this.getRender().renderChildrenWrap() : this
.parent.getChildrenEl()), e
}
getParents() {
const e = [],
t = n => {
n.parent && (e.push(n.parent), t(n.parent))
};
return t(this), e
}
getEl() {
return this.$el
}
getGravatarURL() {
return `${(e={mirror:this.ctx.conf.gravatar.mirror,params:this.ctx.conf.gravatar.params,emailMD5:this.data.email_encrypted}).mirror.replace(/\/$/,"")}/${e.emailMD5}?${e.params.replace(/^\?/,"")}`;
var e
}
getContentMarked() {
return yt(this.data.content)
}
getDateFormatted() {
return C(new Date(this.data.date), this.ctx.$t)
}
getUserUA() {
const e = function(e) {
const t = window || {},
n = navigator || {},
i = String(e || n.userAgent),
s = {
os: "",
osVersion: "",
engine: "",
browser: "",
device: "",
language: "",
version: ""
},
r = {
Trident: i.includes("Trident") || i.includes("NET CLR"),
Presto: i.includes("Presto"),
WebKit: i.includes("AppleWebKit"),
Gecko: i.includes("Gecko/")
},
o = {
Safari: i.includes("Safari"),
Chrome: i.includes("Chrome") || i.includes("CriOS"),
IE: i.includes("MSIE") || i.includes("Trident"),
Edge: i.includes("Edge") || i.includes("Edg"),
Firefox: i.includes("Firefox") || i.includes("FxiOS"),
"Firefox Focus": i.includes("Focus"),
Chromium: i.includes("Chromium"),
Opera: i.includes("Opera") || i.includes("OPR"),
Vivaldi: i.includes("Vivaldi"),
Yandex: i.includes("YaBrowser"),
Kindle: i.includes("Kindle") || i.includes("Silk/"),
360: i.includes("360EE") || i.includes("360SE"),
UC: i.includes("UC") || i.includes(" UBrowser"),
QQBrowser: i.includes("QQBrowser"),
QQ: i.includes("QQ/"),
Baidu: i.includes("Baidu") || i.includes("BIDUBrowser"),
Maxthon: i.includes("Maxthon"),
Sogou: i.includes("MetaSr") || i.includes("Sogou"),
LBBROWSER: i.includes("LBBROWSER"),
"2345Explorer": i.includes("2345Explorer"),
TheWorld: i.includes("TheWorld"),
MIUI: i.includes("MiuiBrowser"),
Quark: i.includes("Quark"),
Qiyu: i.includes("Qiyu"),
Wechat: i.includes("MicroMessenger"),
Taobao: i.includes("AliApp(TB"),
Alipay: i.includes("AliApp(AP"),
Weibo: i.includes("Weibo"),
Douban: i.includes("com.douban.frodo"),
Suning: i.includes("SNEBUY-APP"),
iQiYi: i.includes("IqiyiApp")
},
a = {
Windows: i.includes("Windows"),
Linux: i.includes("Linux") || i.includes("X11"),
macOS: i.includes("Macintosh"),
Android: i.includes("Android") || i.includes("Adr"),
Ubuntu: i.includes("Ubuntu"),
FreeBSD: i.includes("FreeBSD"),
Debian: i.includes("Debian"),
"Windows Phone": i.includes("IEMobile") || i.includes("Windows Phone"),
BlackBerry: i.includes("BlackBerry") || i.includes("RIM"),
MeeGo: i.includes("MeeGo"),
Symbian: i.includes("Symbian"),
iOS: i.includes("like Mac OS X"),
"Chrome OS": i.includes("CrOS"),
WebOS: i.includes("hpwOS")
},
l = {
Mobile: i.includes("Mobi") || i.includes("iPh") || i.includes("480"),
Tablet: i.includes("Tablet") || i.includes("Pad") || i.includes("Nexus 7")
};
l.Mobile ? l.Mobile = !i.includes("iPad") : o.Chrome && i.includes("Edg") ? (o
.Chrome = !1, o.Edge = !0) : t.showModalDialog && t.chrome && (o.Chrome = !1, o[
360] = !0), s.device = "PC", s.language = (() => {
const e = (n.browserLanguage || n.language).split("-");
return e[1] && (e[1] = e[1].toUpperCase()), e.join("_")
})();
const c = {
engine: r,
browser: o,
os: a,
device: l
};
Object.entries(c).forEach((([e, t]) => {
Object.entries(t).forEach((([t, n]) => {
!0 === n && (s[e] = t)
}))
}));
const d = {
Windows: () => {
const e = i.replace(/^.*Windows NT ([\d.]+);.*$/, "$1");
return {
6.4: "10",
6.3: "8.1",
6.2: "8",
6.1: "7",
"6.0": "Vista",
5.2: "XP",
5.1: "XP",
"5.0": "2000",
"10.0": "10",
"11.0": "11"
} [e] || e
},
Android: () => i.replace(/^.*Android ([\d.]+);.*$/, "$1"),
iOS: () => i.replace(/^.*OS ([\d_]+) like.*$/, "$1").replace(/_/g, "."),
Debian: () => i.replace(/^.*Debian\/([\d.]+).*$/, "$1"),
"Windows Phone": () => i.replace(/^.*Windows Phone( OS)? ([\d.]+);.*$/, "$2"),
macOS: () => i.replace(/^.*Mac OS X ([\d_]+).*$/, "$1").replace(/_/g, "."),
WebOS: () => i.replace(/^.*hpwOS\/([\d.]+);.*$/, "$1")
};
s.osVersion = "", d[s.os] && (s.osVersion = d[s.os](), s.osVersion === i && (s
.osVersion = ""));
const h = {
Safari: () => i.replace(/^.*Version\/([\d.]+).*$/, "$1"),
Chrome: () => i.replace(/^.*Chrome\/([\d.]+).*$/, "$1").replace(
/^.*CriOS\/([\d.]+).*$/, "$1"),
IE: () => i.replace(/^.*MSIE ([\d.]+).*$/, "$1").replace(/^.*rv:([\d.]+).*$/,
"$1"),
Edge: () => i.replace(/^.*(Edge|Edg|Edg[A-Z]{1})\/([\d.]+).*$/, "$2"),
Firefox: () => i.replace(/^.*Firefox\/([\d.]+).*$/, "$1").replace(
/^.*FxiOS\/([\d.]+).*$/, "$1"),
"Firefox Focus": () => i.replace(/^.*Focus\/([\d.]+).*$/, "$1"),
Chromium: () => i.replace(/^.*Chromium\/([\d.]+).*$/, "$1"),
Opera: () => i.replace(/^.*Opera\/([\d.]+).*$/, "$1").replace(
/^.*OPR\/([\d.]+).*$/, "$1"),
Vivaldi: () => i.replace(/^.*Vivaldi\/([\d.]+).*$/, "$1"),
Yandex: () => i.replace(/^.*YaBrowser\/([\d.]+).*$/, "$1"),
Kindle: () => i.replace(/^.*Version\/([\d.]+).*$/, "$1"),
Maxthon: () => i.replace(/^.*Maxthon\/([\d.]+).*$/, "$1"),
QQBrowser: () => i.replace(/^.*QQBrowser\/([\d.]+).*$/, "$1"),
QQ: () => i.replace(/^.*QQ\/([\d.]+).*$/, "$1"),
Baidu: () => i.replace(/^.*BIDUBrowser[\s/]([\d.]+).*$/, "$1"),
UC: () => i.replace(/^.*UC?Browser\/([\d.]+).*$/, "$1"),
Sogou: () => i.replace(/^.*SE ([\d.X]+).*$/, "$1").replace(
/^.*SogouMobileBrowser\/([\d.]+).*$/, "$1"),
"2345Explorer": () => i.replace(/^.*2345Explorer\/([\d.]+).*$/, "$1"),
TheWorld: () => i.replace(/^.*TheWorld ([\d.]+).*$/, "$1"),
MIUI: () => i.replace(/^.*MiuiBrowser\/([\d.]+).*$/, "$1"),
Quark: () => i.replace(/^.*Quark\/([\d.]+).*$/, "$1"),
Qiyu: () => i.replace(/^.*Qiyu\/([\d.]+).*$/, "$1"),
Wechat: () => i.replace(/^.*MicroMessenger\/([\d.]+).*$/, "$1"),
Taobao: () => i.replace(/^.*AliApp\(TB\/([\d.]+).*$/, "$1"),
Alipay: () => i.replace(/^.*AliApp\(AP\/([\d.]+).*$/, "$1"),
Weibo: () => i.replace(/^.*weibo__([\d.]+).*$/, "$1"),
Douban: () => i.replace(/^.*com.douban.frodo\/([\d.]+).*$/, "$1"),
Suning: () => i.replace(/^.*SNEBUY-APP([\d.]+).*$/, "$1"),
iQiYi: () => i.replace(/^.*IqiyiVersion\/([\d.]+).*$/, "$1")
};
return s.version = "", h[s.browser] && (s.version = h[s.browser](), s.version === i && (
s.version = "")), s.version.indexOf(".") && (s.version = s.version.substring(0,
s.version.indexOf("."))), "iOS" === s.os && i.includes("iPad") ? s.os =
"iPadOS" : "Edge" !== s.browser || i.includes("Edg") ? "MIUI" === s.browser ? s.os =
"Android" : "Chrome" === s.browser && Number(s.version) > 27 || "Opera" === s
.browser && Number(s.version) > 12 || "Yandex" === s.browser ? s.engine = "Blink" :
void 0 === s.browser && (s.browser = "Unknow App") : s.engine = "EdgeHTML", s
}(this.data.ua);
return {
browser: `${e.browser} ${e.version}`,
os: `${e.os} ${e.osVersion}`
}
}
getConf() {
return this.cConf
}
}
class un {
constructor(e) {
g(this, "opts"), g(this, "$el"), g(this, "$loading"), g(this, "$text"), g(this, "offset", 0), g(
this, "total", 0), g(this, "origText", "Load More"), this.opts = e, this.origText = this
.opts.text || this.origText, this.$el = y(
`<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>`
), this.$loading = this.$el.querySelector(".atk-loading-icon"), this.$text = this.$el
.querySelector(".atk-text"), this.$el.onclick = () => {
this.click()
}
}
get hasMore() {
return this.total > this.offset + this.opts.pageSize
}
click() {
this.hasMore && this.opts.onClick(this.offset + this.opts.pageSize), this.checkDisabled()
}
show() {
this.$el.style.display = ""
}
hide() {
this.$el.style.display = "none"
}
setLoading(e) {
this.$loading.style.display = e ? "" : "none", this.$text.style.display = e ? "none" : ""
}
showErr(e) {
this.setLoading(!1), this.$text.innerText = e, this.$el.classList.add("atk-err"), window
.setTimeout((() => {
this.$text.innerText = this.origText, this.$el.classList.remove("atk-err")
}), 2e3)
}
update(e, t) {
this.offset = e, this.total = t, this.checkDisabled()
}
checkDisabled() {
this.hasMore ? this.show() : this.hide()
}
}
class pn {
constructor() {
g(this, "instance"), g(this, "onReachedBottom", null), g(this, "opt")
}
create(e) {
return this.opt = e, this.instance = new un({
pageSize: e.pageSize,
onClick: t => k(this, null, (function*() {
e.ctx.fetch({
offset: t
})
})),
text: D("loadMore")
}), e.readMoreAutoLoad && (this.onReachedBottom = () => {
this.instance.hasMore && !this.opt.ctx.getData().getLoading() && this.instance
.click()
}, this.opt.ctx.on("list-reach-bottom", this.onReachedBottom)), this.instance.$el
}
setLoading(e) {
this.instance.setLoading(e)
}
update(e, t) {
this.instance.update(e, t)
}
showErr(e) {
this.instance.showErr(e)
}
next() {
this.instance.click()
}
getHasMore() {
return this.instance.hasMore
}
getIsClearComments(e) {
return 0 === e.offset
}
dispose() {
this.onReachedBottom && this.opt.ctx.off("list-reach-bottom", this.onReachedBottom), this
.instance.$el.remove()
}
}
class gn {
constructor(e, t) {
g(this, "opts"), g(this, "total"), g(this, "$el"), g(this, "$input"), g(this, "inputTimer"), g(
this, "$prevBtn"), g(this, "$nextBtn"), g(this, "page", 1), this.total = e, this.opts =
t, this.$el = y(
'<div class="atk-pagination-wrap">\n <div class="atk-pagination">\n <div class="atk-btn atk-btn-prev">Prev</div>\n <input type="text" class="atk-input" aria-label="Enter the number of page" />\n <div class="atk-btn atk-btn-next">Next</div>\n </div>\n </div>'
), this.$input = this.$el.querySelector(".atk-input"), this.$input.value =
`${this.page}`, this.$input.oninput = () => this.input(), this.$input.onkeydown = e => this
.keydown(e), this.$prevBtn = this.$el.querySelector(".atk-btn-prev"), this.$nextBtn = this
.$el.querySelector(".atk-btn-next"), this.$prevBtn.onclick = () => this.prev(), this
.$nextBtn.onclick = () => this.next(), this.checkDisabled()
}
get pageSize() {
return this.opts.pageSize
}
get offset() {
return this.pageSize * (this.page - 1)
}
get maxPage() {
return Math.ceil(this.total / this.pageSize)
}
update(e, t) {
this.page = Math.ceil(e / this.pageSize) + 1, this.total = t, this.setInput(this.page), this
.checkDisabled()
}
setInput(e) {
this.$input.value = `${e}`
}
input(e = !1) {
window.clearTimeout(this.inputTimer);
const t = this.$input.value.trim(),
n = () => {
if ("" === t) return void this.setInput(this.page);
let e = Number(t);
Number.isNaN(e) || e < 1 ? this.setInput(this.page) : (e > this.maxPage && (this
.setInput(this.maxPage), e = this.maxPage), this.change(e))
};
e ? n() : this.inputTimer = window.setTimeout((() => n()), 800)
}
prev() {
const e = this.page - 1;
e < 1 || this.change(e)
}
next() {
const e = this.page + 1;
e > this.maxPage || this.change(e)
}
getHasMore() {
return this.page + 1 <= this.maxPage
}
change(e) {
this.page = e, this.opts.onChange(this.offset), this.setInput(e), this.checkDisabled()
}
checkDisabled() {
this.page + 1 > this.maxPage ? this.$nextBtn.classList.add("atk-disabled") : this.$nextBtn
.classList.remove("atk-disabled"), this.page - 1 < 1 ? this.$prevBtn.classList.add(
"atk-disabled") : this.$prevBtn.classList.remove("atk-disabled")
}
keydown(e) {
const t = e.keyCode || e.which;
if (38 === t) {
const e = Number(this.$input.value) + 1;
if (e > this.maxPage) return;
this.setInput(e), this.input()
} else if (40 === t) {
const e = Number(this.$input.value) - 1;
if (e < 1) return;
this.setInput(e), this.input()
} else 13 === t && this.input(!0)
}
setLoading(e) {
e ? Tt(this.$el) : _t(this.$el)
}
}
class mn {
constructor() {
g(this, "instance")
}
create(e) {
return this.instance = new gn(e.total, {
pageSize: e.pageSize,
onChange: t => k(this, null, (function*() {
e.ctx.editorResetState(), e.ctx.fetch({
offset: t,
onSuccess: () => {
e.ctx.listGotoFirst()
}
})
}))
}), this.instance.$el
}
setLoading(e) {
this.instance.setLoading(e)
}
update(e, t) {
this.instance.update(e, t)
}
next() {
this.instance.next()
}
getHasMore() {
return this.instance.getHasMore()
}
getIsClearComments() {
return !0
}
dispose() {
this.instance.$el.remove()
}
}
function fn(e) {
const t = e.getData().getListLastFetch(),
n = {
offset: 0,
total: 0
};
return t ? (n.offset = t.params.offset, t.data && (n.total = t.params.flatMode ? t.data.total : t.data
.total_roots), n) : n
}
const kn = e => {
let t = null;
e.on("conf-loaded", (n => {
const i = e.get("list");
t && t.dispose(), t = function(e) {
return e.pagination.readMore ? new pn : new mn
}(n);
const {
offset: s,
total: r
} = fn(e), o = t.create({
ctx: e,
pageSize: n.pagination.pageSize,
total: r,
readMoreAutoLoad: n.pagination.autoLoad
});
i.$commentsWrap.after(o), null == t || t.update(s, r)
})), e.on("list-loaded", (n => {
const {
offset: i,
total: s
} = fn(e);
null == t || t.update(i, s)
})), e.on("list-fetch", (n => {
e.getData().getComments().length > 0 && (null == t ? void 0 : t.getIsClearComments(
n)) && e.getData().clearComments()
})), e.on("list-error", (() => {
var e;
null == (e = null == t ? void 0 : t.showErr) || e.call(t, D("loadFail"))
})), e.on("list-fetch", (e => {
null == t || t.setLoading(!0)
})), e.on("list-fetched", (({
params: e
}) => {
null == t || t.setLoading(!1)
}))
};
class yn extends Dt {
constructor(e) {
super(e), g(this, "$commentsWrap"), g(this, "commentNodes", []), this.$el = y(
'<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'
), this.$commentsWrap = this.$el.querySelector(".atk-list-comments-wrap"), kn(e), this
.initCrudEvents()
}
getCommentsWrapEl() {
return this.$commentsWrap
}
getCommentNodes() {
return this.commentNodes
}
getListLayout() {
return new Nt({
$commentsWrap: this.$commentsWrap,
nestSortBy: this.ctx.conf.nestSort,
nestMax: this.ctx.conf.nestMax,
flatMode: this.ctx.conf.flatMode,
createCommentNode: (e, t) => {
const n = function(e, t, n) {
var i;
const s = new hn(e, t, {
isFlatMode: null == (i = e.getData()
.getListLastFetch()) ? void 0 : i.params.flatMode,
afterRender: () => {
e.trigger("comment-rendered", s)
},
onDelete: t => {
e.getData().deleteComment(t.getID())
},
replyTo: t.rid ? n.find((e => e.id === t.rid)) : void 0
});
return s.render(), s
}(this.ctx, e, t);
return this.commentNodes.push(n), n
},
findCommentNode: e => this.commentNodes.find((t => t.getID() === e)),
getCommentDataList: () => this.ctx.getData().getComments()
})
}
initCrudEvents() {
this.ctx.on("list-load", (e => {
this.getListLayout().import(e)
})), this.ctx.on("list-loaded", (e => {
0 === e.length && (this.$commentsWrap.innerHTML = "")
})), this.ctx.on("comment-inserted", (e => {
this.getListLayout().insert(e)
})), this.ctx.on("comment-deleted", (e => {
const t = this.commentNodes.find((t => t.getID() === e.id));
t ? (t.getEl().remove(), this.commentNodes = this.commentNodes.filter((t => t
.getID() !== e.id))) : console.error(
`comment node id=${e.id} not found`)
})), this.ctx.on("comment-updated", (e => {
const t = this.commentNodes.find((t => t.getID() === e.id));
t && t.setData(e)
}))
}
}
let vn, $n;
function bn() {
return {
init() {
vn = document.body.style.overflow, $n = document.body.style.paddingRight
},
unlock() {
document.body.style.overflow = vn, document.body.style.paddingRight = $n
},
lock() {
document.body.style.overflow = "hidden";
const e = parseInt(window.getComputedStyle(document.body, null).getPropertyValue(
"padding-right"), 10);
document.body.style.paddingRight =
`${function(){const e=document.createElement("p");e.style.width="100%",e.style.height="200px";const t=document.createElement("div");t.style.position="absolute",t.style.top="0px",t.style.left="0px",t.style.visibility="hidden",t.style.width="200px",t.style.height="150px",t.style.overflow="hidden",t.appendChild(e),document.body.appendChild(t);const n=e.offsetWidth;t.style.overflow="scroll";let i=e.offsetWidth;return n===i&&(i=t.clientWidth),document.body.removeChild(t),n-i}()+e||0}px`
}
}
}
class wn {
constructor() {
g(this, "$wrap"), g(this, "$mask"), g(this, "allowMaskClose", !0), g(this, "items", []), this
.$wrap = y(
'<div class="atk-layer-wrap" style="display: none;"><div class="atk-layer-mask"></div></div>'
), this.$mask = this.$wrap.querySelector(".atk-layer-mask")
}
createItem(e, t) {
return t || ((t = document.createElement("div")).classList.add("atk-layer-item"), t
.setAttribute("data-layer-name", e), t.style.display = "none"), this.$wrap.appendChild(
t), this.items.push(t), t
}
getWrap() {
return this.$wrap
}
getMask() {
return this.$mask
}
setMaskClose(e) {
this.allowMaskClose = e
}
show() {
this.$wrap.style.display = "block", this.$mask.style.display = "block", this.$mask.classList
.add("atk-fade-in"), this.$mask.onclick = () => {
this.allowMaskClose && this.hide()
}, bn().lock()
}
hide(e) {
if (this.items.filter((e => e.isConnected && "none" !== e.style.display)).length > 1)
return void(e && e());
const t = () => {
this.$wrap.style.display = "none", this.$wrap.classList.remove("atk-fade-out"), e &&
e(), bn().unlock(), this.$wrap.onanimationend = null
};
this.$wrap.classList.add("atk-fade-out"), "none" !== window.getComputedStyle(this.$wrap)[
"animation-name"] ? this.$wrap.onanimationend = () => t() : t()
}
}
class xn {
constructor(e, t, n) {
g(this, "$el"), g(this, "wrap"), g(this, "onAfterHide"), this.wrap = e, this.$el = this.wrap
.createItem(t, n)
}
setOnAfterHide(e) {
this.onAfterHide = e
}
getEl() {
return this.$el
}
show() {
this.$el.style.display = "", this.wrap.show()
}
hide() {
this.wrap.hide((() => {
this.$el.style.display = "none", this.onAfterHide && this.onAfterHide()
}))
}
destroy() {
this.wrap.hide((() => {
this.$el.remove(), this.onAfterHide && this.onAfterHide()
}))
}
}
class Cn {
constructor(e) {
g(this, "wrap"), g(this, "ctx"), this.ctx = e, this.wrap = new wn, document.body.appendChild(
this.wrap.getWrap()), e.on("destroy", (() => {
this.wrap.getWrap().remove()
})), bn().init()
}
getEl() {
return this.wrap.getWrap()
}
create(e, t) {
return new xn(this.wrap, e, t)
}
}
const Sn = "ArtalkUser";
class En {
constructor(e) {
g(this, "data"), this.opts = e;
const t = JSON.parse(window.localStorage.getItem(Sn) || "{}");
this.data = {
nick: t.nick || "",
email: t.email || "",
link: t.link || "",
token: t.token || "",
isAdmin: t.isAdmin || !1
}
}
getData() {
return this.data
}
update(e = {}) {
Object.entries(e).forEach((([e, t]) => {
this.data[e] = t
})), window.localStorage.setItem(Sn, JSON.stringify(this.data)), this.opts.onUserChanged &&
this.opts.onUserChanged(this.data)
}
logout() {
this.update({
token: "",
isAdmin: !1
})
}
checkHasBasicUserInfo() {
return !!this.data.nick && !!this.data.email
}
}
const Tn = {
i18n(e) {
U(e.conf.locale), e.on("conf-loaded", (() => {
U(e.conf.locale)
}))
},
user: e => new En({
onUserChanged: t => {
e.trigger("user-changed", t)
}
}),
layerManager: e => new Cn(e),
checkerLauncher: e => new Ut({
getCtx: () => e,
getApi: () => e.getApi(),
getIframeURLBase: () => e.conf.server,
onReload: () => e.reload()
}),
editor(e) {
const t = new Wt(e);
return e.$root.appendChild(t.$el), t
},
list(e) {
const t = new yn(e);
return e.$root.appendChild(t.$el), t
},
sidebarLayer: e => new jt(e),
editorPlugs() {}
};
function _n(e) {
const t = y(`<span>${e.errMsg}${D("listLoadFailMsg")}<br/></span>`);
if (e.retryFn) {
const n = y(`<span style="cursor:pointer;">${D("listRetry")}</span>`);
n.onclick = () => e.retryFn && e.retryFn(), t.appendChild(n)
}
if (e.onOpenSidebar) {
const n = y(
`<span atk-only-admin-show> | <span style="cursor:pointer;">${D("open")+D("ctrlCenter")}</span></span>`
);
t.appendChild(n), n.onclick = () => e.onOpenSidebar && e.onOpenSidebar()
}
Pt(e.$err, t)
}
function Ln(e) {
e.getApi().system.conf().then((t => {
let n = {
apiVersion: t.version.version
};
if (e.conf.useBackendConf) {
if (!t.frontend_conf) throw new Error(
"The remote backend does not respond to the frontend conf, but `useBackendConf` conf is enabled"
);
n = u(u({}, n), function(e) {
const t = ["el", "pageKey", "pageTitle", "server", "site", "darkMode"];
return Object.keys(e).forEach((n => {
t.includes(n) && delete e[n]
})), e.emoticons && "string" == typeof e.emoticons && (e.emoticons =
e.emoticons.trim(), e.emoticons.startsWith("[") || e.emoticons
.startsWith("{") ? e.emoticons = JSON.parse(e.emoticons) :
"false" === e.emoticons && (e.emoticons = !1)), e
}(t.frontend_conf))
}
e.conf.remoteConfModifier && e.conf.remoteConfModifier(n), e.updateConf(n)
})).catch((t => {
var n;
e.updateConf({});
let i = "";
if (null == (n = t.data) ? void 0 : n.err_no_site) {
const t = {
create_name: e.conf.site,
create_urls: `${window.location.protocol}//${window.location.host}`
};
i = `sites|${JSON.stringify(t)}`
}
throw _n({
$err: e.get("list").$el,
errMsg: t.msg || String(t),
errData: t.data,
retryFn: () => Ln(e),
onOpenSidebar: e.get("user").getData().isAdmin ? () => e.showSidebar({
view: i
}) : void 0
}), t
})).then((() => {
e.conf.remoteConfModifier || e.fetch({
offset: 0
})
})).catch((() => {}))
}
const An = "ArtalkContent";
class On {
constructor(e) {
this.kit = e
}
reqAdd() {
return k(this, null, (function*() {
return yield this.kit.useApi().comment.add(u({}, this.getSubmitAddParams()))
}))
}
getSubmitAddParams() {
const {
nick: e,
email: t,
link: n
} = this.kit.useUser().getData(), i = this.kit.useConf();
return {
content: this.kit.useEditor().getContentFinal(),
nick: e,
email: t,
link: n,
rid: 0,
page_key: i.pageKey,
page_title: i.pageTitle,
site_name: i.site
}
}
postSubmitAdd(e) {
this.kit.useGlobalCtx().getData().insertComment(e)
}
}
class Pn extends qt {
constructor(e) {
super(e), g(this, "customs", []), g(this, "defaultPreset"), this.defaultPreset = new On(this
.kit);
const t = () => this.do();
this.kit.useMounted((() => {
this.kit.useGlobalCtx().on("editor-submit", t)
})), this.kit.useUnmounted((() => {
this.kit.useGlobalCtx().off("editor-submit", t)
}))
}
registerCustom(e) {
this.customs.push(e)
}
do() {
return k(this, null, (function*() {
if ("" === this.kit.useEditor().getContentFinal().trim()) return void this.kit
.useEditor().focus();
const e = this.customs.find((e => e.activeCond()));
this.kit.useEditor().showLoading();
try {
let t;
(null == e ? void 0 : e.pre) && e.pre(), t = (null == e ? void 0 : e.req) ?
yield e.req(): yield this.defaultPreset.reqAdd(), (null == e ? void 0 :
e.post) ? e.post(t) : this.defaultPreset.postSubmitAdd(t)
} catch (t) {
return console.error(t), void this.kit.useEditor().showNotify(
`${D("commentFail")}${t.msg||String(t)}`, "e")
} finally {
this.kit.useEditor().hideLoading()
}
this.kit.useEditor().reset(), this.kit.useGlobalCtx().trigger(
"editor-submitted")
}))
}
}
class Rn extends qt {
constructor(e) {
super(e), g(this, "emoticons", []), g(this, "loadingTask", null), g(this, "$grpWrap"), g(this,
"$grpSwitcher"), g(this, "isListLoaded", !1), g(this, "isImgLoaded", !1), this.kit
.useMounted((() => {
this.usePanel('<div class="atk-editor-plug-emoticons"></div>'), this.useBtn(D(
"emoticon"))
})), this.kit.useUnmounted((() => {})), this.useContentTransformer((e => this
.transEmoticonImageText(e))), this.usePanelShow((() => {
(() => {
k(this, null, (function*() {
yield this.loadEmoticonsData(), this.isImgLoaded || (
this.initEmoticonsList(), this.isImgLoaded = !0
), setTimeout((() => {
this.changeListHeight()
}), 30)
}))
})()
})), this.usePanelHide((() => {
this.$panel.parentElement.style.height = ""
})), window.setTimeout((() => {
this.loadEmoticonsData()
}), 1e3)
}
loadEmoticonsData() {
return k(this, null, (function*() {
this.isListLoaded || (null === this.loadingTask ? (this.loadingTask = (() => k(
this, null, (function*() {
Tt(this.$panel), this.emoticons = yield this
.handleData(this.kit.useConf().emoticons),
_t(this.$panel), this.loadingTask = null,
this.isListLoaded = !0
})))(), yield this.loadingTask) : yield this.loadingTask)
}))
}
handleData(e) {
return k(this, null, (function*() {
if (!Array.isArray(e) && ["object", "string"].includes(typeof e) && (e = [e]), !
Array.isArray(e)) return Pt(this.$panel, "表情包数据必须为 Array/Object/String 类型"),
_t(this.$panel), [];
const t = t => {
"object" == typeof t && (t.name && e.find((e => e.name === t.name)) || e
.push(t))
},
n = e => k(this, null, (function*() {
yield Promise.all(e.map(((e, i) => k(this, null, (function*() {
if ("object" != typeof e || Array
.isArray(e)) {
if (Array.isArray(e)) yield n(
e);
else if ("string" == typeof e) {
const i = yield this
.remoteLoad(e);
Array.isArray(i) ? yield n(
i): "object" ==
typeof i && t(i)
}
} else t(e)
})))))
}));
return yield n(e), e.forEach((e => {
if (this.isOwOFormat(e)) {
this.convertOwO(e).forEach((e => {
t(e)
}))
} else Array.isArray(e) && e.forEach((e => {
t(e)
}))
})), e = e.filter((e => "object" == typeof e && !Array.isArray(e) && !!
e && !!e.name)), this.solveNullKey(e), this.solveSameKey(e), e
}))
}
remoteLoad(e) {
return k(this, null, (function*() {
if (!e) return [];
try {
const t = yield fetch(e);
return yield t.json()
} catch (t) {
return _t(this.$panel), console.error("[Emoticons] Load Failed:", t), Pt(
this.$panel, `${D("emoticon")}${D("loadFail")} ${String(t)}`), []
}
}))
}
solveNullKey(e) {
e.forEach((e => {
e.items.forEach(((t, n) => {
t.key || (t.key = `${e.name} ${n+1}`)
}))
}))
}
solveSameKey(e) {
const t = {};
e.forEach((e => {
e.items.forEach((e => {
e.key && "" !== String(e.key).trim() && (t[e.key] ? t[e.key]++ :
t[e.key] = 1, t[e.key] > 1 && (e.key =
`${e.key} ${t[e.key]}`))
}))
}))
}
isOwOFormat(e) {
try {
return "object" == typeof e && !!Object.values(e).length && Array.isArray(Object.keys(Object
.values(e)[0].container)) && Object.keys(Object.values(e)[0].container[0]).includes(
"icon")
} catch (t) {
return !1
}
}
convertOwO(e) {
const t = [];
return Object.entries(e).forEach((([e, n]) => {
const i = {
name: e,
type: n.type,
items: []
};
n.container.forEach(((t, n) => {
const s = t.icon;
if (/<(img|IMG)/.test(s)) {
const e = /src=["'](.*?)["']/.exec(s);
e && e.length > 1 && (t.icon = e[1])
}
i.items.push({
key: t.text || `${e} ${n+1}`,
val: t.icon
})
})), t.push(i)
})), t
}
initEmoticonsList() {
this.$grpWrap = y('<div class="atk-grp-wrap"></div>'), this.$panel.append(this.$grpWrap), this
.emoticons.forEach(((e, t) => {
const n = y('<div class="atk-grp" style="display: none;"></div>');
this.$grpWrap.append(n), n.setAttribute("data-index", String(t)), n
.setAttribute("data-grp-name", e.name), n.setAttribute("data-type", e.type),
e.items.forEach((t => {
const i = y('<span class="atk-item"></span>');
if (n.append(i), t.key && !new RegExp(
`^(${e.name})?\\s?[0-9]+$`).test(t.key) && i
.setAttribute("title", t.key), "image" === e.type) {
const e = document.createElement("img");
e.src = t.val, e.alt = t.key, i.append(e)
} else i.innerText = t.val;
i.onclick = () => {
"image" === e.type ? this.kit.useEditor().insertContent(
`:[${t.key}]`) : this.kit.useEditor()
.insertContent(t.val || "")
}
}))
})), this.emoticons.length > 1 && (this.$grpSwitcher = y(
'<div class="atk-grp-switcher"></div>'), this.$panel.append(this.$grpSwitcher), this
.emoticons.forEach(((e, t) => {
const n = y("<span />");
n.innerText = e.name, n.setAttribute("data-index", String(t)), n.onclick =
() => this.openGrp(t), this.$grpSwitcher.append(n)
}))), this.emoticons.length > 0 && this.openGrp(0)
}
openGrp(e) {
var t, n, i;
Array.from(this.$grpWrap.children).forEach((t => {
const n = t;
n.getAttribute("data-index") !== String(e) ? n.style.display = "none" : n.style
.display = ""
})), null == (t = this.$grpSwitcher) || t.querySelectorAll("span.active").forEach((e => e
.classList.remove("active"))), null == (i = null == (n = this.$grpSwitcher) ? void 0 : n
.querySelector(`span[data-index="${e}"]`)) || i.classList.add("active"), this
.changeListHeight()
}
changeListHeight() {}
transEmoticonImageText(e) {
return this.emoticons && Array.isArray(this.emoticons) ? (this.emoticons.forEach((t => {
"image" === t.type && Object.entries(t.items).forEach((([t, n]) => {
e = e.split(`:[${n.key}]`).join(
`<img src="${n.val}" atk-emoticon="${n.key}">`)
}))
})), e) : e
}
}
const Mn = ["png", "jpg", "jpeg", "gif", "bmp", "svg", "webp"];
class In extends qt {
constructor(e) {
super(e), g(this, "$imgUploadInput"), this.kit.useMounted((() => this.init())), this
.initDragImg()
}
init() {
this.$imgUploadInput = document.createElement("input"), this.$imgUploadInput.type = "file", this
.$imgUploadInput.style.display = "none", this.$imgUploadInput.accept = Mn.map((e =>
`.${e}`)).join(",");
const e = this.useBtn(`${D("image")}`);
e.after(this.$imgUploadInput), e.onclick = () => {
const e = this.$imgUploadInput;
e.onchange = () => {
(() => {
k(this, null, (function*() {
if (!e.files || 0 === e.files.length) return;
const t = e.files[0];
this.uploadImg(t)
}))
})()
}, e.click()
}, this.kit.useConf().imgUpload || this.$btn.setAttribute("atk-only-admin-show", "")
}
initDragImg() {
const e = e => {
if (e)
for (let t = 0; t < e.length; t++) {
const n = e[t];
this.uploadImg(n)
}
},
t = e => {
e.stopPropagation(), e.preventDefault()
},
n = t => {
var n;
const i = null == (n = t.dataTransfer) ? void 0 : n.files;
(null == i ? void 0 : i.length) && (t.preventDefault(), e(i))
},
i = t => {
var n;
const i = null == (n = t.clipboardData) ? void 0 : n.files;
(null == i ? void 0 : i.length) && (t.preventDefault(), e(i))
};
this.kit.useMounted((() => {
this.kit.useUI().$textarea.addEventListener("dragover", t), this.kit.useUI()
.$textarea.addEventListener("drop", n), this.kit.useUI().$textarea
.addEventListener("paste", i)
})), this.kit.useUnmounted((() => {
this.kit.useUI().$textarea.removeEventListener("dragover", t), this.kit.useUI()
.$textarea.removeEventListener("drop", n), this.kit.useUI().$textarea
.removeEventListener("paste", i)
}))
}
uploadImg(e) {
return k(this, null, (function*() {
const t = /[^.]+$/.exec(e.name);
if (!t || !Mn.includes(t[0])) return;
if (!this.kit.useUser().checkHasBasicUserInfo()) return void this.kit
.useEditor().showNotify(D("uploadLoginMsg"), "w");
let n = "\n";
"" === this.kit.useUI().$textarea.value.trim() && (n = "");
const i = `${n}![](Uploading ${e.name}...)`;
let s;
this.kit.useEditor().insertContent(i);
try {
const t = this.kit.useConf().imgUploader;
s = t ? {
img_url: yield t(e)
} : yield this.kit.useApi().upload.imgUpload(e)
} catch (r) {
console.error(r), this.kit.useEditor().showNotify(
`${D("uploadFail")}${r.msg}`, "e")
}
if (s && s.img_url) {
let e = s.img_url;
E(e) || (e = T({
base: this.kit.useConf().server,
path: e
})), this.kit.useEditor().setContent(this.kit.useUI().$textarea.value
.replace(i, `${n}![](${e})`))
} else this.kit.useEditor().setContent(this.kit.useUI().$textarea.value.replace(
i, ""))
}))
}
}
class Un extends qt {
constructor(e) {
super(e), g(this, "isPlugPanelShow", !1), this.kit.useMounted((() => {
this.usePanel('<div class="atk-editor-plug-preview"></div>');
let e = D("preview");
kt() && (e +=
' <i title="Markdown is supported"><svg class="markdown" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><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>'
), this.useBtn(e)
})), this.kit.useUnmounted((() => {})), this.kit.useEvents().on("content-updated", (e => {
this.isPlugPanelShow && this.updateContent()
})), this.usePanelShow((() => {
this.isPlugPanelShow = !0, this.updateContent()
})), this.usePanelHide((() => {
this.isPlugPanelShow = !1
}))
}
updateContent() {
this.$panel.innerHTML = this.kit.useEditor().getContentMarked()
}
}
const Dn = [class extends qt {
constructor(e) {
super(e);
const t = () => {
this.save()
};
this.kit.useMounted((() => {
const e = window.localStorage.getItem(An) || "";
"" !== e.trim() && (this.kit.useEditor().showNotify(D("restoredMsg"),
"i"), this.kit.useEditor().setContent(e)), this.kit.useEvents()
.on("content-updated", t)
})), this.kit.useUnmounted((() => {
this.kit.useEvents().off("content-updated", t)
}))
}
save() {
window.localStorage.setItem(An, this.kit.useEditor().getContentRaw().trim())
}
}, class extends qt {
get $inputs() {
return this.kit.useEditor().getHeaderInputEls()
}
constructor(e) {
super(e);
const t = {},
n = {},
i = (e, t, n) => () => {
this.kit.useEvents().trigger(e, {
field: n,
$input: t
})
};
this.kit.useMounted((() => {
Object.entries(this.$inputs).forEach((([e, s]) => {
s.addEventListener("input", t[e] = i("header-input", s, e)),
s.addEventListener("change", n[e] = i("header-change",
s, e))
}))
})), this.kit.useUnmounted((() => {
Object.entries(this.$inputs).forEach((([e, i]) => {
i.removeEventListener("input", t[e]), i.removeEventListener(
"change", n[e])
}))
}))
}
}, class extends qt {
constructor(e) {
super(e), g(this, "query", {
timer: null,
abortFn: null
});
const t = ({
$input: e,
field: t
}) => {
"edit" !== this.kit.useEditor().getState() && (this.kit.useUser().update({
[t]: e.value.trim()
}), "nick" !== t && "email" !== t || this.fetchUserInfo())
};
this.kit.useMounted((() => {
Object.entries(this.kit.useEditor().getHeaderInputEls()).forEach((([e,
t]) => {
t.placeholder = `${D(e)}`, t.value = this.kit.useUser()
.getData()[e] || ""
})), this.kit.useEvents().on("header-input", t)
})), this.kit.useUnmounted((() => {
this.kit.useEvents().off("header-input", t)
}))
}
fetchUserInfo() {
this.kit.useUser().logout(), this.query.timer && window.clearTimeout(this.query.timer),
this.query.abortFn && this.query.abortFn(), this.query.timer = window.setTimeout((
() => {
this.query.timer = null;
const {
req: e,
abort: t
} = this.kit.useApi().user.userGet(this.kit.useUser().getData().nick,
this.kit.useUser().getData().email);
this.query.abortFn = t, e.then((e => this.onUserInfoFetched(e))).catch((
e => {})).finally((() => {
this.query.abortFn = null
}))
}), 400)
}
onUserInfoFetched(e) {
var t;
e.is_login || this.kit.useUser().logout(), this.kit.useGlobalCtx().getData()
.updateUnreads(e.unread), this.kit.useUser().checkHasBasicUserInfo() && !e
.is_login && (null == (t = e.user) ? void 0 : t.is_admin) && this.kit.useGlobalCtx()
.checkAdmin({
onSuccess: () => {}
}), e.user && e.user.link && (this.kit.useUI().$link.value = e.user.link, this.kit
.useUser().update({
link: e.user.link
}))
}
}, class extends qt {
constructor(e) {
super(e);
const t = ({
field: e
}) => {
"link" === e && this.onLinkInputChange()
};
this.kit.useMounted((() => {
this.kit.useEvents().on("header-change", t)
})), this.kit.useUnmounted((() => {
this.kit.useEvents().off("header-change", t)
}))
}
onLinkInputChange() {
const e = this.kit.useUI().$link.value.trim();
e && !/^(http|https):\/\//.test(e) && (this.kit.useUI().$link.value = `https://${e}`,
this.kit.useUser().update({
link: this.kit.useUI().$link.value
}))
}
}, class extends qt {
constructor(e) {
super(e);
const t = e => this.onKeydown(e),
n = () => this.onInput();
this.kit.useMounted((() => {
this.kit.useUI().$textarea.placeholder = this.kit.useConf()
.placeholder || D("placeholder"), this.kit.useUI().$textarea
.addEventListener("keydown", t), this.kit.useUI().$textarea
.addEventListener("input", n)
})), this.kit.useUnmounted((() => {
this.kit.useUI().$textarea.removeEventListener("keydown", t), this.kit
.useUI().$textarea.removeEventListener("input", n)
})), this.kit.useEvents().on("content-updated", (() => {
window.setTimeout((() => {
this.adaptiveHeightByContent()
}), 80)
}))
}
onKeydown(e) {
9 === (e.keyCode || e.which) && (e.preventDefault(), this.kit.useEditor().insertContent(
"\t"))
}
onInput() {
this.kit.useEvents().trigger("content-updated", this.kit.useEditor().getContentRaw())
}
adaptiveHeightByContent() {
const e = this.kit.useUI().$textarea.offsetHeight - this.kit.useUI().$textarea
.clientHeight;
this.kit.useUI().$textarea.style.height = "0px", this.kit.useUI().$textarea.style
.height = `${this.kit.useUI().$textarea.scrollHeight+e}px`
}
}, Pn, class extends qt {
constructor(e) {
super(e);
const t = () => {
this.kit.useEditor().submit()
};
this.kit.useMounted((() => {
this.kit.useUI().$submitBtn.innerText = this.kit.useConf().sendBtn || D(
"send"), this.kit.useUI().$submitBtn.addEventListener("click",
t)
})), this.kit.useUnmounted((() => {
this.kit.useUI().$submitBtn.removeEventListener("click", t)
}))
}
}, Ft, class extends qt {
constructor(e) {
super(e), g(this, "comment"), this.useEditorStateEffect("reply", (e => (this.setReply(
e), () => {
this.cancelReply()
}))), this.kit.useEvents().on("mounted", (() => {
const e = this.kit.useDeps(Pn);
if (!e) throw Error("SubmitPlug not initialized");
const t = new On(this.kit);
e.registerCustom({
activeCond: () => !!this.comment,
req: () => k(this, null, (function*() {
if (!this.comment) throw new Error(
"reply comment cannot be empty");
return yield this.kit.useApi().comment.add(
p(u({}, t
.getSubmitAddParams()), {
rid: this.comment.id,
page_key: this.comment
.page_key,
page_title: void 0,
site_name: this.comment
.site_name
}))
})),
post: e => {
const n = this.kit.useConf();
e.page_key !== n.pageKey && window.open(
`${e.page_url}#atk-comment-${e.id}`), t
.postSubmitAdd(e)
}
})
}))
}
setReply(e) {
const t = this.kit.useUI();
t.$sendReply || (t.$sendReply = y(
`<div class="atk-send-reply">${D("reply")} <span class="atk-text"></span><span class="atk-cancel">×</span></div>`
), t.$sendReply.querySelector(".atk-text").innerText = `@${e.nick}`, t
.$sendReply.addEventListener("click", (() => {
this.kit.useEditor().resetState()
})), t.$textareaWrap.append(t.$sendReply)), this.comment = e, t.$textarea
.focus()
}
cancelReply() {
if (!this.comment) return;
const e = this.kit.useUI();
e.$sendReply && (e.$sendReply.remove(), e.$sendReply = void 0), this.comment = void 0
}
}, class extends qt {
constructor(e) {
super(e), g(this, "comment"), g(this, "originalSubmitBtnText", "Send"), this
.useEditorStateEffect("edit", (e => (this.edit(e), () => {
this.cancelEdit()
}))), this.kit.useMounted((() => {
const e = this.kit.useDeps(Pn);
if (!e) throw Error("SubmitPlug not initialized");
e.registerCustom({
activeCond: () => !!this.comment,
req: () => k(this, null, (function*() {
const e = {
content: this.kit.useEditor()
.getContentFinal(),
nick: this.kit.useUI().$nick.value,
email: this.kit.useUI().$email
.value,
link: this.kit.useUI().$link.value
};
return yield this.kit.useApi().comment
.commentEdit(u(u({}, this.comment),
e))
})),
post: e => {
this.kit.useGlobalCtx().getData().updateComment(e)
}
})
}))
}
edit(e) {
const t = this.kit.useUI();
if (!t.$editCancelBtn) {
const e = y(
`<div class="atk-send-reply">${D("editCancel")} <span class="atk-cancel">×</span></div>`
);
e.onclick = () => {
this.kit.useEditor().resetState()
}, t.$textareaWrap.append(e), t.$editCancelBtn = e
}
this.comment = e, t.$header.style.display = "none", t.$nick.value = e.nick || "", t
.$email.value = e.email || "", t.$link.value = e.link || "", this.kit.useEditor()
.setContent(e.content), t.$textarea.focus(), this.updateSubmitBtnText(D("save"))
}
cancelEdit() {
if (!this.comment) return;
const e = this.kit.useUI();
e.$editCancelBtn && (e.$editCancelBtn.remove(), e.$editCancelBtn = void 0), this
.comment = void 0;
const {
nick: t,
email: n,
link: i
} = this.kit.useUser().getData();
e.$nick.value = t, e.$email.value = n, e.$link.value = i, this.kit.useEditor()
.setContent(""), this.restoreSubmitBtnText(), e.$header.style.display = ""
}
updateSubmitBtnText(e) {
this.originalSubmitBtnText = this.kit.useUI().$submitBtn.innerText, this.kit.useUI()
.$submitBtn.innerText = e
}
restoreSubmitBtnText() {
this.kit.useUI().$submitBtn.innerText = this.originalSubmitBtnText
}
}, class extends qt {
constructor(e) {
super(e);
const t = () => this.open(),
n = () => this.close();
this.kit.useMounted((() => {
this.kit.useEvents().on("editor-open", t), this.kit.useEvents().on(
"editor-close", n)
})), this.kit.useUnmounted((() => {
this.kit.useEvents().off("editor-open", t), this.kit.useEvents().off(
"editor-close", n)
}))
}
open() {
var e;
null == (e = this.kit.useUI().$textareaWrap.querySelector(".atk-comment-closed")) || e
.remove(), this.kit.useUI().$textarea.style.display = "", this.kit.useUI().$bottom
.style.display = ""
}
close() {
this.kit.useUI().$textareaWrap.querySelector(".atk-comment-closed") || this.kit.useUI()
.$textareaWrap.prepend(y(
`<div class="atk-comment-closed">${D("onlyAdminCanReply")}</div>`)), this.kit
.useUser().getData().isAdmin ? (this.kit.useUI().$textarea.style.display = "", this
.kit.useUI().$bottom.style.display = "") : (this.kit.useUI().$textarea.style
.display = "none", this.kit.useEvents().trigger("panel-close"), this.kit.useUI()
.$bottom.style.display = "none")
}
}, Rn, In, Un];
class Bn {
constructor(e) {
this.plugs = e
}
useEditor() {
return this.plugs.editor
}
useGlobalCtx() {
return this.plugs.editor.ctx
}
useConf() {
return this.plugs.editor.ctx.conf
}
useApi() {
return this.plugs.editor.ctx.getApi()
}
useUser() {
return this.plugs.editor.ctx.get("user")
}
useUI() {
return this.plugs.editor.getUI()
}
useEvents() {
return this.plugs.getEvents()
}
useMounted(e) {
this.useEvents().on("mounted", e)
}
useUnmounted(e) {
this.useEvents().on("unmounted", e)
}
useDeps(e) {
return this.plugs.get(e)
}
}
class qn {
constructor(e) {
g(this, "plugs", []), g(this, "openedPlug", null), g(this, "events", new bt), this.editor = e;
let t = !1;
this.editor.ctx.on("conf-loaded", (() => {
t && this.getEvents().trigger("unmounted"), this.clear();
const e = (n = this.editor.ctx.conf, [{
k: In,
v: n.imgUpload
}, {
k: Rn,
v: n.emoticons
}, {
k: Un,
v: n.preview
}, {
k: Ft,
v: n.editorTravel
}].filter((e => !e.v)).flatMap((e => e.k)));
var n;
Dn.filter((t => !e.includes(t))).forEach((e => {
const t = new Bn(this);
this.plugs.push(new e(t))
})), this.getEvents().trigger("mounted"), t = !0, this.loadPluginUI()
})), this.events.on("panel-close", (() => this.closePlugPanel()))
}
getPlugs() {
return this.plugs
}
getEvents() {
return this.events
}
clear() {
this.plugs = [], this.events = new bt, this.openedPlug && this.closePlugPanel()
}
loadPluginUI() {
this.editor.getUI().$plugPanelWrap.innerHTML = "", this.editor.getUI().$plugPanelWrap.style
.display = "none", this.editor.getUI().$plugBtnWrap.innerHTML = "", this.plugs.forEach((e =>
this.loadPluginItem(e)))
}
loadPluginItem(e) {
const t = e.$btn;
if (!t) return;
this.editor.getUI().$plugBtnWrap.appendChild(t), !t.onclick && (t.onclick = () => {
this.editor.getUI().$plugBtnWrap.querySelectorAll(".active").forEach((e => e
.classList.remove("active"))), e !== this.openedPlug ? (this.openPlugPanel(
e), t.classList.add("active")) : this.closePlugPanel()
});
const n = e.$panel;
n && (n.style.display = "none", this.editor.getUI().$plugPanelWrap.appendChild(n))
}
get(e) {
return this.plugs.find((t => t instanceof e))
}
openPlugPanel(e) {
this.plugs.forEach((t => {
const n = t.$panel;
n && (t === e ? (n.style.display = "", this.events.trigger("panel-show", e)) : (
n.style.display = "none", this.events.trigger("panel-hide", e)))
})), this.editor.getUI().$plugPanelWrap.style.display = "", this.openedPlug = e
}
closePlugPanel() {
this.openedPlug && (this.editor.getUI().$plugPanelWrap.style.display = "none", this.events
.trigger("panel-hide", this.openedPlug), this.openedPlug = null)
}
getTransformedContent(e) {
let t = e;
return this.plugs.forEach((e => {
e.contentTransformer && (t = e.contentTransformer(t))
})), t
}
}
const Fn = "2.7.3";
function zn(e) {
return k(this, null, (function*() {
e.countEl && document.querySelector(e.countEl) && Wn(e, {
query: "page_comment",
numEl: e.countEl
});
const t = e.pvAdd ? {
[e.pageKey]: yield e.getApi().page.pv()
} : void 0;
e.pvEl && document.querySelector(e.pvEl) && Wn(e, {
query: "page_pv",
numEl: e.pvEl,
data: t
})
}))
}
function Wn(e, t) {
return k(this, null, (function*() {
let n = t.data || {},
i = Array.from(document.querySelectorAll(t.numEl)).map((t => t.getAttribute(
"data-page-key") || e.pageKey)).filter((e => "number" != typeof n[e]));
if (i = [...new Set(i)], i.length > 0) {
const s = yield e.getApi().page.stat(t.query, i);
n = u(u({}, n), s)
}! function(e, t, n) {
document.querySelectorAll(e).forEach((e => {
const i = e.getAttribute("data-page-key"),
s = Number(i ? t[i] : n);
e.innerHTML = `${s}`
}))
}(t.numEl, n, n[e.pageKey])
}))
}
let jn = !1;
let Nn;
function Hn(e, t) {
const n = "atk-dark-mode";
e.forEach((e => {
t ? e.classList.add(n) : e.classList.remove(n)
}))
}
const Qn = [...[e => {
e.on("inited", (() => {
!1 !== e.conf.immediateFetch && e.trigger("conf-fetch")
})), e.on("conf-fetch", (() => {
Ln(e)
}))
}, e => {
! function() {
try {
if (!Ee.name) return
} catch (e) {
return
}
Ee.setOptions(u({
renderer: ht()
}, ft)), gt = Ee
}(), e.on("conf-loaded", (e => {
var t;
e.markedReplacers && (t = e.markedReplacers, mt = t)
}))
}, e => {
const t = e.get("editor"),
n = new qn(t);
e.inject("editorPlugs", n)
}, e => {
const t = () => {
var t;
t = e.get("user").getData().isAdmin,
function(e) {
const t = [];
e.$root.querySelectorAll("[atk-only-admin-show]").forEach((e => t.push(e)));
const n = document.querySelector(".atk-sidebar");
return n && n.querySelectorAll("[atk-only-admin-show]").forEach((e => t
.push(e))), t
}({
$root: e.$root
}).forEach((e => {
t ? e.classList.remove("atk-hide") : e.classList.add("atk-hide")
}))
};
e.on("list-loaded", (() => {
t()
})), e.on("user-changed", (e => {
t()
}))
}, ...[e => {
e.on("list-fetch", (t => {
if (e.getData().getLoading()) return;
e.getData().setLoading(!0);
const n = u({
offset: 0,
limit: e.conf.pagination.pageSize,
flatMode: e.conf.flatMode,
paramsModifier: e.conf.listFetchParamsModifier
}, t);
e.getData().setListLastFetch({
params: n
}), e.getApi().comment.get(n.offset, n.limit, n.flatMode, n
.paramsModifier).then((t => {
e.getData().setListLastFetch({
params: n,
data: t
}), e.getData().loadComments(t.comments), e
.getData().updatePage(t.page), e.getData()
.updateUnreads(t.unread || []), n.onSuccess && n
.onSuccess(t), e.trigger("list-fetched", {
params: n,
data: t
})
})).catch((t => {
const i = {
msg: t.msg || String(t),
data: t.data
};
throw n.onError && n.onError(i), e.trigger("list-error",
i), e.trigger("list-fetched", {
params: n,
error: i
}), t
})).finally((() => {
e.getData().setLoading(!1)
}))
}))
}, e => {
e.on("list-fetch", (t => {
const n = e.get("list");
0 === t.offset && Lt(!0, n.$el)
})), e.on("list-fetched", (() => {
Lt(!1, e.get("list").$el)
}))
}, e => {
e.on("comment-rendered", (t => {
if (!0 === e.conf.listUnreadHighlight) {
const n = e.getData().getUnreads(),
i = n.find((e => e.comment_id === t.getID()));
i ? (t.getRender().setUnread(!0), t.getRender().setOpenAction((
() => {
window.open(i.read_link), e.getData()
.updateUnreads(n.filter((e => e
.comment_id !== t.getID())))
}))) : t.getRender().setUnread(!1)
}
})), e.on("list-goto", (t => {
const n = b("atk_notify_key");
n && e.getApi().user.markRead(t, n).then((() => {
e.getData().updateUnreads(e.getData().getUnreads()
.filter((e => e.comment_id !== t)))
}))
}))
}, e => {
let t;
e.on("inited", (() => {
const n = e.get("list");
t = n.$el.querySelector('[data-action="admin-close-comment"]'), t
.addEventListener("click", (() => {
const t = e.getData().getPage();
if (!t) throw new Error("Page data not found");
t.admin_only = !t.admin_only,
function(e, t) {
e.editorShowLoading(), e.getApi().page.pageEdit(
t).then((t => {
e.getData().updatePage(t)
})).catch((t => {
e.editorShowNotify(
`${D("editFail")}: ${t.msg||String(t)}`,
"e")
})).finally((() => {
e.editorHideLoading()
}))
}(e, t)
}))
})), e.on("page-loaded", (n => {
var i, s;
const r = e.get("editor");
!0 === (null == n ? void 0 : n.admin_only) ? (null == (i = r
.getPlugs()) || i.getEvents().trigger("editor-close"), t && (t
.innerText = D("openComment"))) : (null == (s = r
.getPlugs()) || s.getEvents().trigger("editor-open"), t && (t
.innerText = D("closeComment")))
})), e.on("list-loaded", (t => {
e.editorResetState()
}))
}, e => {
e.on("list-loaded", (() => {
(() => {
var t, n;
const i = e.get("list").$el.querySelector(
".atk-comment-count .atk-text");
if (!i) return;
const s = $(D("counter", {
count: `${Number(null==(n=null==(t=e.getData().getListLastFetch())?void 0:t.data)?void 0:n.total)||0}`
}));
i.innerHTML = s.replace(/(\d+)/,
'<span class="atk-comment-count-num">$1</span>')
})()
})), e.on("comment-inserted", (() => {
const t = e.getData().getListLastFetch();
(null == t ? void 0 : t.data) && (t.data.total += 1)
})), e.on("comment-deleted", (() => {
const t = e.getData().getListLastFetch();
(null == t ? void 0 : t.data) && (t.data.total -= 1)
}))
}, e => {
let t = null;
const n = () => {
if (!t) return;
const n = e.get("user").getData();
if (n.nick && n.email) {
t.classList.remove("atk-hide");
const e = t.querySelector(".atk-text");
e && (e.innerText = n.isAdmin ? D("ctrlCenter") : D("msgCenter"))
} else t.classList.add("atk-hide")
};
e.on("conf-loaded", (() => {
const i = e.get("list");
t = i.$el.querySelector('[data-action="open-sidebar"]'), t && (t
.onclick = () => {
e.showSidebar()
}, n())
})), e.on("user-changed", (e => {
n()
}))
}, e => {
let t = null;
e.on("conf-loaded", (() => {
const n = e.get("list");
t = n.$el.querySelector(".atk-unread-badge")
})), e.on("unreads-updated", (e => {
var n;
n = e.length || 0, t && (n > 0 ? (t.innerText = `${Number(n||0)}`, t
.style.display = "block") : t.style.display = "none")
}))
}, e => {
const t = t => {
e.conf.listFetchParamsModifier = t, e.reload()
},
n = e => {
! function(e) {
const {
$dropdownWrap: t,
dropdownList: n
} = e;
if (t.querySelector(".atk-dropdown")) return;
t.classList.add("atk-dropdown-wrap"), t.append(y(
'<span class="atk-arrow-down-icon"></span>'));
let i = 0;
const s = (e, t, n, s) => {
s(), i = e, r.querySelectorAll(".active").forEach((e => {
e.classList.remove("active")
})), t.classList.add("active"), r.style.display = "none",
setTimeout((() => {
r.style.display = ""
}), 80)
},
r = y('<ul class="atk-dropdown atk-fade-in"></ul>');
n.forEach(((e, t) => {
const n = e[0],
o = e[1],
a = y(
'<li class="atk-dropdown-item"><span></span></li>'),
l = a.querySelector("span");
l.innerText = n, l.onclick = () => {
s(t, a, n, o)
}, r.append(a), t === i && a.classList.add("active")
})), t.append(r)
}({
$dropdownWrap: e,
dropdownList: [
[D("sortLatest"), () => {
t((e => {
e.sort_by = "date_desc"
}))
}],
[D("sortBest"), () => {
t((e => {
e.sort_by = "vote"
}))
}],
[D("sortOldest"), () => {
t((e => {
e.sort_by = "date_asc"
}))
}],
[D("sortAuthor"), () => {
t((e => {
e.view_only_admin = !0
}))
}]
]
})
};
e.on("conf-loaded", (() => {
const t = e.get("list").$el.querySelector(".atk-comment-count");
t && (e.conf.listSort ? n(t) : function(e) {
var t, n;
const {
$dropdownWrap: i
} = e;
i.classList.remove("atk-dropdown-wrap"), null == (t = i
.querySelector(".atk-arrow-down-icon")) || t
.remove(), null == (n = i.querySelector(
".atk-dropdown")) || n.remove()
}({
$dropdownWrap: t
}))
}))
}, e => {
let t = !0;
const n = () => {
const n = function() {
let e = Number(b("atk_comment"));
if (!e) {
const t = window.location.hash.match(/#atk-comment-([0-9]+)/);
if (!t || !t[1] || Number.isNaN(Number(t[1]))) return null;
e = Number(t[1])
}
return e || null
}();
n && (e.trigger("list-goto", n), t = !0)
},
i = () => {
t = !1, n()
};
e.on("inited", (() => {
window.addEventListener("hashchange", i), e.on("list-loaded", n)
})), e.on("destroy", (() => {
window.removeEventListener("hashchange", i), e.off("list-loaded", n)
}));
let s = 0;
e.on("list-goto", (n => {
if (s === n) return;
const i = e.get("list").getCommentNodes().find((e => e.getID() === n));
if (!i) return;
s = n, i.getParents().forEach((e => {
e.getRender().heightLimitRemoveForChildren()
}));
const r = () => {
At(i.getEl(), !1), i.getEl().classList.remove("atk-flash-once"),
window.setTimeout((() => {
i.getEl().classList.add("atk-flash-once")
}), 150)
};
t ? window.setTimeout((() => r()), 350) : r()
}))
}, e => {
e.on("list-loaded", (t => {
const n = e.get("list"),
i = t.length <= 0;
let s = n.getCommentsWrapEl().querySelector(".atk-list-no-comment");
i ? s || (s = y('<div class="atk-list-no-comment"></div>'), s
.innerHTML = at(n.ctx.conf.noComment || n.ctx.$t("noComment")),
n.getCommentsWrapEl().appendChild(s)) : null == s || s.remove()
}))
}, e => {
e.on("conf-loaded", (() => {
const t = e.get("list").$el.querySelector(".atk-copyright");
t && (t.innerHTML =
`Powered By <a href="https://artalk.js.org" target="_blank" title="Artalk v${Fn}">Artalk</a>`
)
}))
}, e => {
let t = null;
e.on("inited", (() => {
t = window.setInterval((() => {
e.get("list").$el.querySelectorAll(
"[data-atk-comment-date]").forEach((t => {
const n = t.getAttribute(
"data-atk-comment-date");
t.innerText = C(new Date(Number(n)), e
.$t)
}))
}), 3e4)
})), e.on("destroy", (() => {
t && window.clearInterval(t)
}))
}, e => {
e.on("list-fetch", (() => {
Pt(e.get("list").$el, null)
})), e.on("list-error", (t => {
_n({
$err: e.get("list").$el,
errMsg: t.msg,
errData: t.data,
retryFn: () => e.fetch({
offset: 0
})
})
}))
}, e => {
const t = document;
let n = null;
const i = () => {
null == n || n.disconnect(), n = null
};
e.on("list-loaded", (() => {
i();
const s = e.get("list").getCommentsWrapEl().querySelector(
".atk-comment-wrap:nth-last-child(3)");
s && ("IntersectionObserver" in window ? (s => {
n = new IntersectionObserver((([t]) => {
t.isIntersecting && (i(), e.trigger(
"list-reach-bottom"))
}), {
root: t
}), n.observe(s)
})(s) : console.warn("IntersectionObserver api not supported"))
})), e.on("destroy", (() => {
i()
}))
}, e => {
const t = () => {
const t = e.get("list"),
n = e.conf.scrollRelativeTo && e.conf.scrollRelativeTo();
(n || window).scroll({
top: w(t.$el, n).top,
left: 0
})
};
e.on("inited", (() => {
e.on("list-goto-first", t)
})), e.on("destroy", (() => {
e.off("list-goto-first", t)
}))
}], e => {
e.on("conf-loaded", (() => {
zn({
getApi: () => e.getApi(),
pageKey: e.conf.pageKey,
countEl: e.conf.countEl,
pvEl: e.conf.pvEl,
pvAdd: !0
})
}))
}, e => {
e.on("conf-loaded", (() => {
const t = e.get("list");
e.conf.apiVersion && e.conf.versionCheck && !jn && function(e, t, n) {
const i = function(e, t) {
const n = e.split("."),
i = t.split(".");
for (let s = 0; s < 3; s++) {
const e = Number(n[s]),
t = Number(i[s]);
if (e > t) return 1;
if (t > e) return -1;
if (!Number.isNaN(e) && Number.isNaN(t)) return 1;
if (Number.isNaN(e) && !Number.isNaN(t)) return -1
}
return 0
}(t, n);
if (0 === i) return;
const s = y(
`<div>${D("updateMsg",{name:D(i<0?"frontend":"backend")})}<br/><br/><span style="color: var(--at-color-meta);">${D("currentVersion")}: ${D("frontend")} ${t} / ${D("backend")} ${n}</span><br/><br/></div>`
),
r = y(`<span style="cursor:pointer">${D("ignore")}</span>`);
r.onclick = () => {
Pt(e.$el.parentElement, null), jn = !0, e.ctx.fetch({
offset: 0
})
}, s.append(r), Pt(e.$el.parentElement, s,
'<span class="atk-warn-title">Artalk Warn</span>')
}(t, Fn, e.conf.apiVersion)
}))
}, e => {
let t;
const n = n => {
const i = [e.$root, e.get("layerManager").getEl()];
Nn || (Nn = window.matchMedia("(prefers-color-scheme: dark)")), "auto" === n ? (t ||
(t = e => Hn(i, e.matches), Nn.addEventListener("change", t)), Hn(i, Nn
.matches)) : (t && (Nn.removeEventListener("change", t), t = void 0),
Hn(i, n))
};
e.on("inited", (() => n(e.conf.darkMode))), e.on("conf-loaded", (e => n(e.darkMode))), e.on(
"dark-mode-changed", (e => n(e))), e.on("destroy", (() => {
t && (null == Nn || Nn.removeEventListener("change", t)), t = void 0
}))
}]];
class Vn {
constructor(e) {
g(this, "ctx"), g(this, "plugins", [...Qn]);
const t = xt(e, !0);
this.ctx = new St(t), Object.entries(Tn).forEach((([e, t]) => {
const n = t(this.ctx);
n && this.ctx.inject(e, n)
})), this.plugins.forEach((e => {
"function" == typeof e && e(this.ctx)
})), this.ctx.trigger("inited")
}
getConf() {
return this.ctx.getConf()
}
getEl() {
return this.ctx.$root
}
update(e) {
return this.ctx.updateConf(e), this
}
reload() {
this.ctx.reload()
}
destroy() {
this.ctx.trigger("destroy"), this.ctx.$root.remove()
}
on(e, t) {
this.ctx.on(e, t)
}
off(e, t) {
this.ctx.off(e, t)
}
trigger(e, t) {
this.ctx.trigger(e, t)
}
setDarkMode(e) {
this.ctx.setDarkMode(e)
}
static init(e) {
return new Vn(e)
}
static use(e) {
Qn.includes(e) || Qn.push(e)
}
static loadCountWidget(e) {
const t = xt(e, !0);
zn({
getApi: () => new W(Ct(t)),
pageKey: t.pageKey,
countEl: t.countEl,
pvEl: t.pvEl,
pvAdd: !1
})
}
get $root() {
return this.ctx.$root
}
get conf() {
return this.ctx.getConf()
}
}
const Gn = Vn.init,
Kn = Vn.use,
Zn = Vn.loadCountWidget;
e.default = Vn, e.init = Gn, e.loadCountWidget = Zn, e.use = Kn, Object.defineProperties(e, {
__esModule: {
value: !0
},
[Symbol.toStringTag]: {
value: "Module"
}
})
}));
2024-04-12 06:35:37 +00:00
//# sourceMappingURL=Artalk.js.map