mirror of
https://github.com/Sevichecc/Urara-Blog.git
synced 2025-05-02 13:19:30 +08:00
452 lines
13 KiB
Text
452 lines
13 KiB
Text
const n = /[^\0-\x7E]/;
|
|
const t = /[\x2E\u3002\uFF0E\uFF61]/g;
|
|
const o = { overflow: "Overflow Error", "not-basic": "Illegal Input", "invalid-input": "Invalid Input" };
|
|
const e = Math.floor;
|
|
const r = String.fromCharCode;
|
|
function s(n2) {
|
|
throw new RangeError(o[n2]);
|
|
}
|
|
const c = function(n2, t2) {
|
|
return n2 + 22 + 75 * (n2 < 26) - ((t2 != 0) << 5);
|
|
};
|
|
const u = function(n2, t2, o2) {
|
|
let r2 = 0;
|
|
for (n2 = o2 ? e(n2 / 700) : n2 >> 1, n2 += e(n2 / t2); n2 > 455; r2 += 36) {
|
|
n2 = e(n2 / 35);
|
|
}
|
|
return e(r2 + 36 * n2 / (n2 + 38));
|
|
};
|
|
function toASCII(o2) {
|
|
return function(n2, o3) {
|
|
const e2 = n2.split("@");
|
|
let r2 = "";
|
|
e2.length > 1 && (r2 = e2[0] + "@", n2 = e2[1]);
|
|
const s2 = function(n3, t2) {
|
|
const o4 = [];
|
|
let e3 = n3.length;
|
|
for (; e3--; ) {
|
|
o4[e3] = t2(n3[e3]);
|
|
}
|
|
return o4;
|
|
}((n2 = n2.replace(t, ".")).split("."), o3).join(".");
|
|
return r2 + s2;
|
|
}(o2, function(t2) {
|
|
return n.test(t2) ? "xn--" + function(n2) {
|
|
const t3 = [];
|
|
const o3 = (n2 = function(n3) {
|
|
const t4 = [];
|
|
let o4 = 0;
|
|
const e2 = n3.length;
|
|
for (; o4 < e2; ) {
|
|
const r2 = n3.charCodeAt(o4++);
|
|
if (r2 >= 55296 && r2 <= 56319 && o4 < e2) {
|
|
const e3 = n3.charCodeAt(o4++);
|
|
(64512 & e3) == 56320 ? t4.push(((1023 & r2) << 10) + (1023 & e3) + 65536) : (t4.push(r2), o4--);
|
|
} else {
|
|
t4.push(r2);
|
|
}
|
|
}
|
|
return t4;
|
|
}(n2)).length;
|
|
let f = 128;
|
|
let i = 0;
|
|
let l = 72;
|
|
for (const o4 of n2) {
|
|
o4 < 128 && t3.push(r(o4));
|
|
}
|
|
const h = t3.length;
|
|
let p = h;
|
|
for (h && t3.push("-"); p < o3; ) {
|
|
let o4 = 2147483647;
|
|
for (const t4 of n2) {
|
|
t4 >= f && t4 < o4 && (o4 = t4);
|
|
}
|
|
const a = p + 1;
|
|
o4 - f > e((2147483647 - i) / a) && s("overflow"), i += (o4 - f) * a, f = o4;
|
|
for (const o5 of n2) {
|
|
if (o5 < f && ++i > 2147483647 && s("overflow"), o5 == f) {
|
|
let n3 = i;
|
|
for (let o6 = 36; ; o6 += 36) {
|
|
const s2 = o6 <= l ? 1 : o6 >= l + 26 ? 26 : o6 - l;
|
|
if (n3 < s2) {
|
|
break;
|
|
}
|
|
const u2 = n3 - s2;
|
|
const f2 = 36 - s2;
|
|
t3.push(r(c(s2 + u2 % f2, 0))), n3 = e(u2 / f2);
|
|
}
|
|
t3.push(r(c(n3, 0))), l = u(i, a, p == h), i = 0, ++p;
|
|
}
|
|
}
|
|
++i, ++f;
|
|
}
|
|
return t3.join("");
|
|
}(t2) : t2;
|
|
});
|
|
}
|
|
|
|
const HASH_RE = /#/g;
|
|
const AMPERSAND_RE = /&/g;
|
|
const SLASH_RE = /\//g;
|
|
const EQUAL_RE = /=/g;
|
|
const IM_RE = /\?/g;
|
|
const PLUS_RE = /\+/g;
|
|
const ENC_BRACKET_OPEN_RE = /%5B/gi;
|
|
const ENC_BRACKET_CLOSE_RE = /%5D/gi;
|
|
const ENC_CARET_RE = /%5E/gi;
|
|
const ENC_BACKTICK_RE = /%60/gi;
|
|
const ENC_CURLY_OPEN_RE = /%7B/gi;
|
|
const ENC_PIPE_RE = /%7C/gi;
|
|
const ENC_CURLY_CLOSE_RE = /%7D/gi;
|
|
const ENC_SPACE_RE = /%20/gi;
|
|
const ENC_SLASH_RE = /%2F/gi;
|
|
const ENC_ENC_SLASH_RE = /%252F/gi;
|
|
function encode(text) {
|
|
return encodeURI("" + text).replace(ENC_PIPE_RE, "|").replace(ENC_BRACKET_OPEN_RE, "[").replace(ENC_BRACKET_CLOSE_RE, "]");
|
|
}
|
|
function encodeHash(text) {
|
|
return encode(text).replace(ENC_CURLY_OPEN_RE, "{").replace(ENC_CURLY_CLOSE_RE, "}").replace(ENC_CARET_RE, "^");
|
|
}
|
|
function encodeQueryValue(text) {
|
|
return encode(text).replace(PLUS_RE, "%2B").replace(ENC_SPACE_RE, "+").replace(HASH_RE, "%23").replace(AMPERSAND_RE, "%26").replace(ENC_BACKTICK_RE, "`").replace(ENC_CURLY_OPEN_RE, "{").replace(ENC_CURLY_CLOSE_RE, "}").replace(ENC_CARET_RE, "^");
|
|
}
|
|
function encodeQueryKey(text) {
|
|
return encodeQueryValue(text).replace(EQUAL_RE, "%3D");
|
|
}
|
|
function encodePath(text) {
|
|
return encode(text).replace(HASH_RE, "%23").replace(IM_RE, "%3F").replace(ENC_ENC_SLASH_RE, "%2F").replace(AMPERSAND_RE, "%26").replace(PLUS_RE, "%2B");
|
|
}
|
|
function encodeParam(text) {
|
|
return encodePath(text).replace(SLASH_RE, "%2F");
|
|
}
|
|
function decode(text = "") {
|
|
try {
|
|
return decodeURIComponent("" + text);
|
|
} catch (_err) {
|
|
return "" + text;
|
|
}
|
|
}
|
|
function decodePath(text) {
|
|
return decode(text.replace(ENC_SLASH_RE, "%252F"));
|
|
}
|
|
function decodeQueryValue(text) {
|
|
return decode(text.replace(PLUS_RE, " "));
|
|
}
|
|
function encodeHost(name = "") {
|
|
return toASCII(name);
|
|
}
|
|
|
|
function parseQuery(paramsStr = "") {
|
|
const obj = {};
|
|
if (paramsStr[0] === "?") {
|
|
paramsStr = paramsStr.substr(1);
|
|
}
|
|
for (const param of paramsStr.split("&")) {
|
|
const s = param.match(/([^=]+)=?(.*)/) || [];
|
|
if (s.length < 2) {
|
|
continue;
|
|
}
|
|
const key = decode(s[1]);
|
|
if (key === "__proto__" || key === "constructor") {
|
|
continue;
|
|
}
|
|
const value = decodeQueryValue(s[2] || "");
|
|
if (obj[key]) {
|
|
if (Array.isArray(obj[key])) {
|
|
obj[key].push(value);
|
|
} else {
|
|
obj[key] = [obj[key], value];
|
|
}
|
|
} else {
|
|
obj[key] = value;
|
|
}
|
|
}
|
|
return obj;
|
|
}
|
|
function encodeQueryItem(key, val) {
|
|
if (typeof val === "number" || typeof val === "boolean") {
|
|
val = String(val);
|
|
}
|
|
if (!val) {
|
|
return encodeQueryKey(key);
|
|
}
|
|
if (Array.isArray(val)) {
|
|
return val.map((_val) => `${encodeQueryKey(key)}=${encodeQueryValue(_val)}`).join("&");
|
|
}
|
|
return `${encodeQueryKey(key)}=${encodeQueryValue(val)}`;
|
|
}
|
|
function stringifyQuery(query) {
|
|
return Object.keys(query).map((k) => encodeQueryItem(k, query[k])).join("&");
|
|
}
|
|
|
|
class $URL {
|
|
constructor(input = "") {
|
|
this.query = {};
|
|
if (typeof input !== "string") {
|
|
throw new TypeError(`URL input should be string received ${typeof input} (${input})`);
|
|
}
|
|
const parsed = parseURL(input);
|
|
this.protocol = decode(parsed.protocol);
|
|
this.host = decode(parsed.host);
|
|
this.auth = decode(parsed.auth);
|
|
this.pathname = decodePath(parsed.pathname);
|
|
this.query = parseQuery(parsed.search);
|
|
this.hash = decode(parsed.hash);
|
|
}
|
|
get hostname() {
|
|
return parseHost(this.host).hostname;
|
|
}
|
|
get port() {
|
|
return parseHost(this.host).port || "";
|
|
}
|
|
get username() {
|
|
return parseAuth(this.auth).username;
|
|
}
|
|
get password() {
|
|
return parseAuth(this.auth).password || "";
|
|
}
|
|
get hasProtocol() {
|
|
return this.protocol.length;
|
|
}
|
|
get isAbsolute() {
|
|
return this.hasProtocol || this.pathname[0] === "/";
|
|
}
|
|
get search() {
|
|
const q = stringifyQuery(this.query);
|
|
return q.length ? "?" + q : "";
|
|
}
|
|
get searchParams() {
|
|
const p = new URLSearchParams();
|
|
for (const name in this.query) {
|
|
const value = this.query[name];
|
|
if (Array.isArray(value)) {
|
|
value.forEach((v) => p.append(name, v));
|
|
} else {
|
|
p.append(name, value || "");
|
|
}
|
|
}
|
|
return p;
|
|
}
|
|
get origin() {
|
|
return (this.protocol ? this.protocol + "//" : "") + encodeHost(this.host);
|
|
}
|
|
get fullpath() {
|
|
return encodePath(this.pathname) + this.search + encodeHash(this.hash);
|
|
}
|
|
get encodedAuth() {
|
|
if (!this.auth) {
|
|
return "";
|
|
}
|
|
const { username, password } = parseAuth(this.auth);
|
|
return encodeURIComponent(username) + (password ? ":" + encodeURIComponent(password) : "");
|
|
}
|
|
get href() {
|
|
const auth = this.encodedAuth;
|
|
const originWithAuth = (this.protocol ? this.protocol + "//" : "") + (auth ? auth + "@" : "") + encodeHost(this.host);
|
|
return this.hasProtocol && this.isAbsolute ? originWithAuth + this.fullpath : this.fullpath;
|
|
}
|
|
append(url) {
|
|
if (url.hasProtocol) {
|
|
throw new Error("Cannot append a URL with protocol");
|
|
}
|
|
Object.assign(this.query, url.query);
|
|
if (url.pathname) {
|
|
this.pathname = withTrailingSlash(this.pathname) + withoutLeadingSlash(url.pathname);
|
|
}
|
|
if (url.hash) {
|
|
this.hash = url.hash;
|
|
}
|
|
}
|
|
toJSON() {
|
|
return this.href;
|
|
}
|
|
toString() {
|
|
return this.href;
|
|
}
|
|
}
|
|
|
|
function isRelative(inputStr) {
|
|
return ["./", "../"].some((str) => inputStr.startsWith(str));
|
|
}
|
|
const PROTOCOL_REGEX = /^\w+:(\/\/)?/;
|
|
const PROTOCOL_RELATIVE_REGEX = /^\/\/[^/]+/;
|
|
function hasProtocol(inputStr, acceptProtocolRelative = false) {
|
|
return PROTOCOL_REGEX.test(inputStr) || acceptProtocolRelative && PROTOCOL_RELATIVE_REGEX.test(inputStr);
|
|
}
|
|
const TRAILING_SLASH_RE = /\/$|\/\?/;
|
|
function hasTrailingSlash(input = "", queryParams = false) {
|
|
if (!queryParams) {
|
|
return input.endsWith("/");
|
|
}
|
|
return TRAILING_SLASH_RE.test(input);
|
|
}
|
|
function withoutTrailingSlash(input = "", queryParams = false) {
|
|
if (!queryParams) {
|
|
return (hasTrailingSlash(input) ? input.slice(0, -1) : input) || "/";
|
|
}
|
|
if (!hasTrailingSlash(input, true)) {
|
|
return input || "/";
|
|
}
|
|
const [s0, ...s] = input.split("?");
|
|
return (s0.slice(0, -1) || "/") + (s.length ? `?${s.join("?")}` : "");
|
|
}
|
|
function withTrailingSlash(input = "", queryParams = false) {
|
|
if (!queryParams) {
|
|
return input.endsWith("/") ? input : input + "/";
|
|
}
|
|
if (hasTrailingSlash(input, true)) {
|
|
return input || "/";
|
|
}
|
|
const [s0, ...s] = input.split("?");
|
|
return s0 + "/" + (s.length ? `?${s.join("?")}` : "");
|
|
}
|
|
function hasLeadingSlash(input = "") {
|
|
return input.startsWith("/");
|
|
}
|
|
function withoutLeadingSlash(input = "") {
|
|
return (hasLeadingSlash(input) ? input.substr(1) : input) || "/";
|
|
}
|
|
function withLeadingSlash(input = "") {
|
|
return hasLeadingSlash(input) ? input : "/" + input;
|
|
}
|
|
function cleanDoubleSlashes(input = "") {
|
|
return input.split("://").map((str) => str.replace(/\/{2,}/g, "/")).join("://");
|
|
}
|
|
function withBase(input, base) {
|
|
if (isEmptyURL(base)) {
|
|
return input;
|
|
}
|
|
const _base = withoutTrailingSlash(base);
|
|
if (input.startsWith(_base)) {
|
|
return input;
|
|
}
|
|
return joinURL(_base, input);
|
|
}
|
|
function withoutBase(input, base) {
|
|
if (isEmptyURL(base)) {
|
|
return input;
|
|
}
|
|
const _base = withoutTrailingSlash(base);
|
|
if (!input.startsWith(_base)) {
|
|
return input;
|
|
}
|
|
const trimmed = input.substring(_base.length);
|
|
return trimmed[0] === "/" ? trimmed : "/" + trimmed;
|
|
}
|
|
function withQuery(input, query) {
|
|
const parsed = parseURL(input);
|
|
const mergedQuery = { ...parseQuery(parsed.search), ...query };
|
|
parsed.search = stringifyQuery(mergedQuery);
|
|
return stringifyParsedURL(parsed);
|
|
}
|
|
function getQuery(input) {
|
|
return parseQuery(parseURL(input).search);
|
|
}
|
|
function isEmptyURL(url) {
|
|
return !url || url === "/";
|
|
}
|
|
function isNonEmptyURL(url) {
|
|
return url && url !== "/";
|
|
}
|
|
function joinURL(base, ...input) {
|
|
let url = base || "";
|
|
for (const i of input.filter(isNonEmptyURL)) {
|
|
url = url ? withTrailingSlash(url) + withoutLeadingSlash(i) : i;
|
|
}
|
|
return url;
|
|
}
|
|
function withHttp(input) {
|
|
return withProtocol(input, "http://");
|
|
}
|
|
function withHttps(input) {
|
|
return withProtocol(input, "https://");
|
|
}
|
|
function withoutProtocol(input) {
|
|
return withProtocol(input, "");
|
|
}
|
|
function withProtocol(input, protocol) {
|
|
const match = input.match(PROTOCOL_REGEX);
|
|
if (!match) {
|
|
return protocol + input;
|
|
}
|
|
return protocol + input.substring(match[0].length);
|
|
}
|
|
function createURL(input) {
|
|
return new $URL(input);
|
|
}
|
|
function normalizeURL(input) {
|
|
return createURL(input).toString();
|
|
}
|
|
function resolveURL(base, ...input) {
|
|
const url = createURL(base);
|
|
for (const i of input.filter(isNonEmptyURL)) {
|
|
url.append(createURL(i));
|
|
}
|
|
return url.toString();
|
|
}
|
|
function isSamePath(p1, p2) {
|
|
return decode(withoutTrailingSlash(p1)) === decode(withoutTrailingSlash(p2));
|
|
}
|
|
function isEqual(a, b, opts = {}) {
|
|
if (!opts.trailingSlash) {
|
|
a = withTrailingSlash(a);
|
|
b = withTrailingSlash(b);
|
|
}
|
|
if (!opts.leadingSlash) {
|
|
a = withLeadingSlash(a);
|
|
b = withLeadingSlash(b);
|
|
}
|
|
if (!opts.encoding) {
|
|
a = decode(a);
|
|
b = decode(b);
|
|
}
|
|
return a === b;
|
|
}
|
|
|
|
function parseURL(input = "", defaultProto) {
|
|
if (!hasProtocol(input, true)) {
|
|
return defaultProto ? parseURL(defaultProto + input) : parsePath(input);
|
|
}
|
|
const [protocol = "", auth, hostAndPath = ""] = (input.replace(/\\/g, "/").match(/([^:/]+:)?\/\/([^/@]+@)?(.*)/) || []).splice(1);
|
|
const [host = "", path = ""] = (hostAndPath.match(/([^/?#]*)(.*)?/) || []).splice(1);
|
|
const { pathname, search, hash } = parsePath(path);
|
|
return {
|
|
protocol,
|
|
auth: auth ? auth.substr(0, auth.length - 1) : "",
|
|
host,
|
|
pathname,
|
|
search,
|
|
hash
|
|
};
|
|
}
|
|
function parsePath(input = "") {
|
|
const [pathname = "", search = "", hash = ""] = (input.match(/([^#?]*)(\?[^#]*)?(#.*)?/) || []).splice(1);
|
|
return {
|
|
pathname,
|
|
search,
|
|
hash
|
|
};
|
|
}
|
|
function parseAuth(input = "") {
|
|
const [username, password] = input.split(":");
|
|
return {
|
|
username: decode(username),
|
|
password: decode(password)
|
|
};
|
|
}
|
|
function parseHost(input = "") {
|
|
const [hostname, port] = (input.match(/([^/]*)(:0-9+)?/) || []).splice(1);
|
|
return {
|
|
hostname: decode(hostname),
|
|
port
|
|
};
|
|
}
|
|
function stringifyParsedURL(parsed) {
|
|
const fullpath = parsed.pathname + (parsed.search ? (parsed.search.startsWith("?") ? "" : "?") + parsed.search : "") + parsed.hash;
|
|
if (!parsed.protocol) {
|
|
return fullpath;
|
|
}
|
|
return parsed.protocol + "//" + (parsed.auth ? parsed.auth + "@" : "") + parsed.host + fullpath;
|
|
}
|
|
|
|
export { $URL, cleanDoubleSlashes, createURL, decode, decodePath, decodeQueryValue, encode, encodeHash, encodeHost, encodeParam, encodePath, encodeQueryItem, encodeQueryKey, encodeQueryValue, getQuery, hasLeadingSlash, hasProtocol, hasTrailingSlash, isEmptyURL, isEqual, isNonEmptyURL, isRelative, isSamePath, joinURL, normalizeURL, parseAuth, parseHost, parsePath, parseQuery, parseURL, resolveURL, stringifyParsedURL, stringifyQuery, withBase, withHttp, withHttps, withLeadingSlash, withProtocol, withQuery, withTrailingSlash, withoutBase, withoutLeadingSlash, withoutProtocol, withoutTrailingSlash };
|