minutool 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"minutool.js","sources":["../src/array.ts","../src/string.ts","../src/base64.ts","../src/browser.ts","../src/cookie.ts","../src/util.ts","../src/math.ts","../src/dom.ts","../src/file.ts","../src/html.ts","../src/img.ts","../src/md5.ts","../src/mime.ts","../src/net.ts","../src/object.ts","../src/time.ts"],"sourcesContent":["/**\r\n * 从数组中提取指定列的值\r\n * @param {T[]} arr - 源数组\r\n * @param {keyof T} col_name - 列名(对象的键)\r\n * @returns {any[]} 提取的列值数组\r\n * @example\r\n * arrayColumn([{id: 1, name: 'A'}, {id: 2, name: 'B'}], 'name') // ['A', 'B']\r\n */\r\nexport const arrayColumn = <T = any>(arr: T[], col_name: keyof T): any[] => {\r\n\tlet data: any[] = [];\r\n\tfor(let i in arr){\r\n\t\tdata.push(arr[i][col_name]);\r\n\t}\r\n\treturn data;\r\n};\r\n\r\n/**\r\n * 查找数组中指定值的索引\r\n * @param {T[]} arr - 源数组\r\n * @param {T} val - 要查找的值\r\n * @returns {string|null} 返回索引字符串,未找到返回 null\r\n * @example\r\n * arrayIndex(['a', 'b', 'c'], 'b') // '1'\r\n */\r\nexport const arrayIndex = <T = any>(arr: T[], val: T): string | null => {\r\n\tfor(let i in arr){\r\n\t\tif(arr[i] === val){\r\n\t\t\treturn i;\r\n\t\t}\r\n\t}\r\n\treturn null;\r\n};\r\n\r\n\r\n/**\r\n * 数组去重\r\n * @param {T[]} arr - 源数组\r\n * @returns {T[]} 去重后的数组\r\n * @example\r\n * arrayDistinct([1, 2, 2, 3, 3, 3]) // [1, 2, 3]\r\n */\r\nexport const arrayDistinct = <T = any>(arr: T[]): T[] => {\r\n\tlet tmpMap = new Map();\r\n\treturn arr.filter((item: T) => {\r\n\t\tif(!tmpMap.has(item)){\r\n\t\t\ttmpMap.set(item, true);\r\n\t\t\treturn true;\r\n\t\t}\r\n\t});\r\n}\r\n\r\n\r\n/**\r\n * 按指定键对数组进行分组\r\n * @param {T[]} arr - 源数组\r\n * @param {keyof T} by_key - 分组依据的键\r\n * @param {boolean} [limit] - 是否限制每组只保留一个元素\r\n * @returns {Record<string, T[]> | Record<string, T>} 分组后的对象\r\n * @example\r\n * arrayGroup([{type: 'A', val: 1}, {type: 'A', val: 2}], 'type')\r\n * // { A: [{type: 'A', val: 1}, {type: 'A', val: 2}] }\r\n */\r\nexport const arrayGroup = <T extends Record<string, any>>(arr: T[], by_key: keyof T, limit?: boolean): Record<string, T[]> | Record<string, T> => {\r\n\tif(!arr || !arr.length){\r\n\t\treturn arr as any;\r\n\t}\r\n\tlet tmp_rst: Record<string, T[]> = {};\r\n\tarr.forEach((item: T) => {\r\n\t\tlet k = item[by_key];\r\n\t\tif(!tmp_rst[k]){\r\n\t\t\ttmp_rst[k] = [];\r\n\t\t}\r\n\t\ttmp_rst[k].push(item);\r\n\t});\r\n\tif(!limit){\r\n\t\treturn tmp_rst;\r\n\t}\r\n\tlet rst: Record<string, T> = {};\r\n\tfor(let i in tmp_rst){\r\n\t\trst[i] = tmp_rst[i][0];\r\n\t}\r\n\treturn rst;\r\n};\r\n\r\n\r\n/**\r\n * 按照对象的键进行字母顺序排序\r\n * @param {T} obj - 源对象\r\n * @returns {T} 键排序后的对象\r\n * @example\r\n * arraySortByKey({c: 3, a: 1, b: 2}) // {a: 1, b: 2, c: 3}\r\n */\r\nexport const arraySortByKey = <T extends Record<string, any>>(obj: T): T => {\r\n\treturn Object.keys(obj).sort().reduce(function(result: Record<string, any>, key: string){\r\n\t\tresult[key] = obj[key];\r\n\t\treturn result;\r\n\t}, {} as Record<string, any>) as T;\r\n}\r\n\r\n\r\n/**\r\n * 将数组分割成指定大小的块\r\n * @param {T[]} list - 源数组\r\n * @param {number} size - 每块的大小\r\n * @returns {T[][]} 分块后的二维数组\r\n * @example\r\n * arrayChunk([1, 2, 3, 4, 5], 2) // [[1, 2], [3, 4], [5]]\r\n */\r\nexport const arrayChunk = <T = any>(list: T[], size: number): T[][] => {\r\n\tlet len = list.length;\r\n\tif(size < 1 || !len){\r\n\t\treturn [];\r\n\t}\r\n\tif(size > len){\r\n\t\treturn [list];\r\n\t}\r\n\tlet res = [];\r\n\tlet integer = Math.floor(len / size);\r\n\tlet rest = len % size;\r\n\tfor(let i = 1; i <= integer; i++){\r\n\t\tres.push(list.splice(0, size));\r\n\t}\r\n\tif(rest){\r\n\t\tres.push(list.splice(0, rest));\r\n\t}\r\n\treturn res;\r\n}\r\n\r\n/**\r\n * 从数组末尾开始移除值为 falsy 的元素,直到遇到第一个 truthy 元素\r\n * @param {any[]} arr - 要处理的数组\r\n * @returns {any[]} 处理后的数组\r\n * @example\r\n * arrayTrimTail([1, 2, 0, false, null]) // [1, 2]\r\n */\r\nexport const arrayTrimTail = (arr: any[]) => {\r\n let lastNonZeroIndex = -1;\r\n for (let i = arr.length - 1; i >= 0; i--) {\r\n if (arr[i]) {\r\n lastNonZeroIndex = i;\r\n break;\r\n }\r\n }\r\n return arr.slice(0, lastNonZeroIndex + 1);\r\n};\r\n","/**\r\n * 首字母大写\r\n * @param str - 输入字符串\r\n * @returns 首字母大写的字符串\r\n * @example\r\n * capitalize('hello') // 'Hello'\r\n */\r\nexport function capitalize(str: string): string {\r\n if (!str) return str;\r\n return str.charAt(0).toUpperCase() + str.slice(1);\r\n}\r\n\r\n/**\r\n * 反转义字符串\r\n * @param str\r\n * @returns {string}\r\n * @description:\r\n * discuss at: https://locutus.io/php/stripslashes/\r\n * original by: Kevin van Zonneveld (https://kvz.io)\r\n * improved by: Ates Goral (https://magnetiq.com)\r\n * improved by: marrtins\r\n * improved by: rezna\r\n * fixed by: Mick@el\r\n * bugfixed by: Onno Marsman (https://twitter.com/onnomarsman)\r\n * bugfixed by: Brett Zamir (https://brett-zamir.me)\r\n * input by: Rick Waldron\r\n * input by: Brant Messenger (https://www.brantmessenger.com/)\r\n * reimplemented by: Brett Zamir (https://brett-zamir.me)\r\n * example 1: stripslashes('Kevin\\'s code')\r\n * returns 1: \"Kevin's code\"\r\n * example 2: stripslashes('Kevin\\\\\\'s code')\r\n * returns 2: \"Kevin\\'s code\"\r\n */\r\nexport const stripSlashes = (str: string): string => {\r\n return (str + \"\").replace(/\\\\(.?)/g, function (_s: string, n1: string) {\r\n switch (n1) {\r\n case \"\\\\\":\r\n return \"\\\\\";\r\n case \"0\":\r\n return \"\\u0000\";\r\n case \"\":\r\n return \"\";\r\n default:\r\n return n1;\r\n }\r\n });\r\n};\r\n\r\n/**\r\n * 中英文字符串截取(中文按照 2 个字符长度计算)\r\n * @param {string} str - 要截取的字符串\r\n * @param {number} len - 截取长度\r\n * @param {string} [eclipse_text='...'] - 省略符,默认为 '...'\r\n * @returns {string} 返回截取后的字符串\r\n * @example\r\n * cutString('中文English', 6, '...') // '中文E...'\r\n */\r\nexport const cutString = (str: string, len: number, eclipse_text: string = \"...\"): string => {\r\n let r = /[^\\x00-\\xff]/g;\r\n if (str.replace(r, \"mm\").length <= len) {\r\n return str;\r\n }\r\n let m = Math.floor(len / 2);\r\n for (let i = m; i < str.length; i++) {\r\n if (str.substr(0, i).replace(r, \"mm\").length >= len) {\r\n return str.substr(0, i) + eclipse_text;\r\n }\r\n }\r\n return str;\r\n};\r\n\r\n/**\r\n * 混合ES6模板字符串\r\n * @example extract(\"hello ${user_name}\", {user_name:\"Jack\"});\r\n * @param {String} es_template 模板\r\n * @param {Object} params 数据对象\r\n * @return {String}\r\n */\r\nexport const extract = (es_template: string, params: Record<string, any>): string => {\r\n const names = Object.keys(params);\r\n const values = Object.values(params);\r\n return new Function(...names, `return \\`${es_template}\\`;`)(...values);\r\n};\r\n\r\n/**\r\n * 驼峰命名转换\r\n * @param str - 输入字符串\r\n * @returns 驼峰命名的字符串\r\n * @example\r\n * camelCase('hello-world') // 'helloWorld'\r\n * camelCase('hello_world') // 'helloWorld'\r\n */\r\nexport function camelCase(str: string): string {\r\n return str.replace(/[-_](.)/g, (_, char) => char.toUpperCase());\r\n}\r\n\r\n/**\r\n * 短横线命名转换\r\n * @param str - 输入字符串\r\n * @returns 短横线命名的字符串\r\n * @example\r\n * kebabCase('helloWorld') // 'hello-world'\r\n * kebabCase('HelloWorld') // 'hello-world'\r\n */\r\nexport function kebabCase(str: string): string {\r\n return str\r\n .replace(/([a-z])([A-Z])/g, \"$1-$2\")\r\n .replace(/[\\s_]+/g, \"-\")\r\n .toLowerCase();\r\n}\r\n\r\n/**\r\n * 截断字符串\r\n * @param str - 输入字符串\r\n * @param length - 最大长度\r\n * @param suffix - 后缀,默认为 '...'\r\n * @returns 截断后的字符串\r\n * @example\r\n * truncate('hello world', 5) // 'hello...'\r\n */\r\nexport function truncate(str: string, length: number, suffix: string = \"...\"): string {\r\n if (str.length <= length) return str;\r\n return str.slice(0, length) + suffix;\r\n}\r\n\r\n/**\r\n * 正则表达式转义(将特殊字符转义)\r\n * @param {string} str - 要转义的字符串\r\n * @returns {string} 返回转义后的字符串\r\n * @example\r\n * regQuote('a.b') // 'a\\\\.b'\r\n */\r\nexport const regQuote = (str: string): string => {\r\n return (str + \"\").replace(/([\\\\\\.\\+\\*\\?\\[\\^\\]\\$\\(\\)\\{\\}\\=\\!\\<\\>\\|\\:])/g, \"\\\\$1\");\r\n};\r\n\r\n/**\r\n * UTF-8 解码\r\n * @param {string} srcStr - 要解码的字符串\r\n * @returns {string} 返回解码后的字符串\r\n * @example\r\n * utf8Decode(encodedStr) // 'decoded string'\r\n */\r\nexport const utf8Decode = (srcStr: string): string => {\r\n let t = \"\";\r\n let n = 0;\r\n let r = 0,\r\n c2 = 0,\r\n c3 = 0;\r\n while (n < srcStr.length) {\r\n r = srcStr.charCodeAt(n);\r\n if (r < 128) {\r\n t += String.fromCharCode(r);\r\n n++;\r\n } else if (r > 191 && r < 224) {\r\n c2 = srcStr.charCodeAt(n + 1);\r\n t += String.fromCharCode(((r & 31) << 6) | (c2 & 63));\r\n n += 2;\r\n } else {\r\n c2 = srcStr.charCodeAt(n + 1);\r\n c3 = srcStr.charCodeAt(n + 2);\r\n t += String.fromCharCode(((r & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));\r\n n += 3;\r\n }\r\n }\r\n return t;\r\n};\r\n\r\n/**\r\n * UTF-8 编码\r\n * @param {string} srcStr - 要编码的字符串\r\n * @returns {string} 返回编码后的字符串\r\n * @example\r\n * utf8Encode('string') // 'encoded string'\r\n */\r\nexport const utf8Encode = (srcStr: string): string => {\r\n srcStr = srcStr.replace(/\\r\\n/g, \"n\");\r\n let t = \"\";\r\n for (let n = 0; n < srcStr.length; n++) {\r\n let r = srcStr.charCodeAt(n);\r\n if (r < 128) {\r\n t += String.fromCharCode(r);\r\n } else if (r > 127 && r < 2048) {\r\n t += String.fromCharCode((r >> 6) | 192);\r\n t += String.fromCharCode((r & 63) | 128);\r\n } else {\r\n t += String.fromCharCode((r >> 12) | 224);\r\n t += String.fromCharCode(((r >> 6) & 63) | 128);\r\n t += String.fromCharCode((r & 63) | 128);\r\n }\r\n }\r\n return t;\r\n};\r\n\r\n/**\r\n * 获取 UTF-8 字符串长度(一个中文字按照 3 个字数计算)\r\n * @param {string} str - 要计算的字符串\r\n * @returns {number} 返回字符串长度\r\n * @example\r\n * getUTF8StrLen('中文') // 6\r\n */\r\nexport const getUTF8StrLen = (str: string): number => {\r\n let realLength = 0;\r\n let len = str.length;\r\n let charCode = -1;\r\n for (let i = 0; i < len; i++) {\r\n charCode = str.charCodeAt(i);\r\n if (charCode >= 0 && charCode <= 128) {\r\n realLength += 1;\r\n } else {\r\n realLength += 3;\r\n }\r\n }\r\n return realLength;\r\n};\r\nconst DEFAULT_RANDOM_STRING = \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890\";\r\n\r\n/**\r\n * 产生随机字符串\r\n * @param {Number} length\r\n * @param {String} sourceStr\r\n * @returns {String}\r\n */\r\nexport const randomString = (length = 6, sourceStr = DEFAULT_RANDOM_STRING) => {\r\n let codes = \"\";\r\n for (let i = 0; i < length; i++) {\r\n let rnd = Math.round(Math.random() * (sourceStr.length - 1));\r\n codes += sourceStr.substring(rnd, rnd + 1);\r\n }\r\n return codes;\r\n};\r\n\r\n/**\r\n * 产生随机单词\r\n * @param {Number} count 单词数量\r\n * @param {Number} letterMax 每个单词最大字符数量\r\n * @return {String[]} 单词列表\r\n */\r\nexport const randomWords = (count = 1, letterMax = 8) => {\r\n let words = [];\r\n const possible = \"bcdfghjklmnpqrstvwxyz\";\r\n const possibleVowels = \"aeiou\";\r\n\r\n while (count-- > 0) {\r\n let word = \"\";\r\n for (let i = 0; i < letterMax; i = i + 3) {\r\n word += possible[Math.floor(Math.random() * possible.length)];\r\n word += possibleVowels[Math.floor(Math.random() * possibleVowels.length)];\r\n word += possible[Math.floor(Math.random() * possible.length)];\r\n }\r\n words.push(word);\r\n }\r\n return words;\r\n};\r\n/**\r\n * 字符串转成首字母大写(Pascal Case)\r\n * @param {string} str - 要转换的字符串\r\n * @param {boolean} [capitalize_first=false] - 是否将第一个单词首字母大写\r\n * @returns {string} 返回转换后的字符串\r\n * @example\r\n * strToPascalCase('hello-world', true) // 'HelloWorld'\r\n */\r\nexport const strToPascalCase = (str: string, capitalize_first: boolean = false): string => {\r\n let words: string[] = [];\r\n str.replace(/[-_\\s+]/g, \" \")\r\n .split(\" \")\r\n .forEach((word, idx) => {\r\n words.push(idx === 0 && !capitalize_first ? word : capitalize(word));\r\n });\r\n return words.join(\"\");\r\n};\r\n\r\n// trim 方向常量\r\nexport const TRIM_BOTH = 0;\r\nexport const TRIM_LEFT = 1;\r\nexport const TRIM_RIGHT = 2;\r\n\r\n/**\r\n * 去除字符串首尾指定字符或空白\r\n * @param {string} str - 源字符串\r\n * @param {string} [chars=''] - 指定字符,默认为空白\r\n * @param {number} [dir=TRIM_BOTH] - 方向(TRIM_BOTH/TRIM_LEFT/TRIM_RIGHT)\r\n * @returns {string} 返回去除后的字符串\r\n * @example\r\n * trim('__hello__', '_') // 'hello'\r\n */\r\nexport const trim = (str: string, chars: string = \"\", dir: number = TRIM_BOTH): string => {\r\n if (chars.length) {\r\n let regLeft = new RegExp(\"^[\" + regQuote(chars) + \"]+\"),\r\n regRight = new RegExp(\"[\" + regQuote(chars) + \"]+$\");\r\n return dir === TRIM_LEFT ? str.replace(regLeft, \"\") : dir === TRIM_RIGHT ? str.replace(regRight, \"\") : str.replace(regLeft, \"\").replace(regRight, \"\");\r\n } else {\r\n return dir === TRIM_BOTH ? str.trim() : dir === TRIM_LEFT ? str.trimStart() : str.trimEnd();\r\n }\r\n};\r\n\r\n/**\r\n * 将字符串分割成指定长度的数组\r\n * @param {string} str - 要分割的字符串\r\n * @param {number} size - 每段的长度\r\n * @returns {string[]} 返回分割后的数组\r\n * @example\r\n * strChunk('abcdef', 2) // ['ab', 'cd', 'ef']\r\n */\r\nexport const strChunk = (str: string, size: number): string[] => {\r\n let ret: string[] = [];\r\n for (let i = 0; i < str.length; i += size) {\r\n ret.push(str.slice(i, i + size));\r\n }\r\n return ret;\r\n};\r\n","import { utf8Decode, utf8Encode } from \"./string\";\r\n\r\nconst BASE64_KEY_STR = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\";\r\n\r\n/**\r\n * Base64 解码\r\n * @param {string} text - Base64 编码的字符串\r\n * @returns {string} 解码后的字符串\r\n * @example\r\n * base64Decode('SGVsbG8=') // 'Hello'\r\n */\r\nexport const base64Decode = (text: string): string => {\r\n let t = \"\";\r\n let n, r, i;\r\n let s, o, u, a;\r\n let f = 0;\r\n text = text.replace(/\\+\\+[++^A-Za-z0-9+/=]/g, \"\");\r\n while (f < text.length) {\r\n s = BASE64_KEY_STR.indexOf(text.charAt(f++));\r\n o = BASE64_KEY_STR.indexOf(text.charAt(f++));\r\n u = BASE64_KEY_STR.indexOf(text.charAt(f++));\r\n a = BASE64_KEY_STR.indexOf(text.charAt(f++));\r\n n = (s << 2) | (o >> 4);\r\n r = ((o & 15) << 4) | (u >> 2);\r\n i = ((u & 3) << 6) | a;\r\n t = t + String.fromCharCode(n);\r\n if (u !== 64) {\r\n t = t + String.fromCharCode(r);\r\n }\r\n if (a !== 64) {\r\n t = t + String.fromCharCode(i);\r\n }\r\n }\r\n t = utf8Decode(t);\r\n return t;\r\n};\r\n\r\n/**\r\n * URL 安全模式进行 Base64 编码(替换 + 和 / 为 - 和 _)\r\n * @param {string} text - 要编码的字符串\r\n * @returns {string} URL 安全的 Base64 编码字符串\r\n * @example\r\n * base64UrlSafeEncode('test') // URL安全的Base64字符串\r\n */\r\nexport const base64UrlSafeEncode = (text: string): string => {\r\n return utf8Encode(text).replace(\"+\", \"-\").replace(\"/\", \"_\");\r\n};\r\n\r\n/**\r\n * 字符串转 Base64 编码\r\n * @param {string} text - 要编码的字符串\r\n * @returns {string} Base64 编码后的字符串\r\n * @example\r\n * Base64Encode('Hello') // 'SGVsbG8='\r\n */\r\nexport const Base64Encode = (text: string): string => {\r\n let t = \"\";\r\n let n, r, i, s, o, u, a;\r\n let f = 0;\r\n text = utf8Encode(text);\r\n while (f < text.length) {\r\n n = text.charCodeAt(f++);\r\n r = text.charCodeAt(f++);\r\n i = text.charCodeAt(f++);\r\n s = n >> 2;\r\n o = ((n & 3) << 4) | (r >> 4);\r\n u = ((r & 15) << 2) | (i >> 6);\r\n a = i & 63;\r\n if (isNaN(r)) {\r\n u = a = 64;\r\n } else if (isNaN(i)) {\r\n a = 64;\r\n }\r\n t = t + BASE64_KEY_STR.charAt(s) + BASE64_KEY_STR.charAt(o) + BASE64_KEY_STR.charAt(u) + BASE64_KEY_STR.charAt(a);\r\n }\r\n return t;\r\n};\r\n\r\n/**\r\n * 转换 Blob 数据到 Base64 Data URL\r\n * @param {Blob} blob - Blob 对象\r\n * @returns {Promise<unknown>} 返回 Base64 Data URL 字符串的 Promise\r\n * @example\r\n * blobToBase64(blob).then(base64 => console.log(base64))\r\n */\r\nexport const blobToBase64 = async (blob: Blob): Promise<unknown> => {\r\n return await _blobToBase64(blob);\r\n};\r\n\r\n/**\r\n * 转换 Blob 数据到 Base64 Data URL(内部实现)\r\n * @param {Blob} blob - Blob 对象\r\n * @returns {Promise<unknown>} 返回 Base64 Data URL 字符串的 Promise\r\n */\r\nconst _blobToBase64 = (blob: Blob): Promise<unknown> =>\r\n new Promise((resolve, reject) => {\r\n const reader = new FileReader();\r\n reader.readAsDataURL(blob);\r\n reader.onload = () => resolve(reader.result);\r\n reader.onerror = (error) => reject(error);\r\n });\r\n","\r\n/**\r\n * 进入全屏模式\r\n * @param {HTMLElement} element - 要全屏显示的元素\r\n * @returns {Promise<void>} 返回 Promise,全屏操作完成后 resolve\r\n * @throws {string} 如果浏览器不支持全屏,抛出错误\r\n * @example\r\n * enterFullScreen(document.body)\r\n */\r\nexport const enterFullScreen = (element: any): Promise<void> => {\r\n\tif (element.requestFullscreen) {\r\n\t\treturn element.requestFullscreen();\r\n\t}\r\n\tif (element.webkitRequestFullScreen) {\r\n\t\treturn element.webkitRequestFullScreen();\r\n\t}\r\n\tif (element.mozRequestFullScreen) {\r\n\t\telement.mozRequestFullScreen();\r\n\t}\r\n\tif (element.msRequestFullScreen) {\r\n\t\telement.msRequestFullScreen();\r\n\t}\r\n\tthrow \"Browser no allow full screen\";\r\n}\r\n\r\n/**\r\n * 退出全屏模式\r\n * @returns {Promise<void>} 返回 Promise,退出全屏操作完成后 resolve\r\n * @example\r\n * exitFullScreen()\r\n */\r\nexport const exitFullScreen = () => {\r\n\treturn document.exitFullscreen();\r\n}\r\n\r\n/**\r\n * 切换全屏模式(全屏时退出,非全屏时进入)\r\n * @param {HTMLElement} element - 要全屏显示的元素\r\n * @returns {Promise<unknown>} 返回 Promise\r\n * @example\r\n * toggleFullScreen(document.body)\r\n */\r\nexport const toggleFullScreen = (element: any): Promise<unknown> => {\r\n\treturn new Promise((resolve, reject) => {\r\n\t\tif (!isInFullScreen()) {\r\n\t\t\tenterFullScreen(element).then(resolve).catch(reject);\r\n\t\t} else {\r\n\t\t\texitFullScreen().then(resolve).catch(reject);\r\n\t\t}\r\n\t})\r\n}\r\n/**\r\n * 检测是否正在全屏\r\n * @returns {boolean} 如果当前正在全屏模式,返回 true,否则返回 false\r\n * @example\r\n * isInFullScreen() // false\r\n */\r\nexport const isInFullScreen = () => {\r\n\treturn !!document.fullscreenElement;\r\n}\r\n\r\n/**\r\n * 检测浏览器语言(支持完全匹配和前缀匹配)\r\n * @param {string[]} supportedLngs - 支持的语言列表\r\n * @returns {string} 返回匹配的语言或第一个支持的语言\r\n * @example\r\n * detectLanguage(['en', 'zh-CN', 'zh']) // '根据浏览器语言返回匹配的语言'\r\n */\r\nexport const detectLanguage = (supportedLngs: string[]) => {\r\n const browserLang = navigator.language || (navigator as any).userLanguage;\r\n\r\n // 尝试完全匹配\r\n if (supportedLngs.includes(browserLang)) {\r\n return browserLang;\r\n }\r\n\r\n // 尝试匹配语言代码的前缀 (例如 zh-CN -> zh)\r\n const langPrefix = browserLang.split(\"-\")[0];\r\n const match = supportedLngs.find((lng) => lng.startsWith(langPrefix));\r\n if (match) {\r\n return match;\r\n }\r\n return supportedLngs[0];\r\n};\r\n\r\n/**\r\n * 检测是否为 Firefox 浏览器\r\n * @returns {boolean} 如果是 Firefox 浏览器,返回 true,否则返回 false\r\n * @example\r\n * isFirefox() // false\r\n */\r\nexport const isFirefox = () => {\r\n return navigator.userAgent.toLowerCase().indexOf(\"firefox\") > -1;\r\n};","\r\n/**\r\n * 设置 Cookie\r\n * @param {string} name - Cookie 名称\r\n * @param {string} value - Cookie 值\r\n * @param {number} days - 有效天数,0 表示会话 Cookie\r\n * @param {string} [path='/'] - Cookie 路径,默认为根路径\r\n * @returns {void}\r\n * @example\r\n * setCookie('username', 'john', 7)\r\n */\r\nexport const setCookie = (name: string, value: string, days: number, path: string = '/'): void => {\r\n\tlet expires = \"\";\r\n\tif(days){\r\n\t\tlet date = new Date();\r\n\t\tdate.setTime(Date.now() + (days * 24 * 60 * 60 * 1000));\r\n\t\texpires = \"; expires=\" + date.toUTCString();\r\n\t}\r\n\tdocument.cookie = name + \"=\" + (value || \"\") + expires + \"; path=\" + path;\r\n}\r\n\r\n/**\r\n * 获取 Cookie\r\n * @param {string} name - Cookie 名称\r\n * @returns {string|null} 返回 Cookie 值,未找到返回 null\r\n * @example\r\n * getCookie('username') // 'john'\r\n */\r\nexport const getCookie = (name: string): string | null => {\r\n\tlet nameEQ = name + \"=\";\r\n\tlet ca = document.cookie.split(';');\r\n\tfor(let i = 0; i < ca.length; i++){\r\n\t\tlet c = ca[i];\r\n\t\twhile(c.charAt(0) === ' ') c = c.substring(1, c.length);\r\n\t\tif(c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);\r\n\t}\r\n\treturn null;\r\n}\r\n\r\n/**\r\n * 删除 Cookie\r\n * @param {string} name - Cookie 名称\r\n * @returns {void}\r\n * @example\r\n * deleteCookie('username')\r\n */\r\nexport const deleteCookie = (name: string): void => {\r\n\tdocument.cookie = name + '=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;';\r\n}","import { randomString } from \"./string\";\r\n\r\nlet _guid = 0;\r\n/**\r\n * 生成全局唯一 ID\r\n * @param {string} [prefix=''] - ID 前缀\r\n * @returns {string} 返回唯一 ID\r\n * @example\r\n * guid('user') // 'guid_user123_1'\r\n */\r\nexport const guid = (prefix = \"\") => {\r\n return \"guid_\" + (prefix || randomString(6)) + ++_guid;\r\n};\r\n\r\n/**\r\n * 节流函数\r\n * 规定在一个单位时间内,只能触发一次函数。如果这个函数单位时间内触发多次函数,只有一次生效。\r\n * @param {Function} fn - 要节流的函数\r\n * @param {number} intervalMiSec - 间隔时间(毫秒)\r\n * @returns {Function} 返回节流后的函数\r\n * @example\r\n * const throttled = throttle(() => console.log('called'), 1000)\r\n */\r\nexport const throttle = (fn: Function, intervalMiSec: number): Function => {\r\n let context: any, args: any;\r\n let previous = 0;\r\n return function (this: any) {\r\n let now = +new Date();\r\n context = this;\r\n args = arguments;\r\n if (now - previous > intervalMiSec) {\r\n fn.apply(context, args as any);\r\n previous = now;\r\n }\r\n };\r\n};\r\n\r\n/**\r\n * 更有效果的节流函数\r\n * 区别:如果函数执行间隔还没到期,放入下一个时间周期执行,如果已经有下一周期未执行,当前触发作废。\r\n * 这种效果在 Change 类型函数场景中更有效果,可以确保最后一次变更能够有效执行\r\n * @param {Function} fn - 要节流的函数\r\n * @param {number} intervalMiSec - 间隔时间(毫秒)\r\n * @returns {Function} 返回节流后的函数\r\n * @example\r\n * const throttled = throttleEffect(() => console.log('called'), 1000)\r\n */\r\nexport const throttleEffect = (fn: Function, intervalMiSec: number): Function => {\r\n let context: any, args: any;\r\n let lastExecuteTime = 0;\r\n let queuing = false;\r\n return function (this: any) {\r\n if (queuing) {\r\n return;\r\n }\r\n let now = +new Date();\r\n context = this;\r\n args = arguments;\r\n let remaining = intervalMiSec - (now - lastExecuteTime);\r\n if (remaining <= 0) {\r\n fn.apply(context, args as any);\r\n lastExecuteTime = now;\r\n } else {\r\n queuing = true;\r\n setTimeout(() => {\r\n fn.apply(context, args as any);\r\n queuing = false;\r\n lastExecuteTime = now;\r\n }, remaining);\r\n }\r\n };\r\n};\r\n\r\n/**\r\n * 防抖函数\r\n * 在事件被触发 n 秒后再执行回调,如果在这 n 秒内又被触发,则重新计时。\r\n * @param {Function} fn - 要防抖的函数\r\n * @param {number} intervalMiSec - 间隔时间(毫秒)\r\n * @returns {Function} 返回防抖后的函数\r\n * @example\r\n * const debounced = debounce(() => console.log('called'), 1000)\r\n */\r\nexport const debounce = (fn: Function, intervalMiSec: number): Function => {\r\n let timeout: any;\r\n return function (this: any) {\r\n let context = this;\r\n let args = arguments;\r\n clearTimeout(timeout);\r\n timeout = setTimeout(function () {\r\n fn.apply(context, args);\r\n }, intervalMiSec);\r\n };\r\n};\r\n/**\r\n * 检测对象是否为 Promise 对象\r\n * @param {any} obj - 要检测的对象\r\n * @returns {boolean} 如果是 Promise 返回 true,否则返回 false\r\n * @example\r\n * isPromise(Promise.resolve()) // true\r\n */\r\nexport const isPromise = (obj: any): boolean => {\r\n return obj && typeof obj === \"object\" && obj.then && typeof obj.then === \"function\";\r\n};\r\n\r\n/**\r\n * 检测字符串是否为有效的 JSON\r\n * @param {string} json - 要检测的字符串\r\n * @returns {boolean} 如果是有效 JSON 返回 true,否则返回 false\r\n * @example\r\n * isJson('{\"name\":\"John\"}') // true\r\n */\r\nexport const isJson = (json: string): boolean => {\r\n let is_json = false;\r\n try {\r\n JSON.parse(json);\r\n is_json = true;\r\n } catch (error) {}\r\n return is_json;\r\n};\r\n\r\n/**\r\n * 检测目标是否为 Object(非数组的对象)\r\n * @param {any} item - 要检测的对象\r\n * @returns {boolean} 如果是对象返回 true,否则返回 false\r\n * @example\r\n * isObject({}) // true\r\n * isObject([]) // false\r\n */\r\nexport const isObject = (item: any): boolean => {\r\n return item && typeof item === \"object\" && !Array.isArray(item);\r\n};\r\n\r\n/**\r\n * 检测是否为函数\r\n * @param {any} value - 要检测的值\r\n * @returns {boolean} 如果是函数返回 true,否则返回 false\r\n * @example\r\n * isFunction(() => {}) // true\r\n */\r\nexport const isFunction = (value: any): boolean => {\r\n return value ? Object.prototype.toString.call(value) === \"[object Function]\" || \"function\" === typeof value || value instanceof Function : false;\r\n};\r\n\r\n/**\r\n * 检测是否为 URL(不包含 blob: data: file: 等协议)\r\n * @param {string} str - 要检测的字符串\r\n * @returns {boolean} 如果是 URL 返回 true,否则返回 false\r\n * @example\r\n * isUrl('https://example.com') // true\r\n */\r\nexport const isUrl = (str: string) => {\r\n if (typeof str !== \"string\" || str.trim() === \"\") return false;\r\n // 常见的可作为资源的 URL/路径:http(s)://, //, blob:, data:, file:, 以及以 / 或 ./ ../ 开头的相对路径\r\n return /^(https?:\\/\\/|\\/\\/|\\/|\\.\\.?\\/*)/i.test(str);\r\n};\r\n\r\n/**\r\n * 判断字符串是否符合 JSON 标准\r\n * @param {string} json - 要检测的字符串\r\n * @returns {boolean} 如果是有效 JSON 返回 true,否则返回 false\r\n * @example\r\n * isJSON('{\"name\":\"John\"}') // true\r\n */\r\nexport const isJSON = (json: string): boolean => {\r\n\tlet is_json = false;\r\n\ttry{\r\n\t\tJSON.parse(json);\r\n\t\tis_json = true;\r\n\t}catch(error){\r\n\t}\r\n\treturn is_json;\r\n}\r\n\r\n/**\r\n * 打印调用堆栈\r\n * @returns {void}\r\n * @example\r\n * printStack() // 在控制台输出堆栈信息\r\n */\r\nexport const printStack = () => {\r\n let stack = new Error().stack;\r\n console.log(stack);\r\n};","/** 黄金分割比 0.618 **/\r\nexport const GOLDEN_RATIO = (1 + Math.sqrt(5)) / 2 - 1;\r\n\r\n//标准屏幕DPI\r\nexport const STAND_DPI = 96;\r\n\r\n/**\r\n * 毫米转换成像素\r\n * @param {number} dimension - 毫米值\r\n * @param {number} [dpi=STAND_DPI] - DPI 值,默认为标准 DPI (96)\r\n * @returns {number} 返回像素值\r\n * @example\r\n * mmToPx(25.4) // 96\r\n */\r\nexport const mmToPx = (dimension: number, dpi: number = STAND_DPI): number => {\r\n let px = (dimension / 25.4) * dpi;\r\n return px;\r\n};\r\n\r\n/**\r\n * 将 mm 转换为 TWIP(Twentieth of a Point)\r\n * @param {number} mm - 毫米值\r\n * @returns {number} 返回 TWIP 值\r\n * @example\r\n * mmToTwip(1) // 57\r\n */\r\nexport const mmToTwip = (mm: number): number => Math.round(mm * 56.6929);\r\n\r\n/**\r\n * 将 mm 转换为磅(Point)\r\n * @param {number} mm - 毫米值\r\n * @returns {number} 返回磅值\r\n * @example\r\n * mmToPt(1) // 2.83\r\n */\r\nexport const mmToPt = (mm: number): number => mm * 2.83464566929;\r\n\r\n/**\r\n * 将磅(Point)转换为 mm\r\n * @param {number} pt - 磅值\r\n * @returns {number} 返回毫米值\r\n * @example\r\n * ptToMm(2.83) // 1\r\n */\r\nexport const ptToMm = (pt: number): number => pt / 2.83464566929;\r\n\r\n/**\r\n * 像素转毫米\r\n * @param {number} px - 像素值\r\n * @param {number} [dpi=STAND_DPI] - DPI 值,默认为标准 DPI (96)\r\n * @returns {number} 返回毫米值\r\n * @example\r\n * pxToMm(96) // 25.4\r\n */\r\nexport const pxToMm = (px: number, dpi: number = STAND_DPI): number => {\r\n return (25.4 * px) / dpi;\r\n};\r\n\r\n/**\r\n * 限制数值在指定范围内\r\n * @param {number} num - 要限制的数值\r\n * @param {number} min - 最小值\r\n * @param {number} max - 最大值\r\n * @returns {number} 返回限制后的数值\r\n * @example\r\n * limit(150, 0, 100) // 100\r\n */\r\nexport const limit = (num: number, min: number, max: number): number => {\r\n return Math.min(Math.max(num, min), max);\r\n}\r\n\r\n/**\r\n * 检测指定值是否在指定区间内\r\n * @param {Number} val\r\n * @param {Number} min\r\n * @param {Number} max\r\n * @param {Boolean} includeEqual 是否包含等于判断\r\n * @returns {boolean}\r\n */\r\nexport const between = (val: number, min: number, max: number, includeEqual: boolean = true): boolean => {\r\n\treturn includeEqual ? (val >= min && val <= max) : (val > min && val < max);\r\n};\r\n\r\n/**\r\n * 随机整数\r\n * @param {Number} min\r\n * @param {Number} max\r\n * @return {Number}\r\n */\r\nexport const randomInt = (min: number, max: number): number => {\r\n\treturn Math.floor(Math.random() * (max + 1 - min)) + min;\r\n};\r\n\r\n/**\r\n * 取整\r\n * @param {Number} num\r\n * @param {Number} precision 精度,默认为两位小数\r\n * @returns {number}\r\n */\r\nexport const round = (num: number, precision: number = 2): number => {\r\n\tlet multiple = Math.pow(10, precision);\r\n\treturn Math.round(num * multiple) / multiple;\r\n}\r\n\r\n/**\r\n * 检测数值最大精度\r\n * @param {...any} numbers 待检测数值\r\n * @returns\r\n */\r\nexport const detectedPrecision = (...numbers: number[]): number => {\r\n let maxPrecision = 0;\r\n numbers.forEach((num) => {\r\n if (typeof num === \"number\" && !isNaN(num)) {\r\n const decimalPart = num.toString().split(\".\")[1];\r\n if (decimalPart) {\r\n maxPrecision = Math.max(maxPrecision, decimalPart.length);\r\n }\r\n }\r\n });\r\n return maxPrecision;\r\n};\r\n\r\n/**\r\n * 计算数字位数\r\n * @param {number} n - 要计算的数字\r\n * @returns {number} 返回数字的位数\r\n * @example\r\n * digitCount(123) // 3\r\n */\r\nexport const digitCount = (n: number) => {\r\n n = Math.abs(Number(n)); // 取绝对值,防止负数\r\n if (n === 0) return 1;\r\n return Math.floor(Math.log10(n)) + 1;\r\n};","import { guid } from \"./util\";\r\nimport { between } from \"./math\";\r\n\r\n/**\r\n * 隐藏节点(通过设置 display:none 方式)\r\n * @param {HTMLElement|string} dom - DOM 元素或选择器\r\n * @returns {void}\r\n * @example\r\n * hide('#myElement')\r\n */\r\nexport const hide = (dom: HTMLElement | string): void => {\r\n findOne(dom).style.display = \"none\";\r\n};\r\n/**\r\n * 显示节点(通过设置 display 为空方式)\r\n * @param {HTMLElement|string} dom - DOM 元素或选择器\r\n * @returns {void}\r\n * @example\r\n * show('#myElement')\r\n */\r\nexport const show = (dom: HTMLElement | string): void => {\r\n findOne(dom).style.display = \"\";\r\n};\r\n\r\n/**\r\n * 移除 DOM 节点\r\n * @param {HTMLElement|string} dom - DOM 元素或选择器\r\n * @returns {Node|null} 返回被移除的节点,如果未找到返回 null\r\n * @example\r\n * remove('#myElement')\r\n */\r\nexport const remove = (dom: HTMLElement | string): Node | null => {\r\n let el = findOne(dom);\r\n return el && el.parentNode && el.parentNode.removeChild(el);\r\n};\r\n\r\nconst _el_disabled_class_ = \"disabled\";\r\n\r\n/**\r\n * 禁用元素(禁止交互,设置disabled)\r\n * @param {String|Node} el\r\n * @param {String} disabledClass\r\n */\r\nexport const disabled = (el: HTMLElement | string, disabledClass: string = \"\"): void => {\r\n return toggleDisabled(el, disabledClass, false);\r\n};\r\n\r\n/**\r\n * 启用元素(允许交互,移除disabled)\r\n * @param {String|Node} el\r\n * @param {String} disabledClass\r\n */\r\nexport const enabled = (el: HTMLElement | string, disabledClass: string = \"\"): void => {\r\n return toggleDisabled(el, disabledClass, true);\r\n};\r\n\r\n/**\r\n * 禁用启用元素切换\r\n * @param {String|Node} el\r\n * @param {String} disabledClass\r\n * @param {Boolean|Null} forceEnabled 强制启用、禁用,为空表示自动切换\r\n */\r\nexport const toggleDisabled = (el: HTMLElement | string, disabledClass: string = \"\", forceEnabled: boolean | null = null): void => {\r\n let element = findOne(el) as HTMLElement;\r\n let toDisabled = forceEnabled === null ? !element.classList.contains(_el_disabled_class_) : !forceEnabled;\r\n if (toDisabled) {\r\n insertStyleSheet(`.${_el_disabled_class_} {pointer-event:none !important;}`, \"__element_lock_style__\");\r\n }\r\n element.classList.toggle(_el_disabled_class_, toDisabled);\r\n element[toDisabled ? \"setAttribute\" : \"removeAttribute\"](\"disabled\", \"disabled\");\r\n element[toDisabled ? \"setAttribute\" : \"removeAttribute\"](\"data-disabled\", \"disabled\");\r\n if (disabledClass) {\r\n element.classList.toggle(disabledClass, toDisabled);\r\n }\r\n};\r\n\r\nexport const onHover = (el: HTMLElement | string, onHoverIn: () => void, onHoverOut: () => void): void => {\r\n el = findOne(el) as HTMLElement;\r\n let isHovering = false;\r\n el.addEventListener(\"mouseenter\", () => {\r\n if (!isHovering) {\r\n isHovering = true;\r\n onHoverIn && onHoverIn();\r\n }\r\n });\r\n el.addEventListener(\"mouseleave\", () => {\r\n if (isHovering) {\r\n isHovering = false;\r\n onHoverOut && onHoverOut();\r\n }\r\n });\r\n};\r\n\r\n/**\r\n * 绑定元素,禁止交互\r\n * @param {Node} el\r\n * @param {Function} payload 处理函数,参数为 reset\r\n */\r\nexport const lockElementInteraction = (el: HTMLElement | string, payload: (reset: () => void) => void): void => {\r\n disabled(el);\r\n let reset = () => {\r\n enabled(el);\r\n };\r\n payload(reset);\r\n};\r\n/**\r\n * 获取当前节点在父节点中的索引号\r\n * @param {HTMLElement} node - DOM 节点\r\n * @returns {number} 返回索引号,如果没有父节点返回 -1\r\n * @example\r\n * nodeIndex(element) // 2\r\n */\r\nexport const nodeIndex = (node: HTMLElement): number => {\r\n return node.parentNode ? Array.prototype.indexOf.call(node.parentNode.children, node) : -1;\r\n};\r\n\r\n/**\r\n * 通过选择器查找子节点(强制添加 :scope 来约束必须是子节点)\r\n * @param {string|HTMLElement|HTMLElement[]|NodeList|HTMLCollection} selector - 选择器或 DOM 元素\r\n * @param {Document|HTMLElement} [parent=document] - 父节点,默认为 document\r\n * @returns {HTMLElement[]} 返回查找到的所有元素数组\r\n * @example\r\n * findAll('.item', container)\r\n */\r\nexport const findAll = (\r\n selector: string | HTMLElement | HTMLElement[] | NodeList | HTMLCollection,\r\n parent: Document | HTMLElement = document,\r\n): HTMLElement[] => {\r\n if (typeof selector === \"string\") {\r\n selector = selector.trim();\r\n if (selector.indexOf(\":scope\") !== 0) {\r\n selector = \":scope \" + selector;\r\n }\r\n return Array.from(parent.querySelectorAll(selector));\r\n } else if (Array.isArray(selector)) {\r\n let ns: HTMLElement[] = [];\r\n selector.forEach((sel) => {\r\n ns.push(...findAll(sel));\r\n });\r\n return ns;\r\n } else if (NodeList.prototype.isPrototypeOf(selector) || HTMLCollection.prototype.isPrototypeOf(selector)) {\r\n return Array.from(selector as any) as HTMLElement[];\r\n } else if (selector instanceof HTMLElement) {\r\n return [selector];\r\n } else {\r\n return selector as any;\r\n }\r\n};\r\n\r\n/**\r\n * 通过选择器查找单个节点\r\n * @param {string|HTMLElement} selector - 选择器,如果是 HTMLElement,则直接返回\r\n * @param {Document|HTMLElement} [parent=document] - 父节点,默认为 document\r\n * @returns {HTMLElement} 返回查找到的元素\r\n * @example\r\n * findOne('.item')\r\n */\r\nexport const findOne = (selector: string | HTMLElement, parent: Document | HTMLElement = document): HTMLElement => {\r\n return typeof selector === \"string\" ? (parent.querySelector(selector) as HTMLElement) : selector;\r\n};\r\n/**\r\n * 获取节点的 XPath\r\n * @param {HTMLElement|null} el - DOM 元素\r\n * @returns {string|null} 返回 XPath 字符串,失败返回 null\r\n * @example\r\n * getNodeXPath(element) // '/html[1]/body[1]/div[1]'\r\n */\r\nexport const getNodeXPath = (el: HTMLElement | null): string | null => {\r\n let allNodes = document.getElementsByTagName(\"*\");\r\n let seg_list: string[] = [];\r\n for (seg_list = []; el && el.nodeType === 1; el = el.parentNode as HTMLElement) {\r\n if (el.hasAttribute(\"id\")) {\r\n let uniqueIdCount = 0;\r\n for (let n = 0; n < allNodes.length; n++) {\r\n if (allNodes[n].hasAttribute(\"id\") && allNodes[n].id === el.id) uniqueIdCount++;\r\n if (uniqueIdCount > 1) break;\r\n }\r\n if (uniqueIdCount === 1) {\r\n seg_list.unshift('id(\"' + el.getAttribute(\"id\") + '\")');\r\n return seg_list.join(\"/\");\r\n } else {\r\n seg_list.unshift(el.localName.toLowerCase() + '[@id=\"' + el.getAttribute(\"id\") + '\"]');\r\n }\r\n } else if (el.hasAttribute(\"class\")) {\r\n seg_list.unshift(el.localName.toLowerCase() + '[@class=\"' + el.getAttribute(\"class\") + '\"]');\r\n } else {\r\n let i: number, sib: ChildNode | null;\r\n for (i = 1, sib = el.previousSibling; sib; sib = sib.previousSibling) {\r\n if ((sib as any).localName === el.localName) {\r\n i++;\r\n }\r\n }\r\n seg_list.unshift(el.localName.toLowerCase() + \"[\" + i + \"]\");\r\n }\r\n }\r\n return seg_list.length ? \"/\" + seg_list.join(\"/\") : null;\r\n};\r\n/**\r\n * 监听节点树变更\r\n * @param {HTMLElement} dom - 要监听的 DOM 节点\r\n * @param {Function} callback - 回调函数\r\n * @param {boolean} [includeElementChanged=true] - 是否包含表单元素的值变更\r\n * @returns {void}\r\n * @example\r\n * onDomTreeChange(container, () => console.log('changed'))\r\n */\r\nexport const onDomTreeChange = (dom: HTMLElement, callback: () => void, includeElementChanged: boolean = true): void => {\r\n const PRO_KEY = \"ON_DOM_TREE_CHANGE_BIND_\" + guid();\r\n let watchEl = () => {\r\n findAll(`input:not([${PRO_KEY}]), textarea:not([${PRO_KEY}]), select:not([${PRO_KEY}])`, dom).forEach((el) => {\r\n el.setAttribute(PRO_KEY, \"1\");\r\n el.addEventListener(\"change\", callback);\r\n });\r\n };\r\n mutationEffective(\r\n dom,\r\n { attributes: true, subtree: true, childList: true },\r\n () => {\r\n includeElementChanged && watchEl();\r\n callback();\r\n },\r\n 10,\r\n );\r\n includeElementChanged && watchEl();\r\n};\r\n\r\n/**\r\n * 更低占用执行 mutation 监听,支持指定最小间隔时间执行回调\r\n * @param {HTMLElement} dom - 要监听的 DOM 节点\r\n * @param {MutationObserverInit} option - MutationObserver 配置选项\r\n * @param {Function} payload - 回调函数,接收 MutationObserver 实例作为参数\r\n * @param {number} [minInterval=10] - 执行回调最小间隔时间(毫秒)\r\n * @returns {void}\r\n * @example\r\n * mutationEffective(dom, {attributes: true, childList: true}, (obs) => console.log('changed'))\r\n */\r\nexport const mutationEffective = (dom: HTMLElement, option: MutationObserverInit, payload: (obs: MutationObserver) => void, minInterval: number = 10): void => {\r\n let last_queue_time = 0;\r\n let callback_queueing = false;\r\n let obs = new MutationObserver(() => {\r\n if (callback_queueing) {\r\n return;\r\n }\r\n let r = minInterval - (Date.now() - last_queue_time);\r\n if (r > 0) {\r\n callback_queueing = true;\r\n setTimeout(() => {\r\n callback_queueing = false;\r\n last_queue_time = Date.now();\r\n payload(obs);\r\n }, r);\r\n } else {\r\n last_queue_time = Date.now();\r\n payload(obs);\r\n }\r\n });\r\n obs.observe(dom, option);\r\n};\r\n\r\ninterface Dimension {\r\n left: number;\r\n top: number;\r\n width: number;\r\n height: number;\r\n}\r\n\r\n/**\r\n * 保持对象尽量在容器内部,优先保证上边、左边显示\r\n * @param {Object} objDim\r\n * @param {Number} objDim.left\r\n * @param {Number} objDim.top\r\n * @param {Number} objDim.width\r\n * @param {Number} objDim.height\r\n * @param {Object} ctnDim\r\n * @param {Number} ctnDim.left\r\n * @param {Number} ctnDim.top\r\n * @param {Number} ctnDim.width\r\n * @param {Number} ctnDim.height\r\n * {Array} dimension [dimension.left, dimension.top]\r\n */\r\nexport const keepRectInContainer = (\r\n objDim: Dimension,\r\n ctnDim: Dimension = {\r\n left: 0,\r\n top: 0,\r\n width: window.innerWidth,\r\n height: window.innerHeight,\r\n },\r\n): { left: number; top: number } => {\r\n let ret = { left: objDim.left, top: objDim.top };\r\n\r\n //oversize\r\n if (objDim.width > ctnDim.width || objDim.height > ctnDim.height) {\r\n return ret;\r\n }\r\n\r\n //右边超出\r\n if (objDim.width + objDim.left > ctnDim.width + ctnDim.left) {\r\n ret.left = objDim.left - (objDim.width + objDim.left - (ctnDim.width + ctnDim.left));\r\n }\r\n\r\n //底边超出\r\n if (objDim.height + objDim.top > ctnDim.height + ctnDim.top) {\r\n ret.top = objDim.top - (objDim.height + objDim.top - (ctnDim.height + ctnDim.top));\r\n }\r\n\r\n //优先保证左边露出\r\n if (objDim.left < ctnDim.left) {\r\n ret.left = ctnDim.left;\r\n }\r\n\r\n //优先保证上边露出\r\n if (objDim.top < ctnDim.top) {\r\n ret.top = ctnDim.top;\r\n }\r\n return ret;\r\n};\r\n\r\n/**\r\n * 矩形相交(包括边重叠情况)\r\n * @param {Dimension} rect1 - 第一个矩形对象\r\n * @param {Dimension} rect2 - 第二个矩形对象\r\n * @returns {boolean} 如果两个矩形相交返回 true,否则返回 false\r\n * @example\r\n * rectAssoc({left: 0, top: 0, width: 100, height: 100}, {left: 50, top: 50, width: 100, height: 100}) // true\r\n */\r\nexport const rectAssoc = (rect1: Dimension, rect2: Dimension): boolean => {\r\n if (rect1.left <= rect2.left) {\r\n return (\r\n rect1.left + rect1.width >= rect2.left &&\r\n (between(rect2.top, rect1.top, rect1.top + rect1.height) ||\r\n between(rect2.top + rect2.height, rect1.top, rect1.top + rect1.height) ||\r\n (rect2.top >= rect1.top && rect2.height >= rect1.height))\r\n );\r\n } else {\r\n return (\r\n rect2.left + rect2.width >= rect1.left &&\r\n (between(rect1.top, rect2.top, rect2.top + rect2.height) ||\r\n between(rect1.top + rect1.height, rect2.top, rect2.top + rect2.height) ||\r\n (rect1.top >= rect2.top && rect1.height >= rect2.height))\r\n );\r\n }\r\n};\r\n\r\n/**\r\n * 检测元素是否可聚焦\r\n * @param {HTMLElement} el - DOM 元素\r\n * @returns {boolean} 如果元素可聚焦返回 true,否则返回 false\r\n * @example\r\n * isFocusable(inputElement) // true\r\n */\r\nexport const isFocusable = (el: HTMLElement) => {\r\n if (!el) return false;\r\n if (el.tabIndex >= 0) return true;\r\n if (el instanceof HTMLAnchorElement && el.href) return true;\r\n if (el instanceof HTMLButtonElement && !el.disabled) return true;\r\n if (el instanceof HTMLInputElement && !el.disabled) return true;\r\n if (el instanceof HTMLTextAreaElement && !el.disabled) return true;\r\n return false;\r\n};\r\n\r\nlet _c: Record<string, Promise<void>> = {};\r\n\r\n/**\r\n * 挂载 CSS 文件\r\n * @param {string} file - CSS 文件路径\r\n * @param {boolean} [forceReload=false] - 是否强制重新挂载,缺省不重复挂载\r\n * @returns {Promise<void>} 返回 Promise,加载完成后 resolve\r\n * @example\r\n * loadCss('/styles/theme.css')\r\n */\r\nexport const loadCss = (file: string, forceReload: boolean = false): Promise<void> => {\r\n if (!forceReload && file in _c) {\r\n return _c[file];\r\n }\r\n _c[file] = new Promise((resolve, reject) => {\r\n let link = document.createElement(\"link\");\r\n link.rel = \"stylesheet\";\r\n link.href = file;\r\n link.onload = () => {\r\n resolve();\r\n };\r\n link.onerror = () => {\r\n reject();\r\n };\r\n document.head.append(link);\r\n });\r\n return _c[file];\r\n};\r\n\r\n/**\r\n * 加载 Script 脚本\r\n * @param {string} src - 脚本地址\r\n * @param {boolean} [forceReload=false] - 是否强制重新加载,缺省为去重加载\r\n * @returns {Promise<void>} 返回 Promise,加载完成后 resolve\r\n * @example\r\n * loadScript('/scripts/lib.js')\r\n */\r\nexport const loadScript = (src: string, forceReload: boolean = false): Promise<void> => {\r\n if (!forceReload && src in _c) {\r\n return _c[src];\r\n }\r\n _c[src] = new Promise((resolve, reject) => {\r\n let script = document.createElement(\"script\");\r\n script.src = src;\r\n script.onload = () => {\r\n resolve();\r\n };\r\n script.onerror = () => {\r\n reject();\r\n };\r\n document.head.append(script);\r\n });\r\n return _c[src];\r\n};\r\n\r\n/**\r\n * 获取对象宽、高(通过设置 visibility 方式进行获取)\r\n * @param {HTMLElement} dom - DOM 元素\r\n * @returns {{width: number, height: number}} 返回元素的宽度和高度\r\n * @example\r\n * getDomDimension(element) // {width: 100, height: 50}\r\n */\r\nexport const getDomDimension = (dom: HTMLElement): { width: number; height: number } => {\r\n let org_visibility = dom.style.visibility;\r\n let org_display = dom.style.display;\r\n let width, height;\r\n\r\n dom.style.visibility = \"hidden\";\r\n dom.style.display = \"block\";\r\n width = dom.clientWidth;\r\n height = dom.clientHeight;\r\n dom.style.visibility = org_visibility;\r\n dom.style.display = org_display;\r\n return { width, height };\r\n};\r\n\r\n/**\r\n * 在头部插入样式\r\n * @param {string} styleSheetStr - 样式代码\r\n * @param {string} [id=''] - 样式 ID,如果提供 ID,将会检测是否已经插入,可以避免重复插入\r\n * @param {Document} [doc=document] - 文档上下文\r\n * @returns {HTMLStyleElement|null} 返回创建的 style 元素\r\n * @example\r\n * insertStyleSheet('.test { color: red; }', 'my-style')\r\n */\r\nexport const insertStyleSheet = (styleSheetStr: string, id: string = \"\", doc: Document = document): HTMLStyleElement | null => {\r\n if (id && doc.querySelector(`#${id}`)) {\r\n return doc.querySelector(`#${id}`) as HTMLStyleElement;\r\n }\r\n let style = doc.createElement(\"style\");\r\n doc.head.appendChild(style);\r\n style.innerHTML = styleSheetStr;\r\n if (id) {\r\n style.id = id;\r\n }\r\n return style;\r\n};\r\n\r\n/**\r\n * 检测矩形是否在指定布局内部\r\n * @param {Dimension} rect - 要检测的矩形\r\n * @param {Dimension} layout - 布局矩形\r\n * @returns {boolean} 如果矩形在布局内部返回 true,否则返回 false\r\n * @example\r\n * rectInLayout(rect, layout) // true\r\n */\r\nexport const rectInLayout = (rect: Dimension, layout: Dimension): boolean => {\r\n return (\r\n between(rect.top, layout.top, layout.top + layout.height) &&\r\n between(rect.left, layout.left, layout.left + layout.width) && //左上角\r\n between(rect.top + rect.height, layout.top, layout.top + layout.height) &&\r\n between(rect.left + rect.width, layout.left, layout.left + layout.width)\r\n ); //右下角\r\n};\r\n\r\n/**\r\n * 精度位数转小数表示法\r\n * @param {number} precision - 精度位数\r\n * @returns {number} 精度小数表示法,如 0.01\r\n * @example\r\n * precisionToStep(2) // 0.01\r\n */\r\nexport const precisionToStep = (precision: number): number => {\r\n return Math.pow(10, -precision);\r\n};\r\n\r\n/**\r\n * 修复基本 URL(将相对路径转换为绝对 URL)\r\n * @param {string} url - 要修复的 URL\r\n * @param {string} baseUrl - 基本 URL\r\n * @returns {string} 返回修复后的 URL\r\n * @example\r\n * fixBaseUrl('/path', 'https://example.com') // 'https://example.com/path'\r\n */\r\nexport const fixBaseUrl = (url: string, baseUrl: string): string => {\r\n try {\r\n const fixedUrl = new URL(url, baseUrl);\r\n return fixedUrl.href;\r\n } catch {\r\n return url;\r\n }\r\n};\r\n\r\n/**\r\n * 创建 HTML 节点\r\n * @param {string} html - HTML 字符串\r\n * @param {HTMLElement|null} [parentNode=null] - 父级节点,如果提供则自动添加到父节点\r\n * @returns {Node|Node[]} 返回创建的节点,单个或多个\r\n * @example\r\n * createDomByHtml('<div>Hello</div>')\r\n */\r\nexport const createDomByHtml = (html: string, parentNode: HTMLElement | null = null): Node | Node[] => {\r\n let tpl = document.createElement(\"template\");\r\n html = html.trim();\r\n tpl.innerHTML = html;\r\n let nodes: Node[] = [];\r\n if (parentNode) {\r\n tpl.content.childNodes.forEach((node) => {\r\n nodes.push(parentNode.appendChild(node));\r\n });\r\n } else {\r\n nodes = Array.from(tpl.content.childNodes);\r\n }\r\n return nodes.length === 1 ? nodes[0] : nodes;\r\n};\r\n\r\ninterface RectObject {\r\n top: number;\r\n left: number;\r\n right: number;\r\n bottom: number;\r\n width: number;\r\n height: number;\r\n}\r\n\r\n/**\r\n * 获取元素的位置(相对于视口)\r\n * @param {HTMLElement} el - DOM 元素\r\n * @param {boolean} [autoFixInvisible=false] - 是否自动修正隐藏元素无法测量的 bug\r\n * @returns {RectObject} 返回元素的位置和尺寸信息\r\n * @example\r\n * getBoundingClientRect(element) // {top: 100, left: 50, width: 200, height: 100, ...}\r\n */\r\nexport const getBoundingClientRect = (el: HTMLElement, autoFixInvisible = false): RectObject => {\r\n if (!el) {\r\n throw new Error(\"el is null\");\r\n }\r\n const rect = el.getBoundingClientRect();\r\n\r\n //自动修正隐藏元素无法测量bug\r\n if (autoFixInvisible && !rect.height) {\r\n const originalVisibility = el.style.visibility;\r\n const originalDisplay = el.style.display;\r\n el.style.visibility = \"hidden\";\r\n el.style.display = \"block\";\r\n const overlayRect = getBoundingClientRect(el);\r\n el.style.visibility = originalVisibility;\r\n el.style.display = originalDisplay;\r\n return overlayRect;\r\n }\r\n\r\n return {\r\n top: rect.top,\r\n left: rect.left,\r\n right: rect.right,\r\n bottom: rect.bottom,\r\n width: rect.width,\r\n height: rect.height,\r\n };\r\n};\r\n\r\n/**\r\n * 构建 CSS 变量对象(自动添加 -- 前缀和 px 单位)\r\n * @param {Record<string, number|string|undefined>} vars - CSS 变量对象\r\n * @returns {Record<string, string>} 返回格式化后的 CSS 变量对象\r\n * @example\r\n * buildStyleVars({width: 100, color: 'red'}) // {'--width': '100px', '--color': 'red'}\r\n */\r\nexport const buildStyleVars = (vars: Record<string, number | string | undefined>) => {\r\n let styles = {} as Record<string, string>;\r\n for (let k in vars) {\r\n const v = vars[k];\r\n if (v !== undefined) {\r\n styles[`--${k}`] = `${v}` + (typeof v === \"number\" ? \"px\" : \"\");\r\n }\r\n }\r\n return styles;\r\n};\r\n","import { isUrl } from \"./util\";\r\n\r\n/**\r\n * 过滤字符串为合法文件名\r\n * 替换 Windows/Unix 不允许的字符为下划线\r\n * 包括:\\ / : * ? \" < > | 以及控制字符\r\n * @param {string} name\r\n * @returns {string}\r\n */\r\nexport const sanitizeFileName = (name: string): string => {\r\n return name\r\n .replace(/[\\\\/:*?\"<>|]/g, \"_\")\r\n .replace(/[\\0-\\x1F]/g, \"_\") // 单独替换控制字符\r\n .replace(/\\s+/g, \" \") // 替换多个空格为一个空格\r\n .replace(/^\\.+/, \"\") // 去除开头的点\r\n .replace(/\\.+$/, \"\") // 去除结尾的点\r\n .trim();\r\n};\r\n\r\n/**\r\n * 将 Blob 转换为 Data URI\r\n * @param {Blob} blob - Blob 对象\r\n * @returns {Promise<string>} 返回 Data URI 字符串\r\n * @example\r\n * blobToDataUri(blob).then(uri => console.log(uri))\r\n */\r\nexport const blobToDataUri = (blob: Blob): Promise<string> =>\r\n new Promise((resolve, reject) => {\r\n const reader = new FileReader();\r\n reader.onload = () => resolve(reader.result as string);\r\n reader.onerror = (e) => reject(e);\r\n reader.readAsDataURL(blob);\r\n });\r\n\r\n// 缓存通过 URL 获取的文件数据\r\nconst FILE_B64_CACHE_DATA: Record<string, string> = {};\r\n\r\n/**\r\n * URL 转 Base64 Data URL 数据缓存\r\n * @param {string} url - 文件 URL\r\n * @param {string|null} [b64Data=null] - Base64 Data URL 数据,传入 null 则为读取缓存\r\n * @returns {string|null} 读取缓存时返回 Base64 Data URL 字符串,未命中返回 null\r\n * @example\r\n * urlB64DataCache('http://example.com/img.png', dataUrl) // 设置缓存\r\n * urlB64DataCache('http://example.com/img.png') // 读取缓存\r\n */\r\nexport const urlB64DataCache = (url: string, b64Data: string | null = null): string | null => {\r\n if (b64Data !== null) {\r\n FILE_B64_CACHE_DATA[url] = b64Data;\r\n return null;\r\n } else {\r\n return FILE_B64_CACHE_DATA[url] || null;\r\n }\r\n};\r\n\r\n/**\r\n * 将文件转换为 Base64 Data URI\r\n * 支持 File/Blob 对象,或字符串 URL(http(s)/相对/blob:)\r\n * @param {File|Blob|string} file - 文件对象或 URL 字符串\r\n * @returns {Promise<string|null>} 返回 Data URL 字符串,失败返回 null\r\n * @example\r\n * fileToBase64DataUri(file).then(uri => console.log(uri))\r\n */\r\nexport const fileToBase64DataUri = async (file: File | Blob | string) => {\r\n if (!file) {\r\n return null;\r\n }\r\n\r\n // 已经是 data URL\r\n if (typeof file === \"string\" && file.startsWith(\"data:\")) {\r\n return file;\r\n }\r\n\r\n try {\r\n // 字符串 URL(http(s)/相对/blob:)\r\n if (typeof file === \"string\" && isUrl(file)) {\r\n // fetch -> blob -> dataURL\r\n const resp = await fetch(file);\r\n if (!resp.ok) {\r\n throw new Error(`Fetch failed: ${resp.status}`);\r\n }\r\n const blob = await resp.blob();\r\n return await blobToDataUri(blob);\r\n }\r\n\r\n // File 或 Blob\r\n if (file instanceof Blob) {\r\n return await blobToDataUri(file);\r\n }\r\n\r\n // 不能处理的类型,返回 null\r\n return null;\r\n } catch (err) {\r\n console.warn(\"file2Base64DataURL failed:\", err);\r\n return null;\r\n }\r\n};\r\n\r\n/**\r\n * 下载文件\r\n * @param {string} uri - 文件 URI(支持 Data URI 和普通 URL)\r\n * @param {string} fileName - 保存的文件名\r\n * @returns {void}\r\n * @example\r\n * downloadFile('data:text/plain;base64,SGVsbG8=', 'hello.txt')\r\n */\r\nexport const downloadFile = (uri: string, fileName: string) => {\r\n const link = document.createElement(\"a\");\r\n\tlink.rel = 'noopener noreferrer';\r\n link.href = uri;\r\n link.download = fileName;\r\n document.body.appendChild(link);\r\n link.click();\r\n document.body.removeChild(link);\r\n};\r\n","import { regQuote } from \"./string\";\r\n\r\n/**\r\n * 块元素\r\n * 用大写定义,方便直接匹配 node.tagName\r\n * @type {string[]}\r\n */\r\nexport const BLOCK_TAGS = [\r\n \"ADDRESS\",\r\n \"ARTICLE\",\r\n \"ASIDE\",\r\n \"BLOCKQUOTE\",\r\n \"CANVAS\",\r\n \"DD\",\r\n \"DIV\",\r\n \"DL\",\r\n \"DT\",\r\n \"FIELDSET\",\r\n \"FIGCAPTION\",\r\n \"FIGURE\",\r\n \"FOOTER\",\r\n \"FORM\",\r\n \"H1\",\r\n \"H2\",\r\n \"H3\",\r\n \"H4\",\r\n \"H5\",\r\n \"H6\",\r\n \"HEADER\",\r\n \"HR\",\r\n \"LI\",\r\n \"MAIN\",\r\n \"NAV\",\r\n \"NOSCRIPT\",\r\n \"OL\",\r\n \"P\",\r\n \"PRE\",\r\n \"SECTION\",\r\n \"TABLE\",\r\n \"TFOOT\",\r\n \"UL\",\r\n \"VIDEO\",\r\n];\r\n\r\n/**\r\n * 非自关闭标签\r\n * https://www.w3schools.com/html/html_blocks.asp\r\n * @type {*[]}\r\n */\r\nexport const PAIR_TAGS = [\r\n \"A\",\r\n \"ABBR\",\r\n \"ACRONYM\",\r\n \"B\",\r\n \"BDO\",\r\n \"BIG\",\r\n \"BUTTON\",\r\n \"CITE\",\r\n \"CODE\",\r\n \"DFN\",\r\n \"EM\",\r\n \"I\",\r\n \"KBD\",\r\n \"LABEL\",\r\n \"MAP\",\r\n \"OBJECT\",\r\n \"OUTPUT\",\r\n \"Q\",\r\n \"S\",\r\n \"SAMP\",\r\n \"SCRIPT\",\r\n \"SELECT\",\r\n \"SMALL\",\r\n \"SPAN\",\r\n \"STRONG\",\r\n \"SUB\",\r\n \"SUP\",\r\n \"TEXTAREA\",\r\n \"TIME\",\r\n \"TT\",\r\n \"U\",\r\n \"VAR\",\r\n].concat(...BLOCK_TAGS);\r\n\r\n/**\r\n * 自关闭标签\r\n * @type {string[]}\r\n */\r\nexport const SELF_CLOSING_TAGS = [\"AREA\", \"BASE\", \"BR\", \"COL\", \"EMBED\", \"HR\", \"IMG\", \"INPUT\", \"LINK\", \"META\", \"PARAM\", \"SOURCE\", \"TRACK\", \"WBR\"];\r\n\r\n/**\r\n * 非内容可清理标签\r\n * @type {string[]}\r\n */\r\nexport const REMOVABLE_TAGS = [\"STYLE\", \"COMMENT\", \"SELECT\", \"OPTION\", \"SCRIPT\", \"TITLE\", \"HEAD\", \"BUTTON\", \"META\", \"LINK\", \"PARAM\", \"SOURCE\"];\r\n\r\n/**\r\n * 将 HTML 转换为纯文本(移除所有标签和样式)\r\n * @param {string} html - HTML 字符串\r\n * @returns {string} 返回纯文本\r\n * @example\r\n * html2Text('<p>Hello <b>World</b></p>') // 'Hello World'\r\n */\r\nexport const html2Text = (html: string): string => {\r\n //remove removable tags\r\n REMOVABLE_TAGS.forEach((tag) => {\r\n html = html.replace(new RegExp(tag, \"ig\"), \"\");\r\n });\r\n\r\n //remove text line break\r\n html = html.replace(/[\\r|\\n]/g, \"\");\r\n\r\n //convert block tags to line break\r\n html = html.replace(/<(\\w+)([^>]*)>/g, function (_ms: string, tag: string, _tail: string) {\r\n if (BLOCK_TAGS.includes(tag.toUpperCase())) {\r\n return \"\\n\";\r\n }\r\n return \"\";\r\n });\r\n\r\n //remove tag's postfix\r\n html = html.replace(/<\\/(\\w+)([^>]*)>/g, function (_ms: string, _tag: string, _tail: string) {\r\n return \"\";\r\n });\r\n\r\n //remove other tags, likes <img>, input, etc...\r\n html = html.replace(/<[^>]+>/g, \"\");\r\n\r\n //convert entity by names\r\n let entityNamesMap: [RegExp, string][] = [\r\n [/&nbsp;/gi, \" \"],\r\n [/&lt;/gi, \"<\"],\r\n [/&gt;/gi, \">\"],\r\n [/&quot;/gi, '\"'],\r\n [/&apos;/gi, \"'\"],\r\n ];\r\n entityNamesMap.forEach(([matchReg, replacement]) => {\r\n html = html.replace(matchReg, replacement);\r\n });\r\n\r\n //convert entity dec code\r\n html = html.replace(/&#(\\d+);/, function (_ms: string, dec: string) {\r\n return String.fromCharCode(parseInt(dec));\r\n });\r\n\r\n //replace last &amp;\r\n html = html.replace(/&amp;/gi, \"&\");\r\n\r\n //trim head & tail space\r\n html = html.trim();\r\n\r\n return html;\r\n};\r\n\r\n/**\r\n * CSS 选择器转义(处理特殊字符)\r\n * @param {string} str - 要转义的字符串\r\n * @returns {string} 转义后的字符串\r\n * @example\r\n * cssSelectorEscape('my#id') // 'my\\\\#id'\r\n */\r\nexport const cssSelectorEscape = (str: string): string => {\r\n return window.CSS && CSS.escape ? CSS.escape(str) : str.replace(/[!\"#$%&'()*+,.\\/:;<=>?@[\\\\\\]^`{|}~]/g, \"\\\\$&\");\r\n};\r\n\r\n/**\r\n * HTML 实体转字符串\r\n * @param {string} entity - HTML 实体字符串(如 &#72;&#101;&#108;&#108;&#111;)\r\n * @returns {string} 返回解码后的字符串\r\n * @example\r\n * entityToString('&#72;&#101;') // 'He'\r\n */\r\nexport const entityToString = (entity: string): string => {\r\n let entities = entity.split(\";\");\r\n entities.pop();\r\n return entities.map((item: string) => String.fromCharCode(item[2] === \"x\" ? parseInt(item.slice(3), 16) : parseInt(item.slice(2)))).join(\"\");\r\n};\r\n\r\nlet _helper_div: HTMLDivElement | undefined;\r\n/**\r\n * 解码 HTML 实体(包括 script 和 HTML 标签过滤)\r\n * @param {string} str - 包含 HTML 实体的字符串\r\n * @returns {string} 返回解码后的字符串\r\n * @example\r\n * decodeHTMLEntities('&lt;div&gt;') // '<div>'\r\n */\r\nexport const decodeHTMLEntities = (str: string): string => {\r\n if (!_helper_div) {\r\n _helper_div = document.createElement(\"div\");\r\n }\r\n // strip script/html tags\r\n str = str.replace(/<script[^>]*>([\\S\\s]*?)<\\/script>/gim, \"\");\r\n str = str.replace(/<\\/?\\w(?:[^\"'>]|\"[^\"]*\"|'[^']*')*>/gim, \"\");\r\n _helper_div.innerHTML = str;\r\n str = _helper_div.textContent || \"\";\r\n _helper_div.textContent = \"\";\r\n return str;\r\n};\r\n\r\n/**\r\n * 构建 HTML Input:hidden 标签\r\n * @param {Record<string, any>} maps - 键值对对象\r\n * @returns {string} 返回 HTML 字符串\r\n * @example\r\n * buildHtmlHidden({name: 'John', age: 30}) // '<input type=\"hidden\" name=\"name\" value=\"John\"/>...'\r\n */\r\nexport const buildHtmlHidden = (maps: Record<string, any>): string => {\r\n let html = \"\";\r\n for (let key in maps) {\r\n let val = maps[key] === null ? \"\" : maps[key];\r\n html += `<input type=\"hidden\" name=\"${escapeAttr(key)}\" value=\"${escapeAttr(val)}\"/>`;\r\n }\r\n return html;\r\n};\r\n\r\n/**\r\n * 转义 HTML(将特殊字符转换为 HTML 实体)\r\n * @param {string} str - 要转义的字符串\r\n * @param {number} [tabSize=2] - Tab 宽度,如果设置为 0,表示去除 tab\r\n * @param {boolean} [allowLineBreaker=true] - 是否允许换行\r\n * @returns {string} 返回转义后的 HTML\r\n * @example\r\n * escapeHtml('<div>Hello</div>') // '&lt;div&gt;Hello&lt;/div&gt;'\r\n */\r\nexport const escapeHtml = (str: string, tabSize: number = 2, allowLineBreaker: boolean = true): string => {\r\n let s = String(str).replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\").replace(/\"/g, \"&quot;\").replace(/'/g, \"&#039;\");\r\n if (allowLineBreaker) {\r\n s = s.replace(/[\\r\\n]/g, \"<br/>\");\r\n }\r\n if (tabSize) {\r\n s = s.replace(/\\t/g, \"&nbsp;\".repeat(tabSize));\r\n }\r\n s = s.replace(/\\s/g, \"&nbsp;\");\r\n return s;\r\n};\r\n\r\n/**\r\n * 反转义 HTML(将 HTML 实体转换为字符)\r\n * @param {string} html - 包含 HTML 实体的字符串\r\n * @returns {string} 返回反转义后的字符串\r\n * @example\r\n * unescapeHtml('&lt;div&gt;') // '<div>'\r\n */\r\nexport const unescapeHtml = (html: string): string => {\r\n return String(html)\r\n .replace(/&quot;/g, '\"')\r\n .replace(/&#39;/g, \"'\")\r\n .replace(/&lt;/g, \"<\")\r\n .replace(/&gt;/g, \">\")\r\n .replace(/&nbsp;/g, \" \")\r\n .replace(/&amp;/g, \"&\")\r\n .replace(/<br.*>/, \"\\n\");\r\n};\r\n\r\n/**\r\n * 转义 HTML 到属性值(处理属性中的特殊字符)\r\n * @param {string} s - 要转义的字符串\r\n * @param {string} [preserveCR=''] - 是否保留回车符\r\n * @returns {string} 返回转义后的字符串\r\n * @example\r\n * escapeAttr('Hello \"World\"') // 'Hello &quot;World&quot;'\r\n */\r\nexport const escapeAttr = (s: string, preserveCR: string = \"\"): string => {\r\n preserveCR = preserveCR ? \"&#13;\" : \"\\n\";\r\n return (\r\n (\"\" + s) /* Forces the conversion to string. */\r\n .replace(/&/g, \"&amp;\") /* This MUST be the 1st replacement. */\r\n .replace(/'/g, \"&apos;\") /* The 4 other predefined entities, required. */\r\n .replace(/\"/g, \"&quot;\")\r\n .replace(/</g, \"&lt;\")\r\n .replace(/>/g, \"&gt;\")\r\n /*\r\n\t\tYou may add other replacements here for HTML only\r\n\t\t(but it's not necessary).\r\n\t\tOr for XML, only if the named entities are defined in its DTD.\r\n\t\t*/\r\n .replace(/\\r\\n/g, preserveCR) /* Must be before the next replacement. */\r\n .replace(/[\\r\\n]/g, preserveCR)\r\n );\r\n};\r\n\r\n/**\r\n * 字符串转换为 HTML 实体\r\n * @param {string} str - 要转换的字符串\r\n * @param {number} [radix] - 进制,为 16 时使用十六进制\r\n * @returns {string} 返回 HTML 实体字符串\r\n * @example\r\n * stringToEntity('AB', 16) // '&#x41;&#x42;'\r\n */\r\nexport const stringToEntity = (str: string, radix?: number): string => {\r\n let arr = str.split(\"\");\r\n radix = radix || 0;\r\n return arr.map((item: string) => `&#${radix ? \"x\" + item.charCodeAt(0).toString(16) : item.charCodeAt(0)};`).join(\"\");\r\n};\r\n\r\n/**\r\n * 高亮文本(将关键字用指定模板包裹)\r\n * @param {string} text - 原始文本\r\n * @param {string} kw - 关键字\r\n * @param {string} [replaceTpl='<span class=\"matched\">%s</span>'] - 替换模板,%s 为占位符\r\n * @returns {string} 返回高亮后的 HTML\r\n * @example\r\n * highlightText('Hello World', 'World') // 'Hello <span class=\"matched\">World</span>'\r\n */\r\nexport const highlightText = (text: string, kw: string, replaceTpl: string = '<span class=\"matched\">%s</span>'): string => {\r\n if (!kw) {\r\n return text;\r\n }\r\n return text.replace(new RegExp(regQuote(kw), \"ig\"), (match: string) => {\r\n return replaceTpl.replace(\"%s\", match);\r\n });\r\n};\r\n","import { blobToBase64 } from \"./base64\";\r\nimport { urlB64DataCache } from \"./file\";\r\n\r\n/**\r\n * 通过 Image 元素获取 Base64 数据\r\n * @param {HTMLImageElement} img - 图片元素\r\n * @returns {string|null} 返回 Base64 Data URL,失败返回 null\r\n * @example\r\n * imgToBase64(imageElement) // 'data:image/png;base64,...'\r\n */\r\nexport const imgToBase64 = (img: HTMLImageElement): string | null => {\r\n if (!img.src) {\r\n return null;\r\n }\r\n if (img.src.indexOf(\"data:\") === 0) {\r\n return img.src;\r\n }\r\n let canvas = document.createElement(\"canvas\");\r\n canvas.width = img.width;\r\n canvas.height = img.height;\r\n let ctx = canvas.getContext(\"2d\");\r\n if (!ctx) return null;\r\n ctx.drawImage(img, 0, 0, img.width, img.height);\r\n return canvas.toDataURL(\"image/png\");\r\n};\r\n\r\n/**\r\n * 通过图片 URL 获取 Base64(网络请求模式)\r\n * @param {string} src - 图片 URL\r\n * @param {boolean} [cache=false] - 是否缓存结果\r\n * @returns {Promise<unknown>} 返回 Base64 Data URL 的 Promise\r\n * @example\r\n * srcToBase64('https://example.com/image.png').then(base64 => console.log(base64))\r\n */\r\nexport const srcToBase64 = (src: string, cache: boolean = false): Promise<unknown> => {\r\n return new Promise((resolve, reject) => {\r\n if (cache) {\r\n const cached = urlB64DataCache(src);\r\n if (cached) {\r\n return resolve(cached);\r\n }\r\n }\r\n let xhr = new XMLHttpRequest();\r\n xhr.open(\"GET\", src, true);\r\n xhr.responseType = \"blob\";\r\n xhr.onload = function () {\r\n if (this.status === 200) {\r\n let blob = this.response;\r\n blobToBase64(blob)\r\n .then((base64) => {\r\n if (cache) {\r\n urlB64DataCache(src, base64 as string);\r\n }\r\n resolve(base64);\r\n })\r\n .catch((error) => {\r\n reject(error);\r\n });\r\n }\r\n };\r\n xhr.onerror = function () {\r\n reject(\"Error:\" + this.statusText);\r\n };\r\n xhr.onabort = function () {\r\n reject(\"Request abort\");\r\n };\r\n xhr.send();\r\n });\r\n};\r\n","/**\r\n * 将整数相加,在 2^32 处溢出(使用 16 位运算避免 JS 解释器 bug)\r\n * @param {number} x - 第一个整数\r\n * @param {number} y - 第二个整数\r\n * @returns {number} 返回相加结果\r\n */\r\nconst safeAdd = (x: number, y: number): number => {\r\n\tlet lsw = (x & 0xffff) + (y & 0xffff);\r\n\tlet msw = (x >> 16) + (y >> 16) + (lsw >> 16);\r\n\treturn (msw << 16) | (lsw & 0xffff)\r\n}\r\n\r\n/**\r\n * 将 32 位数字向左旋转\r\n * @param {number} num - 要旋转的数字\r\n * @param {number} cnt - 旋转的位数\r\n * @returns {number} 返回旋转后的结果\r\n */\r\nconst bitRotateLeft = (num: number, cnt: number): number => {\r\n\treturn (num << cnt) | (num >>> (32 - cnt))\r\n}\r\n\r\n/**\r\n* These functions implement the four basic operations the algorithm uses.\r\n*/\r\nconst md5cmn = (q: number, a: number, b: number, x: number, s: number, t: number): number => {\r\n\treturn safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b)\r\n}\r\n\r\nconst md5ff = (a: number, b: number, c: number, d: number, x: number, s: number, t: number): number => {\r\n\treturn md5cmn((b & c) | (~b & d), a, b, x, s, t)\r\n}\r\n\r\nconst md5gg = (a: number, b: number, c: number, d: number, x: number, s: number, t: number): number => {\r\n\treturn md5cmn((b & d) | (c & ~d), a, b, x, s, t)\r\n}\r\n\r\nconst md5hh = (a: number, b: number, c: number, d: number, x: number, s: number, t: number): number => {\r\n\treturn md5cmn(b ^ c ^ d, a, b, x, s, t)\r\n}\r\n\r\nconst md5ii = (a: number, b: number, c: number, d: number, x: number, s: number, t: number): number => {\r\n\treturn md5cmn(c ^ (b | ~d), a, b, x, s, t)\r\n}\r\n\r\n/**\r\n* Calculate the MD5 of an array of little-endian words, and a bit length.\r\n*/\r\nconst binlMD5 = (x: number[], len: number): number[] => {\r\n\t/* append padding */\r\n\tx[len >> 5] |= 0x80 << (len % 32);\r\n\tx[((len + 64) >>> 9 << 4) + 14] = len;\r\n\r\n\tlet i: number;\r\n\tlet olda: number;\r\n\tlet oldb: number;\r\n\tlet oldc: number;\r\n\tlet oldd: number;\r\n\tlet a: number = 1732584193;\r\n\tlet b: number = -271733879;\r\n\tlet c: number = -1732584194;\r\n\tlet d: number = 271733878;\r\n\r\n\tfor(i = 0; i < x.length; i += 16){\r\n\t\tolda = a;\r\n\t\toldb = b;\r\n\t\toldc = c;\r\n\t\toldd = d;\r\n\r\n\t\ta = md5ff(a, b, c, d, x[i], 7, -680876936);\r\n\t\td = md5ff(d, a, b, c, x[i + 1], 12, -389564586);\r\n\t\tc = md5ff(c, d, a, b, x[i + 2], 17, 606105819);\r\n\t\tb = md5ff(b, c, d, a, x[i + 3], 22, -1044525330);\r\n\t\ta = md5ff(a, b, c, d, x[i + 4], 7, -176418897);\r\n\t\td = md5ff(d, a, b, c, x[i + 5], 12, 1200080426);\r\n\t\tc = md5ff(c, d, a, b, x[i + 6], 17, -1473231341);\r\n\t\tb = md5ff(b, c, d, a, x[i + 7], 22, -45705983);\r\n\t\ta = md5ff(a, b, c, d, x[i + 8], 7, 1770035416);\r\n\t\td = md5ff(d, a, b, c, x[i + 9], 12, -1958414417);\r\n\t\tc = md5ff(c, d, a, b, x[i + 10], 17, -42063);\r\n\t\tb = md5ff(b, c, d, a, x[i + 11], 22, -1990404162);\r\n\t\ta = md5ff(a, b, c, d, x[i + 12], 7, 1804603682);\r\n\t\td = md5ff(d, a, b, c, x[i + 13], 12, -40341101);\r\n\t\tc = md5ff(c, d, a, b, x[i + 14], 17, -1502002290);\r\n\t\tb = md5ff(b, c, d, a, x[i + 15], 22, 1236535329);\r\n\r\n\t\ta = md5gg(a, b, c, d, x[i + 1], 5, -165796510);\r\n\t\td = md5gg(d, a, b, c, x[i + 6], 9, -1069501632);\r\n\t\tc = md5gg(c, d, a, b, x[i + 11], 14, 643717713);\r\n\t\tb = md5gg(b, c, d, a, x[i], 20, -373897302);\r\n\t\ta = md5gg(a, b, c, d, x[i + 5], 5, -701558691);\r\n\t\td = md5gg(d, a, b, c, x[i + 10], 9, 38016083);\r\n\t\tc = md5gg(c, d, a, b, x[i + 15], 14, -660478335);\r\n\t\tb = md5gg(b, c, d, a, x[i + 4], 20, -405537848);\r\n\t\ta = md5gg(a, b, c, d, x[i + 9], 5, 568446438);\r\n\t\td = md5gg(d, a, b, c, x[i + 14], 9, -1019803690);\r\n\t\tc = md5gg(c, d, a, b, x[i + 3], 14, -187363961);\r\n\t\tb = md5gg(b, c, d, a, x[i + 8], 20, 1163531501);\r\n\t\ta = md5gg(a, b, c, d, x[i + 13], 5, -1444681467);\r\n\t\td = md5gg(d, a, b, c, x[i + 2], 9, -51403784);\r\n\t\tc = md5gg(c, d, a, b, x[i + 7], 14, 1735328473);\r\n\t\tb = md5gg(b, c, d, a, x[i + 12], 20, -1926607734);\r\n\r\n\t\ta = md5hh(a, b, c, d, x[i + 5], 4, -378558);\r\n\t\td = md5hh(d, a, b, c, x[i + 8], 11, -2022574463);\r\n\t\tc = md5hh(c, d, a, b, x[i + 11], 16, 1839030562);\r\n\t\tb = md5hh(b, c, d, a, x[i + 14], 23, -35309556);\r\n\t\ta = md5hh(a, b, c, d, x[i + 1], 4, -1530992060);\r\n\t\td = md5hh(d, a, b, c, x[i + 4], 11, 1272893353);\r\n\t\tc = md5hh(c, d, a, b, x[i + 7], 16, -155497632);\r\n\t\tb = md5hh(b, c, d, a, x[i + 10], 23, -1094730640);\r\n\t\ta = md5hh(a, b, c, d, x[i + 13], 4, 681279174);\r\n\t\td = md5hh(d, a, b, c, x[i], 11, -358537222);\r\n\t\tc = md5hh(c, d, a, b, x[i + 3], 16, -722521979);\r\n\t\tb = md5hh(b, c, d, a, x[i + 6], 23, 76029189);\r\n\t\ta = md5hh(a, b, c, d, x[i + 9], 4, -640364487);\r\n\t\td = md5hh(d, a, b, c, x[i + 12], 11, -421815835);\r\n\t\tc = md5hh(c, d, a, b, x[i + 15], 16, 530742520);\r\n\t\tb = md5hh(b, c, d, a, x[i + 2], 23, -995338651);\r\n\r\n\t\ta = md5ii(a, b, c, d, x[i], 6, -198630844);\r\n\t\td = md5ii(d, a, b, c, x[i + 7], 10, 1126891415);\r\n\t\tc = md5ii(c, d, a, b, x[i + 14], 15, -1416354905);\r\n\t\tb = md5ii(b, c, d, a, x[i + 5], 21, -57434055);\r\n\t\ta = md5ii(a, b, c, d, x[i + 12], 6, 1700485571);\r\n\t\td = md5ii(d, a, b, c, x[i + 3], 10, -1894986606);\r\n\t\tc = md5ii(c, d, a, b, x[i + 10], 15, -1051523);\r\n\t\tb = md5ii(b, c, d, a, x[i + 1], 21, -2054922799);\r\n\t\ta = md5ii(a, b, c, d, x[i + 8], 6, 1873313359);\r\n\t\td = md5ii(d, a, b, c, x[i + 15], 10, -30611744);\r\n\t\tc = md5ii(c, d, a, b, x[i + 6], 15, -1560198380);\r\n\t\tb = md5ii(b, c, d, a, x[i + 13], 21, 1309151649);\r\n\t\ta = md5ii(a, b, c, d, x[i + 4], 6, -145523070);\r\n\t\td = md5ii(d, a, b, c, x[i + 11], 10, -1120210379);\r\n\t\tc = md5ii(c, d, a, b, x[i + 2], 15, 718787259);\r\n\t\tb = md5ii(b, c, d, a, x[i + 9], 21, -343485551);\r\n\r\n\t\ta = safeAdd(a, olda)\r\n\t\tb = safeAdd(b, oldb)\r\n\t\tc = safeAdd(c, oldc)\r\n\t\td = safeAdd(d, oldd)\r\n\t}\r\n\treturn [a, b, c, d]\r\n}\r\n\r\n/**\r\n* Convert an array of little-endian words to a string\r\n*/\r\nconst binl2rstr = (input: number[]): string => {\r\n\tlet i: number;\r\n\tlet output: string = '';\r\n\tlet length32: number = input.length * 32;\r\n\tfor(i = 0; i < length32; i += 8){\r\n\t\toutput += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xff)\r\n\t}\r\n\treturn output\r\n}\r\n\r\n/**\r\n* Convert a raw string to an array of little-endian words\r\n* Characters >255 have their high-byte silently ignored.\r\n*/\r\nconst rstr2binl = (input: string): number[] => {\r\n\tlet i: number;\r\n\tlet output: number[] = [];\r\n\toutput[(input.length >> 2) - 1] = undefined as any;\r\n\tfor(i = 0; i < output.length; i += 1){\r\n\t\toutput[i] = 0\r\n\t}\r\n\tlet length8: number = input.length * 8;\r\n\tfor(i = 0; i < length8; i += 8){\r\n\t\toutput[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << (i % 32)\r\n\t}\r\n\treturn output\r\n}\r\n\r\n/**\r\n* Calculate the MD5 of a raw string\r\n*/\r\nconst rstrMD5 = (s: string): string => {\r\n\treturn binl2rstr(binlMD5(rstr2binl(s), s.length * 8))\r\n}\r\n\r\n/**\r\n* Calculate the HMAC-MD5, of a key and some data (raw strings)\r\n*/\r\nconst rstrHMACMD5 = (key: string, data: string): string => {\r\n\tlet i: number;\r\n\tlet bkey: number[] = rstr2binl(key);\r\n\tlet ipad: number[] = [];\r\n\tlet opad: number[] = [];\r\n\tlet hash: number[];\r\n\tipad[15] = opad[15] = undefined as any;\r\n\tif(bkey.length > 16){\r\n\t\tbkey = binlMD5(bkey, key.length * 8)\r\n\t}\r\n\tfor(i = 0; i < 16; i += 1){\r\n\t\tipad[i] = bkey[i] ^ 0x36363636;\r\n\t\topad[i] = bkey[i] ^ 0x5c5c5c5c\r\n\t}\r\n\thash = binlMD5(ipad.concat(rstr2binl(data)), 512 + data.length * 8);\r\n\treturn binl2rstr(binlMD5(opad.concat(hash), 512 + 128))\r\n}\r\n\r\n/**\r\n* Convert a raw string to a hex string\r\n*/\r\nconst rstr2hex = (input: string): string => {\r\n\tlet hexTab: string = '0123456789abcdef';\r\n\tlet output: string = '';\r\n\tlet x: number;\r\n\tlet i: number;\r\n\tfor(i = 0; i < input.length; i += 1){\r\n\t\tx = input.charCodeAt(i);\r\n\t\toutput += hexTab.charAt((x >>> 4) & 0x0f) + hexTab.charAt(x & 0x0f)\r\n\t}\r\n\treturn output\r\n}\r\n\r\n/**\r\n* Encode a string as utf-8\r\n*/\r\nconst str2rstrUTF8 = (input: string): string => {\r\n\treturn unescape(encodeURIComponent(input))\r\n}\r\n\r\n/**\r\n* Take string arguments and return either raw or hex encoded strings\r\n*/\r\nconst rawMD5 = (s: string): string => {\r\n\treturn rstrMD5(str2rstrUTF8(s))\r\n}\r\n\r\nconst hexMD5 = (s: string): string => {\r\n\treturn rstr2hex(rawMD5(s))\r\n}\r\n\r\nconst rawHMACMD5 = (k: string, d: string): string => {\r\n\treturn rstrHMACMD5(str2rstrUTF8(k), str2rstrUTF8(d))\r\n}\r\n\r\nconst hexHMACMD5 = (k: string, d: string): string => {\r\n\treturn rstr2hex(rawHMACMD5(k, d))\r\n}\r\n\r\n/**\r\n * 计算字符串的 MD5 哈希值\r\n * @param {string} string - 要计算 MD5 的字符串\r\n * @param {string} [key] - HMAC 密钥(可选)\r\n * @param {boolean} [raw] - 是否返回原始字符串,默认返回十六进制字符串\r\n * @returns {string} 返回 MD5 哈希值\r\n * @example\r\n * md5('Hello World') // 'b10a8db164e0754105b7a99be72e3fe5'\r\n */\r\nexport const md5 = (string: string, key?: string, raw?: boolean): string => {\r\n\tif(!key){\r\n\t\tif(!raw){\r\n\t\t\treturn hexMD5(string)\r\n\t\t}\r\n\t\treturn rawMD5(string)\r\n\t}\r\n\tif(!raw){\r\n\t\treturn hexHMACMD5(key, string)\r\n\t}\r\n\treturn rawHMACMD5(key, string)\r\n};\r\n","/**\r\n * 缺省二进制文件MIME\r\n * @see https://datatracker.ietf.org/doc/html/rfc2046\r\n * @type {String}\r\n */\r\nexport const MIME_BINARY_DEFAULT = 'application/octet-stream';\r\n\r\nexport const MIME_JSON = \"application/json\";\r\nexport const MIME_FORM = \"application/x-www-form-urlencoded\";\r\nexport const MIME_MULTIPART = \"multipart/form-data\";\r\nexport const MIME_TEXT = \"text/plain\";\r\nexport const MIME_HTML = \"text/html\";\r\n\r\n\r\n/**\r\n * MIME常见扩展名映射表\r\n * @type {Object}\r\n */\r\nexport const MIME_EXTENSION_MAP = {\r\n\t\"323\": \"text/h323\",\r\n\t\"accdb\": \"application/msaccess\",\r\n\t\"accde\": \"application/msaccess\",\r\n\t\"accdt\": \"application/msaccess\",\r\n\t\"acx\": \"application/internet-property-stream\",\r\n\t\"ai\": \"application/postscript\",\r\n\t\"aif\": \"audio/x-aiff\",\r\n\t\"aifc\": \"audio/aiff\",\r\n\t\"aiff\": \"audio/aiff\",\r\n\t\"application\": \"application/x-ms-application\",\r\n\t\"art\": \"image/x-jg\",\r\n\t\"asf\": \"video/x-ms-asf\",\r\n\t\"asm\": \"text/plain\",\r\n\t\"asr\": \"video/x-ms-asf\",\r\n\t\"asx\": \"video/x-ms-asf\",\r\n\t\"atom\": \"application/atom+xml\",\r\n\t\"au\": \"audio/basic\",\r\n\t\"avi\": \"video/x-msvideo\",\r\n\t\"axs\": \"application/olescript\",\r\n\t\"bas\": \"text/plain\",\r\n\t\"bcpio\": \"application/x-bcpio\",\r\n\t\"bmp\": \"image/bmp\",\r\n\t\"c\": \"text/plain\",\r\n\t\"calx\": \"application/vnd.ms-office.calx\",\r\n\t\"cat\": \"application/vnd.ms-pki.seccat\",\r\n\t\"cdf\": \"application/x-cdf\",\r\n\t\"class\": \"application/x-java-applet\",\r\n\t\"clp\": \"application/x-msclip\",\r\n\t\"cmx\": \"image/x-cmx\",\r\n\t\"cnf\": \"text/plain\",\r\n\t\"cod\": \"image/cis-cod\",\r\n\t\"cpio\": \"application/x-cpio\",\r\n\t\"cpp\": \"text/plain\",\r\n\t\"crd\": \"application/x-mscardfile\",\r\n\t\"crl\": \"application/pkix-crl\",\r\n\t\"crt\": \"application/x-x509-ca-cert\",\r\n\t\"csh\": \"application/x-csh\",\r\n\t\"css\": \"text/css\",\r\n\t\"dcr\": \"application/x-director\",\r\n\t\"der\": \"application/x-x509-ca-cert\",\r\n\t\"dib\": \"image/bmp\",\r\n\t\"dir\": \"application/x-director\",\r\n\t\"disco\": \"text/xml\",\r\n\t\"dll\": \"application/x-msdownload\",\r\n\t\"dll.config\": \"text/xml\",\r\n\t\"dlm\": \"text/dlm\",\r\n\t\"doc\": \"application/msword\",\r\n\t\"docm\": \"application/vnd.ms-word.document.macroEnabled.12\",\r\n\t\"docx\": \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\r\n\t\"dot\": \"application/msword\",\r\n\t\"dotm\": \"application/vnd.ms-word.template.macroEnabled.12\",\r\n\t\"dotx\": \"application/vnd.openxmlformats-officedocument.wordprocessingml.template\",\r\n\t\"dtd\": \"text/xml\",\r\n\t\"dvi\": \"application/x-dvi\",\r\n\t\"dwf\": \"drawing/x-dwf\",\r\n\t\"dxr\": \"application/x-director\",\r\n\t\"eml\": \"message/rfc822\",\r\n\t\"eps\": \"application/postscript\",\r\n\t\"etx\": \"text/x-setext\",\r\n\t\"evy\": \"application/envoy\",\r\n\t\"exe.config\": \"text/xml\",\r\n\t\"fdf\": \"application/vnd.fdf\",\r\n\t\"fif\": \"application/fractals\",\r\n\t\"flr\": \"x-world/x-vrml\",\r\n\t\"flv\": \"video/x-flv\",\r\n\t\"gif\": \"image/gif\",\r\n\t\"gtar\": \"application/x-gtar\",\r\n\t\"gz\": \"application/x-gzip\",\r\n\t\"h\": \"text/plain\",\r\n\t\"hdf\": \"application/x-hdf\",\r\n\t\"hdml\": \"text/x-hdml\",\r\n\t\"hhc\": \"application/x-oleobject\",\r\n\t\"hlp\": \"application/winhlp\",\r\n\t\"hqx\": \"application/mac-binhex40\",\r\n\t\"hta\": \"application/hta\",\r\n\t\"htc\": \"text/x-component\",\r\n\t\"htm\": \"text/html\",\r\n\t\"html\": \"text/html\",\r\n\t\"htt\": \"text/webviewhtml\",\r\n\t\"hxt\": \"text/html\",\r\n\t\"ico\": \"image/x-icon\",\r\n\t\"ief\": \"image/ief\",\r\n\t\"iii\": \"application/x-iphone\",\r\n\t\"ins\": \"application/x-internet-signup\",\r\n\t\"isp\": \"application/x-internet-signup\",\r\n\t\"IVF\": \"video/x-ivf\",\r\n\t\"jar\": \"application/java-archive\",\r\n\t\"jck\": \"application/liquidmotion\",\r\n\t\"jcz\": \"application/liquidmotion\",\r\n\t\"jfif\": \"image/pjpeg\",\r\n\t\"jpe\": \"image/jpeg\",\r\n\t\"jpeg\": \"image/jpeg\",\r\n\t\"jpg\": \"image/jpeg\",\r\n\t\"js\": \"application/x-javascript\",\r\n\t\"jsx\": \"text/jscript\",\r\n\t\"latex\": \"application/x-latex\",\r\n\t\"lit\": \"application/x-ms-reader\",\r\n\t\"lsf\": \"video/x-la-asf\",\r\n\t\"lsx\": \"video/x-la-asf\",\r\n\t\"m13\": \"application/x-msmediaview\",\r\n\t\"m14\": \"application/x-msmediaview\",\r\n\t\"m1v\": \"video/mpeg\",\r\n\t\"m3u\": \"audio/x-mpegurl\",\r\n\t\"man\": \"application/x-troff-man\",\r\n\t\"manifest\": \"application/x-ms-manifest\",\r\n\t\"map\": \"text/plain\",\r\n\t\"mdb\": \"application/x-msaccess\",\r\n\t\"me\": \"application/x-troff-me\",\r\n\t\"mht\": \"message/rfc822\",\r\n\t\"mhtml\": \"message/rfc822\",\r\n\t\"mid\": \"audio/mid\",\r\n\t\"midi\": \"audio/mid\",\r\n\t\"mmf\": \"application/x-smaf\",\r\n\t\"mno\": \"text/xml\",\r\n\t\"mny\": \"application/x-msmoney\",\r\n\t\"mov\": \"video/quicktime\",\r\n\t\"movie\": \"video/x-sgi-movie\",\r\n\t\"mp2\": \"video/mpeg\",\r\n\t\"mp3\": \"audio/mpeg\",\r\n\t\"mpa\": \"video/mpeg\",\r\n\t\"mpe\": \"video/mpeg\",\r\n\t\"mpeg\": \"video/mpeg\",\r\n\t\"mpg\": \"video/mpeg\",\r\n\t\"mpp\": \"application/vnd.ms-project\",\r\n\t\"mpv2\": \"video/mpeg\",\r\n\t\"ms\": \"application/x-troff-ms\",\r\n\t\"mvb\": \"application/x-msmediaview\",\r\n\t\"mvc\": \"application/x-miva-compiled\",\r\n\t\"nc\": \"application/x-netcdf\",\r\n\t\"nsc\": \"video/x-ms-asf\",\r\n\t\"nws\": \"message/rfc822\",\r\n\t\"oda\": \"application/oda\",\r\n\t\"odc\": \"text/x-ms-odc\",\r\n\t\"ods\": \"application/oleobject\",\r\n\t\"one\": \"application/onenote\",\r\n\t\"onea\": \"application/onenote\",\r\n\t\"onetoc\": \"application/onenote\",\r\n\t\"onetoc2\": \"application/onenote\",\r\n\t\"onetmp\": \"application/onenote\",\r\n\t\"onepkg\": \"application/onenote\",\r\n\t\"osdx\": \"application/opensearchdescription+xml\",\r\n\t\"p10\": \"application/pkcs10\",\r\n\t\"p12\": \"application/x-pkcs12\",\r\n\t\"p7b\": \"application/x-pkcs7-certificates\",\r\n\t\"p7c\": \"application/pkcs7-mime\",\r\n\t\"p7m\": \"application/pkcs7-mime\",\r\n\t\"p7r\": \"application/x-pkcs7-certreqresp\",\r\n\t\"p7s\": \"application/pkcs7-signature\",\r\n\t\"pbm\": \"image/x-portable-bitmap\",\r\n\t\"pdf\": \"application/pdf\",\r\n\t\"pfx\": \"application/x-pkcs12\",\r\n\t\"pgm\": \"image/x-portable-graymap\",\r\n\t\"pko\": \"application/vnd.ms-pki.pko\",\r\n\t\"pma\": \"application/x-perfmon\",\r\n\t\"pmc\": \"application/x-perfmon\",\r\n\t\"pml\": \"application/x-perfmon\",\r\n\t\"pmr\": \"application/x-perfmon\",\r\n\t\"pmw\": \"application/x-perfmon\",\r\n\t\"png\": \"image/png\",\r\n\t\"pnm\": \"image/x-portable-anymap\",\r\n\t\"pnz\": \"image/png\",\r\n\t\"pot\": \"application/vnd.ms-powerpoint\",\r\n\t\"potm\": \"application/vnd.ms-powerpoint.template.macroEnabled.12\",\r\n\t\"potx\": \"application/vnd.openxmlformats-officedocument.presentationml.template\",\r\n\t\"ppam\": \"application/vnd.ms-powerpoint.addin.macroEnabled.12\",\r\n\t\"ppm\": \"image/x-portable-pixmap\",\r\n\t\"pps\": \"application/vnd.ms-powerpoint\",\r\n\t\"ppsm\": \"application/vnd.ms-powerpoint.slideshow.macroEnabled.12\",\r\n\t\"ppsx\": \"application/vnd.openxmlformats-officedocument.presentationml.slideshow\",\r\n\t\"ppt\": \"application/vnd.ms-powerpoint\",\r\n\t\"pptm\": \"application/vnd.ms-powerpoint.presentation.macroEnabled.12\",\r\n\t\"pptx\": \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\r\n\t\"prf\": \"application/pics-rules\",\r\n\t\"ps\": \"application/postscript\",\r\n\t\"pub\": \"application/x-mspublisher\",\r\n\t\"qt\": \"video/quicktime\",\r\n\t\"qtl\": \"application/x-quicktimeplayer\",\r\n\t\"ra\": \"audio/x-pn-realaudio\",\r\n\t\"ram\": \"audio/x-pn-realaudio\",\r\n\t\"ras\": \"image/x-cmu-raster\",\r\n\t\"rf\": \"image/vnd.rn-realflash\",\r\n\t\"rgb\": \"image/x-rgb\",\r\n\t\"rm\": \"application/vnd.rn-realmedia\",\r\n\t\"rmi\": \"audio/mid\",\r\n\t\"roff\": \"application/x-troff\",\r\n\t\"rpm\": \"audio/x-pn-realaudio-plugin\",\r\n\t\"rtf\": \"application/rtf\",\r\n\t\"rtx\": \"text/richtext\",\r\n\t\"scd\": \"application/x-msschedule\",\r\n\t\"sct\": \"text/scriptlet\",\r\n\t\"setpay\": \"application/set-payment-initiation\",\r\n\t\"setreg\": \"application/set-registration-initiation\",\r\n\t\"sgml\": \"text/sgml\",\r\n\t\"sh\": \"application/x-sh\",\r\n\t\"shar\": \"application/x-shar\",\r\n\t\"sit\": \"application/x-stuffit\",\r\n\t\"sldm\": \"application/vnd.ms-powerpoint.slide.macroEnabled.12\",\r\n\t\"sldx\": \"application/vnd.openxmlformats-officedocument.presentationml.slide\",\r\n\t\"smd\": \"audio/x-smd\",\r\n\t\"smx\": \"audio/x-smd\",\r\n\t\"smz\": \"audio/x-smd\",\r\n\t\"snd\": \"audio/basic\",\r\n\t\"spc\": \"application/x-pkcs7-certificates\",\r\n\t\"spl\": \"application/futuresplash\",\r\n\t\"src\": \"application/x-wais-source\",\r\n\t\"ssm\": \"application/streamingmedia\",\r\n\t\"sst\": \"application/vnd.ms-pki.certstore\",\r\n\t\"stl\": \"application/vnd.ms-pki.stl\",\r\n\t\"sv4cpio\": \"application/x-sv4cpio\",\r\n\t\"sv4crc\": \"application/x-sv4crc\",\r\n\t\"svg\": \"image/svg+xml\",\r\n\t\"swf\": \"application/x-shockwave-flash\",\r\n\t\"t\": \"application/x-troff\",\r\n\t\"tar\": \"application/x-tar\",\r\n\t\"tcl\": \"application/x-tcl\",\r\n\t\"tex\": \"application/x-tex\",\r\n\t\"texi\": \"application/x-texinfo\",\r\n\t\"texinfo\": \"application/x-texinfo\",\r\n\t\"tgz\": \"application/x-compressed\",\r\n\t\"thmx\": \"application/vnd.ms-officetheme\",\r\n\t\"tif\": \"image/tiff\",\r\n\t\"tiff\": \"image/tiff\",\r\n\t\"tr\": \"application/x-troff\",\r\n\t\"trm\": \"application/x-msterminal\",\r\n\t\"tsv\": \"text/tab-separated-values\",\r\n\t\"txt\": \"text/plain\",\r\n\t\"uls\": \"text/iuls\",\r\n\t\"ustar\": \"application/x-ustar\",\r\n\t\"vbs\": \"text/vbscript\",\r\n\t\"vcf\": \"text/x-vcard\",\r\n\t\"vcs\": \"text/plain\",\r\n\t\"vdx\": \"application/vnd.ms-visio.viewer\",\r\n\t\"vml\": \"text/xml\",\r\n\t\"vsd\": \"application/vnd.visio\",\r\n\t\"vss\": \"application/vnd.visio\",\r\n\t\"vst\": \"application/vnd.visio\",\r\n\t\"vsto\": \"application/x-ms-vsto\",\r\n\t\"vsw\": \"application/vnd.visio\",\r\n\t\"vsx\": \"application/vnd.visio\",\r\n\t\"vtx\": \"application/vnd.visio\",\r\n\t\"wav\": \"audio/wav\",\r\n\t\"wax\": \"audio/x-ms-wax\",\r\n\t\"wbmp\": \"image/vnd.wap.wbmp\",\r\n\t\"wcm\": \"application/vnd.ms-works\",\r\n\t\"wdb\": \"application/vnd.ms-works\",\r\n\t\"wks\": \"application/vnd.ms-works\",\r\n\t\"wm\": \"video/x-ms-wm\",\r\n\t\"wma\": \"audio/x-ms-wma\",\r\n\t\"wmd\": \"application/x-ms-wmd\",\r\n\t\"wmf\": \"application/x-msmetafile\",\r\n\t\"wml\": \"text/vnd.wap.wml\",\r\n\t\"wmlc\": \"application/vnd.wap.wmlc\",\r\n\t\"wmls\": \"text/vnd.wap.wmlscript\",\r\n\t\"wmlsc\": \"application/vnd.wap.wmlscriptc\",\r\n\t\"wmp\": \"video/x-ms-wmp\",\r\n\t\"wmv\": \"video/x-ms-wmv\",\r\n\t\"wmx\": \"video/x-ms-wmx\",\r\n\t\"wmz\": \"application/x-ms-wmz\",\r\n\t\"wps\": \"application/vnd.ms-works\",\r\n\t\"wri\": \"application/x-mswrite\",\r\n\t\"wrl\": \"x-world/x-vrml\",\r\n\t\"wrz\": \"x-world/x-vrml\",\r\n\t\"wsdl\": \"text/xml\",\r\n\t\"wvx\": \"video/x-ms-wvx\",\r\n\t\"x\": \"application/directx\",\r\n\t\"xaf\": \"x-world/x-vrml\",\r\n\t\"xaml\": \"application/xaml+xml\",\r\n\t\"xap\": \"application/x-silverlight-app\",\r\n\t\"xbap\": \"application/x-ms-xbap\",\r\n\t\"xbm\": \"image/x-xbitmap\",\r\n\t\"xdr\": \"text/plain\",\r\n\t\"xht\": \"application/xhtml+xml\",\r\n\t\"xhtml\": \"application/xhtml+xml\",\r\n\t\"xla\": \"application/vnd.ms-excel\",\r\n\t\"xlam\": \"application/vnd.ms-excel.addin.macroEnabled.12\",\r\n\t\"xlc\": \"application/vnd.ms-excel\",\r\n\t\"xlm\": \"application/vnd.ms-excel\",\r\n\t\"xls\": \"application/vnd.ms-excel\",\r\n\t\"xlsb\": \"application/vnd.ms-excel.sheet.binary.macroEnabled.12\",\r\n\t\"xlsm\": \"application/vnd.ms-excel.sheet.macroEnabled.12\",\r\n\t\"xlsx\": \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\r\n\t\"xlt\": \"application/vnd.ms-excel\",\r\n\t\"xltm\": \"application/vnd.ms-excel.template.macroEnabled.12\",\r\n\t\"xltx\": \"application/vnd.openxmlformats-officedocument.spreadsheetml.template\",\r\n\t\"xlw\": \"application/vnd.ms-excel\",\r\n\t\"xml\": \"text/xml\",\r\n\t\"xof\": \"x-world/x-vrml\",\r\n\t\"xpm\": \"image/x-xpixmap\",\r\n\t\"xps\": \"application/vnd.ms-xpsdocument\",\r\n\t\"xsd\": \"text/xml\",\r\n\t\"xsf\": \"text/xml\",\r\n\t\"xsl\": \"text/xml\",\r\n\t\"xslt\": \"text/xml\",\r\n\t\"xwd\": \"image/x-xwindowdump\",\r\n\t\"z\": \"application/x-compress\",\r\n\t\"zip\": \"application/x-zip-compressed\"\r\n}","import { MIME_FORM, MIME_JSON, MIME_MULTIPART } from \"./mime\";\r\n\r\n/**\r\n * 将 URL 查询字符串转换为对象\r\n * @param {string} query - 查询字符串\r\n * @returns {Record<string, string>} 返回键值对对象\r\n * @example\r\n * queryToObj('name=John&age=30') // {name: 'John', age: '30'}\r\n */\r\nexport const queryToObj = (query: string): Record<string, string> => {\r\n const obj: Record<string, string> = {};\r\n query\r\n .replace(/^\\?/, \"\")\r\n .split(\"&\")\r\n .forEach((pair) => {\r\n const [key, value] = pair.split(\"=\");\r\n if (key) {\r\n obj[decodeURIComponent(key)] = decodeURIComponent(value || \"\");\r\n }\r\n });\r\n return obj;\r\n};\r\n\r\n/**\r\n * 替换 URL 中的查询参数\r\n * @param {string} url - 原始 URL\r\n * @param {Record<string, any>} newQuery - 新的查询参数对象\r\n * @returns {string} 返回更新后的 URL\r\n * @example\r\n * queryReplace('http://example.com?a=1', {b: 2}) // 'http://example.com?a=1&b=2'\r\n */\r\nexport const queryReplace = (url: string, newQuery: Record<string, any>): string => {\r\n const [baseUrl, queryString] = url.split(\"?\");\r\n const currentQuery = queryString ? queryToObj(queryString) : {};\r\n const mergedQuery = { ...currentQuery, ...newQuery };\r\n const newQueryString = objToQuery(mergedQuery);\r\n return `${baseUrl}?${newQueryString}`;\r\n};\r\n\r\n/**\r\n * 将对象转换为 URL 查询字符串\r\n * @param {Record<string, any>} data - 数据对象\r\n * @returns {string} 返回查询字符串\r\n * @example\r\n * objToQuery({name: 'John', age: 30}) // 'name=John&age=30'\r\n */\r\nexport const objToQuery = (data: Record<string, any>): string => {\r\n if (typeof data === \"undefined\" || typeof data !== \"object\") {\r\n return data;\r\n }\r\n let query = [];\r\n for (let param in data) {\r\n if (data.hasOwnProperty(param)) {\r\n if (data[param] === null) {\r\n continue; //null数据不提交\r\n }\r\n if (typeof data[param] === \"object\" && data[param].length) {\r\n data[param].forEach((item: any) => {\r\n query.push(encodeURI(param + \"=\" + item));\r\n });\r\n } else if (typeof data[param] === \"object\") {\r\n //todo 不处理子级object、空数组情况\r\n } else {\r\n query.push(encodeURI(param + \"=\" + data[param]));\r\n }\r\n }\r\n }\r\n return query.join(\"&\");\r\n};\r\n\r\n/**\r\n * 可中止的 Fetch 请求\r\n */\r\nexport interface AbortablePromise<T> extends Promise<T> {\r\n abort: () => void;\r\n}\r\n\r\n/**\r\n * 拓展原生 Fetch API 实现可中止的请求,支持超时设置\r\n * @param {string} url - 请求 URL\r\n * @param {RequestInit} [fetchOption={}] - fetch请求选项,包括 method、headers、body 等\r\n * @param {number} [timeout=0] - 超时时间,单位毫秒,0 表示不设置超时\r\n * @returns {AbortablePromise<any>} 返回可中止的 Promise 对象\r\n * @example\r\n * const req = abortableFetch('/api/data');\r\n * req.abort('cancled'); // 中止请求\r\n */\r\nexport const abortableFetch = (url: string, fetchOption: RequestInit = {}, timeout = 0): AbortablePromise<any> => {\r\n const controller = new AbortController();\r\n\r\n let timeoutId: number | null = null;\r\n if (timeout) {\r\n timeoutId = setTimeout(() => controller.abort(), timeout);\r\n }\r\n\r\n const clearTimer = () => {\r\n if (timeoutId !== null) {\r\n clearTimeout(timeoutId);\r\n timeoutId = null;\r\n }\r\n };\r\n\r\n const addAbortMethod = (promise: Promise<any>): AbortablePromise<any> => {\r\n const abortablePromise = promise as AbortablePromise<any>;\r\n\r\n // 保存原始方法\r\n const originalThen = abortablePromise.then.bind(abortablePromise);\r\n const originalCatch = abortablePromise.catch.bind(abortablePromise);\r\n const originalFinally = abortablePromise.finally.bind(abortablePromise);\r\n\r\n // 重写方法,确保返回的 Promise 也具有 abort 方法\r\n abortablePromise.then = function (onfulfilled, onrejected) {\r\n return addAbortMethod(originalThen(onfulfilled, onrejected));\r\n };\r\n\r\n abortablePromise.catch = function (onrejected) {\r\n return addAbortMethod(originalCatch(onrejected));\r\n };\r\n\r\n abortablePromise.finally = function (onfinally) {\r\n return addAbortMethod(originalFinally(onfinally));\r\n };\r\n\r\n // 添加 abort 方法\r\n abortablePromise.abort = (reason?: string) => {\r\n clearTimer();\r\n controller.abort(reason || \"Request aborted by user\");\r\n };\r\n\r\n return abortablePromise;\r\n };\r\n\r\n const fetchPromise = fetch(url, {\r\n ...fetchOption,\r\n signal: controller.signal,\r\n })\r\n .then((res) => {\r\n clearTimer();\r\n return res;\r\n })\r\n .catch((err) => {\r\n clearTimer();\r\n throw err;\r\n });\r\n\r\n return addAbortMethod(fetchPromise);\r\n};\r\n\r\n// 扩展 RequestInit,添加 timeout 和其他自定义属性,timeout 用于设置请求超时时间,其他自定义属性可以直接添加到 headers 中\r\ninterface RequestOption extends RequestInit {\r\n timeout?: number;\r\n [key: string]: any;\r\n}\r\n\r\nconst appendHeader = (key: string, value: any, headers: Headers): void => {\r\n if (value == null) return;\r\n // 将驼峰命名转换为 HTTP 头格式 (例如: ContentType -> content-type)\r\n const headerName = key\r\n .replace(/([A-Z])/g, \"-$1\")\r\n .replace(/^-/, \"\")\r\n .toLowerCase();\r\n headers.set(headerName, String(value));\r\n};\r\n\r\n// 判断属性是否为 RequestInit 的标准属性\r\nconst isRequestInitProp = (key: string): boolean => {\r\n return [\r\n \"method\",\r\n \"headers\",\r\n \"body\",\r\n \"mode\",\r\n \"credentials\",\r\n \"cache\",\r\n \"redirect\",\r\n \"referrer\",\r\n \"referrerPolicy\",\r\n \"integrity\",\r\n \"keepalive\",\r\n \"signal\",\r\n \"window\",\r\n ].includes(key);\r\n};\r\n\r\n/**\r\n * 发送 HTTP 请求\r\n * @param {string} url - 请求 URL\r\n * @param {BodyInit|null} [data=null] - 请求数据,可以是字符串、FormData、URLSearchParams、Blob、ArrayBuffer 等,如果是对象会根据 ContentType 自动转换(例如 application/json 会自动 JSON.stringify)\r\n * @param {RequestOption} option - 请求选项\r\n * @returns {AbortablePromise<Response>} 返回可中止的 Promise\r\n * @example\r\n * request('/api/data', null, {method: 'GET'})\r\n */\r\nexport const request = (url: string, data: BodyInit | null = null, option: RequestOption): AbortablePromise<Response> => {\r\n let { timeout, ...fetchOption } = option;\r\n fetchOption = fetchOption || {};\r\n fetchOption.method = fetchOption.method || \"GET\";\r\n\r\n const IS_GET = fetchOption.method.toUpperCase() === \"GET\";\r\n\r\n const headers = new Headers(fetchOption.headers || {});\r\n\r\n //如果 key 不是RequestInit的属性,则添加到 headers 中\r\n for (let key in fetchOption) {\r\n if (!isRequestInitProp(key)) {\r\n appendHeader(key, fetchOption[key], headers);\r\n }\r\n }\r\n\r\n if (IS_GET && data) {\r\n console.log('org url', url);\r\n url = queryReplace(url, typeof data === \"string\" ? queryToObj(data) : data);\r\n console.log('new url', url);\r\n data = null;\r\n }\r\n\r\n return abortableFetch(\r\n url,\r\n {\r\n headers,\r\n ...{\r\n body: !IS_GET ? fixData(data, headers.get(\"content-type\") || undefined) : undefined,\r\n },\r\n ...fetchOption,\r\n },\r\n timeout,\r\n ).then((response) => {\r\n if (!response.ok) {\r\n throw new Error(`HTTP error! status: ${response.status}`);\r\n }\r\n return response;\r\n }) as AbortablePromise<Response>;\r\n};\r\n\r\n/**\r\n * 检测值是否为 BodyInit 可接受的类型\r\n * @param {any} value - 要检测的值\r\n * @returns {boolean} 如果是 BodyInit 可接受的类型返回 true,否则返回 false\r\n */\r\nexport const isBodyInit = (value: any): value is BodyInit => {\r\n return (\r\n typeof value === \"string\" ||\r\n value instanceof FormData ||\r\n value instanceof URLSearchParams ||\r\n value instanceof Blob ||\r\n value instanceof ArrayBuffer ||\r\n ArrayBuffer.isView(value)\r\n );\r\n};\r\n\r\nconst fixData = (data: any, contentType?: string) => {\r\n if (isBodyInit(data)) {\r\n return data;\r\n }\r\n if (typeof data !== \"object\") {\r\n return data;\r\n }\r\n switch (contentType?.toLowerCase()) {\r\n case MIME_JSON:\r\n return JSON.stringify(data);\r\n case MIME_FORM:\r\n case MIME_MULTIPART:\r\n default:\r\n return objToQuery(data);\r\n }\r\n};\r\n\r\n/**\r\n * 发送 GET 请求并获取 JSON 响应\r\n * @param {string} url - 请求 URL\r\n * @param {any} [data=null] - 请求数据\r\n * @param {RequestOption} [option={}] - 请求选项\r\n * @returns {Promise<any>} 返回解析后的 JSON 数据\r\n * @example\r\n * getJson('/api/users').then(data => console.log(data))\r\n */\r\nexport const getJson = (url: string, data: any = null, option: RequestOption = {}) => {\r\n return request(url, data, { ...option, ContentType: MIME_JSON, Accept: MIME_JSON }).then((response) => response.json());\r\n};\r\n\r\n/**\r\n * 发送 POST 请求并获取 JSON 响应\r\n * @param {string} url - 请求 URL\r\n * @param {any} [data=null] - 请求数据\r\n * @param {RequestOption} [option={}] - 请求选项\r\n * @returns {Promise<any>} 返回解析后的 JSON 数据\r\n * @example\r\n * postJson('/api/users', {name: 'John'}).then(data => console.log(data))\r\n */\r\nexport const postJson = (url: string, data: any = null, option: RequestOption = {}) => {\r\n return request(url, data, { ...option, method: \"POST\", ContentType: MIME_JSON, Accept: MIME_JSON }).then((response) => response.json());\r\n};\r\n\r\n/**\r\n * 上传文件\r\n * @param {string} url - 请求 URL\r\n * @param {Record<string, File>} fileMap - 文件对象映射\r\n * @param {any} [data=null] - 额外的表单数据\r\n * @param {RequestOption} [option={}] - 请求选项\r\n * @returns {Promise<any>} 返回解析后的 JSON 数据\r\n * @example\r\n * postFiles('/api/upload', {avatar: fileObject})\r\n */\r\nexport const postFiles = (url: string, fileMap: Record<string, File>, data: any = null, option: RequestOption = {}) => {\r\n const formData = new FormData();\r\n Object.keys(fileMap).forEach((key) => {\r\n formData.append(key, fileMap[key], fileMap[key].name);\r\n });\r\n if (data) {\r\n for (let key in data) {\r\n if (data.hasOwnProperty(key)) {\r\n formData.append(key, data[key]);\r\n }\r\n }\r\n }\r\n return request(url, formData, { ...option, method: \"POST\" }).then((response) => response.json());\r\n};\r\n","/**\r\n * 深拷贝对象\r\n * @param obj - 要拷贝的对象\r\n * @returns 拷贝后的新对象\r\n * @example\r\n * deepClone({ a: 1, b: { c: 2 } })\r\n */\r\nexport function deepClone<T>(obj: T): T {\r\n if (obj === null || typeof obj !== \"object\") return obj;\r\n if (obj instanceof Date) return new Date(obj.getTime()) as T;\r\n if (obj instanceof Array) return obj.map((item) => deepClone(item)) as T;\r\n if (obj instanceof Object) {\r\n const clonedObj = {} as T;\r\n for (const key in obj) {\r\n if (obj.hasOwnProperty(key)) {\r\n clonedObj[key] = deepClone(obj[key]);\r\n }\r\n }\r\n return clonedObj;\r\n }\r\n return obj;\r\n}\r\n\r\n/**\r\n * 判断对象是否为空\r\n * @param obj - 要判断的对象\r\n * @returns 是否为空对象\r\n * @example\r\n * isEmptyObject({}) // true\r\n * isEmptyObject({ a: 1 }) // false\r\n */\r\nexport function isEmptyObject(obj: object): boolean {\r\n return Object.keys(obj).length === 0;\r\n}\r\n\r\n/**\r\n * 对象属性名转换(根据映射表重命名属性)\r\n * @param {Record<string, any>} obj - 源对象\r\n * @param {Record<string, string>} mapping - 属性名映射表\r\n * @returns {Record<string, any>} 返回转换后的对象\r\n * @example\r\n * objectKeyMapping({a: 1, b: 2}, {a: 'x'}) // {x: 1, b: 2}\r\n */\r\nexport const objectKeyMapping = (obj: Record<string, any>, mapping: Record<string, string>): Record<string, any> => {\r\n let ret: Record<string, any> = {};\r\n for (let key in obj) {\r\n if (mapping[key] !== undefined) {\r\n ret[mapping[key]] = obj[key];\r\n } else {\r\n ret[key] = obj[key];\r\n }\r\n }\r\n return ret;\r\n};\r\n\r\n/**\r\n * 获取对象指定路径的值\r\n * @param obj - 对象\r\n * @param path - 路径,例如 'a.b.c'\r\n * @param defaultValue - 默认值\r\n * @returns 获取到的值或默认值\r\n * @example\r\n * get({ a: { b: { c: 1 } } }, 'a.b.c') // 1\r\n * get({ a: { b: 1 } }, 'a.b.c', 0) // 0\r\n */\r\nexport function objectGet<T = any>(obj: any, path: string, defaultValue?: T): T {\r\n const keys = path.split(\".\");\r\n let result = obj;\r\n\r\n for (const key of keys) {\r\n if (result === null || result === undefined) {\r\n return defaultValue as T;\r\n }\r\n result = result[key];\r\n }\r\n\r\n return result !== undefined ? result : (defaultValue as T);\r\n}\r\n\r\n/**\r\n * 设置对象指定路径的值\r\n * @param obj - 对象\r\n * @param path - 路径,例如 'a.b.c'\r\n * @param value - 要设置的值\r\n * @example\r\n * set({}, 'a.b.c', 1) // { a: { b: { c: 1 } } }\r\n */\r\nexport function objectSet(obj: any, path: string, value: any): void {\r\n const keys = path.split(\".\");\r\n const lastKey = keys.pop()!;\r\n let current = obj;\r\n\r\n for (const key of keys) {\r\n if (!(key in current) || typeof current[key] !== \"object\") {\r\n current[key] = {};\r\n }\r\n current = current[key];\r\n }\r\n\r\n current[lastKey] = value;\r\n}\r\n\r\n/**\r\n * 合并对象\r\n * @param target - 目标对象\r\n * @param sources - 源对象\r\n * @returns 合并后的对象\r\n * @example\r\n * merge({ a: 1 }, { b: 2 }, { c: 3 }) // { a: 1, b: 2, c: 3 }\r\n */\r\nexport function objectMerge<T extends object>(target: T, ...sources: Partial<T>[]): T {\r\n for (const source of sources) {\r\n for (const key in source) {\r\n if (source.hasOwnProperty(key)) {\r\n const sourceValue = source[key];\r\n const targetValue = (target as any)[key];\r\n\r\n if (\r\n sourceValue &&\r\n typeof sourceValue === \"object\" &&\r\n !Array.isArray(sourceValue) &&\r\n targetValue &&\r\n typeof targetValue === \"object\" &&\r\n !Array.isArray(targetValue)\r\n ) {\r\n (target as any)[key] = objectMerge(targetValue, sourceValue);\r\n } else {\r\n (target as any)[key] = sourceValue;\r\n }\r\n }\r\n }\r\n }\r\n return target;\r\n}\r\n\r\n/**\r\n * 清理对象中的 null 值\r\n * @param {any} obj - 要清理的对象\r\n * @param {boolean} [recursive=false] - 是否递归清理子对象\r\n * @returns {any} 返回清理后的对象\r\n * @example\r\n * cleanNull({a: 1, b: null, c: {d: null}}, true) // {a: 1, c: {}}\r\n */\r\nexport const cleanNull = (obj: any, recursive = false) => {\r\n for (const key in obj) {\r\n if (obj[key] === null) {\r\n delete obj[key];\r\n } else if (recursive && typeof obj[key] === \"object\") {\r\n cleanNull(obj[key], true);\r\n }\r\n }\r\n return obj;\r\n};\r\n","export const YEAR_NOW = new Date().getFullYear();\r\nexport const MONTH_NOW = new Date().getMonth() + 1;\r\nexport const DATE_NOW = new Date().getDate();\r\n\r\nexport const ONE_MINUTE = 60 * 1000;\r\nexport const ONE_HOUR = 60 * 60 * 1000;\r\nexport const ONE_DAY = 24 * 60 * 60 * 1000;\r\nexport const ONE_WEEK = 7 * ONE_DAY;\r\nexport const ONE_MONTH30 = 30 * ONE_DAY;\r\nexport const ONE_MONTH31 = 31 * ONE_DAY;\r\nexport const ONE_YEAR365 = 365 * ONE_DAY;\r\nexport const ONE_YEAR366 = 366 * ONE_DAY;\r\n\r\nexport const DAY_SUNDAY = 0;\r\nexport const DAY_MONDAY = 1;\r\nexport const DAY_TUESDAY = 2;\r\nexport const DAY_WEDNESDAY = 3;\r\nexport const DAY_THURSDAY = 4;\r\nexport const DAY_FRIDAY = 5;\r\nexport const DAY_SATURDAY = 6;\r\n\r\n// 星期和月份的常量定义\r\nconst WEEK_DAY_NAMES_EN = [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"];\r\nconst WEEK_DAY_NAMES_SHORT_EN = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\r\n\r\nconst MONTH_NAMES_EN = [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"];\r\nconst MONTH_NAMES_SHORT_EN = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"];\r\n\r\nexport const MONTH_NAMES_CN = [\"一月\", \"二月\", \"三月\", \"四月\", \"五月\", \"六月\", \"七月\", \"八月\", \"九月\", \"十月\", \"十一月\", \"十二月\"];\r\nexport const MONTH_NAMES_SHORT_CN = [\"1月\", \"2月\", \"3月\", \"4月\", \"5月\", \"6月\", \"7月\", \"8月\", \"9月\", \"10月\", \"11月\", \"12月\"];\r\n\r\nexport const WEEK_DAY_NAMES_SHORT_CN = [\"日\", \"一\", \"二\", \"三\", \"四\", \"五\", \"六\"];\r\nexport const WEEK_DAY_NAMES_CN = [\"星期日\", \"星期一\", \"星期二\", \"星期三\", \"星期四\", \"星期五\", \"星期六\"];\r\n\r\n/**\r\n * 倒计时函数(该方法采用 setTimeout 方式,不够精准)\r\n * @param {number} timeout - 倒计时总秒数\r\n * @param {Function} [tickFunc] - 每秒回调函数,接收剩余秒数作为参数\r\n * @param {Function} [onFinish] - 倒计时结束回调函数\r\n * @returns {void}\r\n * @example\r\n * countDown(10, (sec) => console.log(sec), () => console.log('done'))\r\n */\r\nexport const countDown = (timeout: number, tickFunc?: (timeout: number) => void, onFinish?: () => void) => {\r\n let loop = () => {\r\n tickFunc && tickFunc(timeout);\r\n if (timeout-- > 0) {\r\n setTimeout(loop, 1000);\r\n return;\r\n }\r\n onFinish && onFinish();\r\n };\r\n loop();\r\n};\r\n\r\n/**\r\n * 毫秒转换为“时分秒前”格式\r\n * @param {number} ms - 毫秒数\r\n * @returns {string} 返回格式化后的字符串\r\n * @example\r\n * msToHMS(3661000) // '1小时0分钟1秒前'\r\n */\r\nexport const msToHMS = (ms: number) => {\r\n if (!ms || ms < 10) {\r\n return \"刚刚\";\r\n }\r\n ms = Math.floor(ms / 1000); // 转为秒\r\n const h = Math.floor(ms / 3600);\r\n const m = Math.floor((ms % 3600) / 60);\r\n const s = ms % 60;\r\n let str = \"\";\r\n if (h > 0) str += h + \"小时\";\r\n if (m > 0 || h > 0) str += m + \"分钟\";\r\n str += s + \"秒前\";\r\n return str;\r\n};\r\n\r\n/**\r\n * PHP 时间函数映射\r\n * 具体含义可以参考:http://php.net/manual/en/function.date.php\r\n * 或者 php.date.en.md\r\n */\r\nconst PHP_DATE_CHAR_MAP: Record<string, (dateObj: Date) => string | number | boolean> = {\r\n d: (dateObj: Date) => {\r\n let d = dateObj.getDate();\r\n return (d < 10 ? \"0\" : \"\") + d;\r\n },\r\n D: (dateObj: Date) => {\r\n return WEEK_DAY_NAMES_SHORT_EN[dateObj.getDay()];\r\n },\r\n j: (dateObj: Date) => {\r\n return dateObj.getDate();\r\n },\r\n l: (dateObj: Date) => {\r\n return WEEK_DAY_NAMES_EN[dateObj.getDay()];\r\n },\r\n N: (dateObj: Date) => {\r\n let N = dateObj.getDay();\r\n return N === 0 ? 7 : N;\r\n },\r\n S: (dateObj: Date) => {\r\n let S = dateObj.getDate();\r\n return S % 10 === 1 && S !== 11 ? \"st\" : S % 10 === 2 && S !== 12 ? \"nd\" : S % 10 === 3 && S !== 13 ? \"rd\" : \"th\";\r\n },\r\n w: (dateObj: Date) => {\r\n return dateObj.getDay();\r\n },\r\n z: (dateObj: Date) => {\r\n let d = new Date(dateObj.getFullYear(), 0, 1);\r\n return Math.ceil((dateObj.getTime() - d.getTime()) / 86400000);\r\n },\r\n // Week\r\n W: (dateObj: Date) => {\r\n let target = new Date(dateObj.valueOf());\r\n let dayNr = (dateObj.getDay() + 6) % 7;\r\n target.setDate(target.getDate() - dayNr + 3);\r\n let firstThursday = target.valueOf();\r\n target.setMonth(0, 1);\r\n if (target.getDay() !== 4) {\r\n target.setMonth(0, 1 + ((4 - target.getDay() + 7) % 7));\r\n }\r\n let retVal = 1 + Math.ceil((firstThursday - target.getTime()) / 604800000);\r\n\r\n return retVal < 10 ? \"0\" + retVal : retVal;\r\n },\r\n // Month\r\n F: (dateObj: Date) => {\r\n return MONTH_NAMES_EN[dateObj.getMonth()];\r\n },\r\n m: (dateObj: Date) => {\r\n let m = dateObj.getMonth();\r\n return (m < 9 ? \"0\" : \"\") + (m + 1);\r\n },\r\n M: (dateObj: Date) => {\r\n return MONTH_NAMES_SHORT_EN[dateObj.getMonth()];\r\n },\r\n n: (dateObj: Date) => {\r\n return dateObj.getMonth() + 1;\r\n },\r\n t: (dateObj: Date) => {\r\n let year = dateObj.getFullYear();\r\n let nextMonth = dateObj.getMonth() + 1;\r\n if (nextMonth === 12) {\r\n year = year++;\r\n nextMonth = 0;\r\n }\r\n return new Date(year, nextMonth, 0).getDate();\r\n },\r\n // Year\r\n L: (dateObj: Date) => {\r\n let L = dateObj.getFullYear();\r\n return L % 400 === 0 || (L % 100 !== 0 && L % 4 === 0);\r\n },\r\n o: (dateObj: Date) => {\r\n let d = new Date(dateObj.valueOf());\r\n d.setDate(d.getDate() - ((dateObj.getDay() + 6) % 7) + 3);\r\n return d.getFullYear();\r\n },\r\n Y: (dateObj: Date) => {\r\n return dateObj.getFullYear();\r\n },\r\n y: (dateObj: Date) => {\r\n return (\"\" + dateObj.getFullYear()).substr(2);\r\n },\r\n // Time\r\n a: (dateObj: Date) => {\r\n return dateObj.getHours() < 12 ? \"am\" : \"pm\";\r\n },\r\n A: (dateObj: Date) => {\r\n return dateObj.getHours() < 12 ? \"AM\" : \"PM\";\r\n },\r\n B: (dateObj: Date) => {\r\n return Math.floor(((((dateObj.getUTCHours() + 1) % 24) + dateObj.getUTCMinutes() / 60 + dateObj.getUTCSeconds() / 3600) * 1000) / 24);\r\n },\r\n g: (dateObj: Date) => {\r\n return dateObj.getHours() % 12 || 12;\r\n },\r\n G: (dateObj: Date) => {\r\n return dateObj.getHours();\r\n },\r\n h: (dateObj: Date) => {\r\n let h = dateObj.getHours();\r\n return ((h % 12 || 12) < 10 ? \"0\" : \"\") + (h % 12 || 12);\r\n },\r\n H: (dateObj: Date) => {\r\n let H = dateObj.getHours();\r\n return (H < 10 ? \"0\" : \"\") + H;\r\n },\r\n i: (dateObj: Date) => {\r\n let i = dateObj.getMinutes();\r\n return (i < 10 ? \"0\" : \"\") + i;\r\n },\r\n s: (dateObj: Date) => {\r\n let s = dateObj.getSeconds();\r\n return (s < 10 ? \"0\" : \"\") + s;\r\n },\r\n v: (dateObj: Date) => {\r\n let v = dateObj.getMilliseconds();\r\n return (v < 10 ? \"00\" : v < 100 ? \"0\" : \"\") + v;\r\n },\r\n // Timezone\r\n e: (_dateObj: Date) => {\r\n return Intl.DateTimeFormat().resolvedOptions().timeZone;\r\n },\r\n I: (dateObj: Date) => {\r\n let DST = null;\r\n for (let i = 0; i < 12; ++i) {\r\n let d = new Date(dateObj.getFullYear(), i, 1);\r\n let offset = d.getTimezoneOffset();\r\n\r\n if (DST === null) DST = offset;\r\n else if (offset < DST) {\r\n DST = offset;\r\n break;\r\n } else if (offset > DST) break;\r\n }\r\n return dateObj.getTimezoneOffset() === DST ? 1 : 0;\r\n },\r\n O: (dateObj: Date) => {\r\n let O = dateObj.getTimezoneOffset();\r\n return (\r\n (-O < 0 ? \"-\" : \"+\") +\r\n (Math.abs(O / 60) < 10 ? \"0\" : \"\") +\r\n Math.floor(Math.abs(O / 60)) +\r\n (Math.abs(O % 60) === 0 ? \"00\" : (Math.abs(O % 60) < 10 ? \"0\" : \"\") + Math.abs(O % 60))\r\n );\r\n },\r\n P: (dateObj: Date) => {\r\n let P = dateObj.getTimezoneOffset();\r\n return (\r\n (-P < 0 ? \"-\" : \"+\") +\r\n (Math.abs(P / 60) < 10 ? \"0\" : \"\") +\r\n Math.floor(Math.abs(P / 60)) +\r\n \":\" +\r\n (Math.abs(P % 60) === 0 ? \"00\" : (Math.abs(P % 60) < 10 ? \"0\" : \"\") + Math.abs(P % 60))\r\n );\r\n },\r\n T: (dateObj: Date) => {\r\n let tz = dateObj.toLocaleTimeString(navigator.language, { timeZoneName: \"short\" }).split(\" \");\r\n return tz[tz.length - 1];\r\n },\r\n Z: (dateObj: Date) => {\r\n return -dateObj.getTimezoneOffset() * 60;\r\n },\r\n // Full Date/Time\r\n c: (dateObj: Date) => {\r\n return formatDate(\"Y-m-d\\\\TH:i:sP\", dateObj);\r\n },\r\n r: (dateObj: Date) => {\r\n return dateObj.toString();\r\n },\r\n U: (dateObj: Date) => {\r\n return Math.floor(dateObj.getTime() / 1000);\r\n },\r\n};\r\n\r\n/**\r\n * 格式化日期(以 PHP 方式格式化)\r\n * @param {string} format - 格式化字符串(支持 PHP date 函数的格式)\r\n * @param {Date|number|string|null} [date=null] - 日期,可以是日期对象、毫秒数或者日期字符串,缺省为今天\r\n * @returns {string} 返回格式化后的日期字符串\r\n * @example\r\n * formatDate('Y-m-d H:i:s') // '2024-03-11 15:30:00'\r\n */\r\nexport const formatDate = function (format: string, date: Date | number | string | null = null): string {\r\n let dateObj = null;\r\n if (typeof date === \"object\" && date !== null) {\r\n dateObj = date;\r\n } else {\r\n dateObj = new Date(date || Date.now());\r\n }\r\n return format.replace(/(\\\\?)(.)/g, function (_: string, esc: string, chr: string): string {\r\n return esc === \"\" && PHP_DATE_CHAR_MAP[chr] ? String(PHP_DATE_CHAR_MAP[chr](dateObj)) : chr;\r\n });\r\n};\r\n\r\n/**\r\n * 获取日期所在周数(ISO 8601 标准)\r\n * @param {Date} date - 日期对象\r\n * @returns {number} 返回周数\r\n * @example\r\n * getWeekNumber(new Date('2024-03-11')) // 11\r\n */\r\nexport const getWeekNumber = (date: Date): number => {\r\n return formatDate(\"W\", date) as unknown as number;\r\n}"],"names":["arrayColumn","arr","col_name","data","i","arrayIndex","val","arrayDistinct","tmpMap","item","arrayGroup","by_key","limit","tmp_rst","k","rst","arraySortByKey","obj","result","key","arrayChunk","list","size","len","res","integer","rest","arrayTrimTail","lastNonZeroIndex","capitalize","str","stripSlashes","_s","n1","cutString","eclipse_text","r","m","extract","es_template","params","names","values","camelCase","_","char","kebabCase","truncate","length","suffix","regQuote","utf8Decode","srcStr","t","c2","c3","utf8Encode","getUTF8StrLen","realLength","charCode","DEFAULT_RANDOM_STRING","randomString","sourceStr","codes","rnd","randomWords","count","letterMax","words","possible","possibleVowels","word","strToPascalCase","capitalize_first","idx","TRIM_BOTH","TRIM_LEFT","TRIM_RIGHT","trim","chars","dir","regLeft","regRight","strChunk","ret","BASE64_KEY_STR","base64Decode","text","s","o","u","a","f","base64UrlSafeEncode","Base64Encode","blobToBase64","blob","_blobToBase64","resolve","reject","reader","error","enterFullScreen","element","exitFullScreen","toggleFullScreen","isInFullScreen","detectLanguage","supportedLngs","browserLang","langPrefix","match","lng","isFirefox","setCookie","name","value","days","path","expires","date","getCookie","nameEQ","ca","c","deleteCookie","_guid","guid","prefix","throttle","fn","intervalMiSec","context","args","previous","now","throttleEffect","lastExecuteTime","queuing","remaining","debounce","timeout","isPromise","isJson","json","is_json","isObject","isFunction","isUrl","isJSON","printStack","stack","GOLDEN_RATIO","STAND_DPI","mmToPx","dimension","dpi","mmToTwip","mm","mmToPt","ptToMm","pt","pxToMm","px","num","min","max","between","includeEqual","randomInt","round","precision","multiple","detectedPrecision","numbers","maxPrecision","decimalPart","digitCount","n","hide","dom","findOne","show","remove","el","_el_disabled_class_","disabled","disabledClass","toggleDisabled","enabled","forceEnabled","toDisabled","insertStyleSheet","onHover","onHoverIn","onHoverOut","isHovering","lockElementInteraction","payload","nodeIndex","node","findAll","selector","parent","ns","sel","getNodeXPath","allNodes","seg_list","uniqueIdCount","sib","onDomTreeChange","callback","includeElementChanged","PRO_KEY","watchEl","mutationEffective","option","minInterval","last_queue_time","callback_queueing","obs","keepRectInContainer","objDim","ctnDim","rectAssoc","rect1","rect2","isFocusable","_c","loadCss","file","forceReload","link","loadScript","src","script","getDomDimension","org_visibility","org_display","width","height","styleSheetStr","id","doc","style","rectInLayout","rect","layout","precisionToStep","fixBaseUrl","url","baseUrl","createDomByHtml","html","parentNode","tpl","nodes","getBoundingClientRect","autoFixInvisible","originalVisibility","originalDisplay","overlayRect","buildStyleVars","vars","styles","v","sanitizeFileName","blobToDataUri","e","FILE_B64_CACHE_DATA","urlB64DataCache","b64Data","fileToBase64DataUri","resp","err","downloadFile","uri","fileName","BLOCK_TAGS","PAIR_TAGS","SELF_CLOSING_TAGS","REMOVABLE_TAGS","html2Text","tag","_ms","_tail","_tag","matchReg","replacement","dec","cssSelectorEscape","entityToString","entity","entities","_helper_div","decodeHTMLEntities","buildHtmlHidden","maps","escapeAttr","escapeHtml","tabSize","allowLineBreaker","unescapeHtml","preserveCR","stringToEntity","radix","highlightText","kw","replaceTpl","imgToBase64","img","canvas","ctx","srcToBase64","cache","cached","xhr","base64","safeAdd","x","y","lsw","bitRotateLeft","cnt","md5cmn","q","b","md5ff","d","md5gg","md5hh","md5ii","binlMD5","olda","oldb","oldc","oldd","binl2rstr","input","output","length32","rstr2binl","length8","rstrMD5","rstrHMACMD5","bkey","ipad","opad","hash","rstr2hex","hexTab","str2rstrUTF8","rawMD5","hexMD5","rawHMACMD5","hexHMACMD5","md5","string","raw","MIME_BINARY_DEFAULT","MIME_JSON","MIME_FORM","MIME_MULTIPART","MIME_TEXT","MIME_HTML","MIME_EXTENSION_MAP","queryToObj","query","pair","queryReplace","newQuery","queryString","mergedQuery","newQueryString","objToQuery","param","abortableFetch","fetchOption","controller","timeoutId","clearTimer","addAbortMethod","promise","abortablePromise","originalThen","originalCatch","originalFinally","onfulfilled","onrejected","onfinally","reason","fetchPromise","appendHeader","headers","headerName","isRequestInitProp","request","IS_GET","fixData","response","isBodyInit","contentType","getJson","postJson","postFiles","fileMap","formData","deepClone","clonedObj","isEmptyObject","objectKeyMapping","mapping","objectGet","defaultValue","keys","objectSet","lastKey","current","objectMerge","target","sources","source","sourceValue","targetValue","cleanNull","recursive","YEAR_NOW","MONTH_NOW","DATE_NOW","ONE_MINUTE","ONE_HOUR","ONE_DAY","ONE_WEEK","ONE_MONTH30","ONE_MONTH31","ONE_YEAR365","ONE_YEAR366","DAY_SUNDAY","DAY_MONDAY","DAY_TUESDAY","DAY_WEDNESDAY","DAY_THURSDAY","DAY_FRIDAY","DAY_SATURDAY","WEEK_DAY_NAMES_EN","WEEK_DAY_NAMES_SHORT_EN","MONTH_NAMES_EN","MONTH_NAMES_SHORT_EN","MONTH_NAMES_CN","MONTH_NAMES_SHORT_CN","WEEK_DAY_NAMES_SHORT_CN","WEEK_DAY_NAMES_CN","countDown","tickFunc","onFinish","loop","msToHMS","ms","h","PHP_DATE_CHAR_MAP","dateObj","N","S","dayNr","firstThursday","retVal","year","nextMonth","L","H","_dateObj","DST","offset","O","P","tz","formatDate","format","esc","chr","getWeekNumber"],"mappings":"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"}
1
+ {"version":3,"file":"minutool.js","sources":["../src/array.ts","../src/string.ts","../src/base64.ts","../src/browser.ts","../src/cookie.ts","../src/util.ts","../src/math.ts","../src/dom.ts","../src/file.ts","../src/html.ts","../src/img.ts","../src/md5.ts","../src/mime.ts","../src/net.ts","../src/object.ts","../src/time.ts"],"sourcesContent":["/**\r\n * 从数组中提取指定列的值\r\n * @param {T[]} arr - 源数组\r\n * @param {keyof T} col_name - 列名(对象的键)\r\n * @returns {any[]} 提取的列值数组\r\n * @example\r\n * arrayColumn([{id: 1, name: 'A'}, {id: 2, name: 'B'}], 'name') // ['A', 'B']\r\n */\r\nexport const arrayColumn = <T = any>(arr: T[], col_name: keyof T): any[] => {\r\n\tlet data: any[] = [];\r\n\tfor(let i in arr){\r\n\t\tdata.push(arr[i][col_name]);\r\n\t}\r\n\treturn data;\r\n};\r\n\r\n/**\r\n * 查找数组中指定值的索引\r\n * @param {T[]} arr - 源数组\r\n * @param {T} val - 要查找的值\r\n * @returns {string|null} 返回索引字符串,未找到返回 null\r\n * @example\r\n * arrayIndex(['a', 'b', 'c'], 'b') // '1'\r\n */\r\nexport const arrayIndex = <T = any>(arr: T[], val: T): string | null => {\r\n\tfor(let i in arr){\r\n\t\tif(arr[i] === val){\r\n\t\t\treturn i;\r\n\t\t}\r\n\t}\r\n\treturn null;\r\n};\r\n\r\n\r\n/**\r\n * 数组去重\r\n * @param {T[]} arr - 源数组\r\n * @returns {T[]} 去重后的数组\r\n * @example\r\n * arrayDistinct([1, 2, 2, 3, 3, 3]) // [1, 2, 3]\r\n */\r\nexport const arrayDistinct = <T = any>(arr: T[]): T[] => {\r\n\tlet tmpMap = new Map();\r\n\treturn arr.filter((item: T) => {\r\n\t\tif(!tmpMap.has(item)){\r\n\t\t\ttmpMap.set(item, true);\r\n\t\t\treturn true;\r\n\t\t}\r\n\t});\r\n}\r\n\r\n\r\n/**\r\n * 按指定键对数组进行分组\r\n * @param {T[]} arr - 源数组\r\n * @param {keyof T} by_key - 分组依据的键\r\n * @param {boolean} [limit] - 是否限制每组只保留一个元素\r\n * @returns {Record<string, T[]> | Record<string, T>} 分组后的对象\r\n * @example\r\n * arrayGroup([{type: 'A', val: 1}, {type: 'A', val: 2}], 'type')\r\n * // { A: [{type: 'A', val: 1}, {type: 'A', val: 2}] }\r\n */\r\nexport const arrayGroup = <T extends Record<string, any>>(arr: T[], by_key: keyof T, limit?: boolean): Record<string, T[]> | Record<string, T> => {\r\n\tif(!arr || !arr.length){\r\n\t\treturn arr as any;\r\n\t}\r\n\tlet tmp_rst: Record<string, T[]> = {};\r\n\tarr.forEach((item: T) => {\r\n\t\tlet k = item[by_key];\r\n\t\tif(!tmp_rst[k]){\r\n\t\t\ttmp_rst[k] = [];\r\n\t\t}\r\n\t\ttmp_rst[k].push(item);\r\n\t});\r\n\tif(!limit){\r\n\t\treturn tmp_rst;\r\n\t}\r\n\tlet rst: Record<string, T> = {};\r\n\tfor(let i in tmp_rst){\r\n\t\trst[i] = tmp_rst[i][0];\r\n\t}\r\n\treturn rst;\r\n};\r\n\r\n\r\n/**\r\n * 按照对象的键进行字母顺序排序\r\n * @param {T} obj - 源对象\r\n * @returns {T} 键排序后的对象\r\n * @example\r\n * arraySortByKey({c: 3, a: 1, b: 2}) // {a: 1, b: 2, c: 3}\r\n */\r\nexport const arraySortByKey = <T extends Record<string, any>>(obj: T): T => {\r\n\treturn Object.keys(obj).sort().reduce(function(result: Record<string, any>, key: string){\r\n\t\tresult[key] = obj[key];\r\n\t\treturn result;\r\n\t}, {} as Record<string, any>) as T;\r\n}\r\n\r\n\r\n/**\r\n * 将数组分割成指定大小的块\r\n * @param {T[]} list - 源数组\r\n * @param {number} size - 每块的大小\r\n * @returns {T[][]} 分块后的二维数组\r\n * @example\r\n * arrayChunk([1, 2, 3, 4, 5], 2) // [[1, 2], [3, 4], [5]]\r\n */\r\nexport const arrayChunk = <T = any>(list: T[], size: number): T[][] => {\r\n\tlet len = list.length;\r\n\tif(size < 1 || !len){\r\n\t\treturn [];\r\n\t}\r\n\tif(size > len){\r\n\t\treturn [list];\r\n\t}\r\n\tlet res = [];\r\n\tlet integer = Math.floor(len / size);\r\n\tlet rest = len % size;\r\n\tfor(let i = 1; i <= integer; i++){\r\n\t\tres.push(list.splice(0, size));\r\n\t}\r\n\tif(rest){\r\n\t\tres.push(list.splice(0, rest));\r\n\t}\r\n\treturn res;\r\n}\r\n\r\n/**\r\n * 从数组末尾开始移除值为 falsy 的元素,直到遇到第一个 truthy 元素\r\n * @param {any[]} arr - 要处理的数组\r\n * @returns {any[]} 处理后的数组\r\n * @example\r\n * arrayTrimTail([1, 2, 0, false, null]) // [1, 2]\r\n */\r\nexport const arrayTrimTail = (arr: any[]) => {\r\n let lastNonZeroIndex = -1;\r\n for (let i = arr.length - 1; i >= 0; i--) {\r\n if (arr[i]) {\r\n lastNonZeroIndex = i;\r\n break;\r\n }\r\n }\r\n return arr.slice(0, lastNonZeroIndex + 1);\r\n};\r\n","/**\r\n * 首字母大写\r\n * @param str - 输入字符串\r\n * @returns 首字母大写的字符串\r\n * @example\r\n * capitalize('hello') // 'Hello'\r\n */\r\nexport function capitalize(str: string): string {\r\n if (!str) return str;\r\n return str.charAt(0).toUpperCase() + str.slice(1);\r\n}\r\n\r\n/**\r\n * 反转义字符串\r\n * @param str\r\n * @returns {string}\r\n * @description:\r\n * discuss at: https://locutus.io/php/stripslashes/\r\n * original by: Kevin van Zonneveld (https://kvz.io)\r\n * improved by: Ates Goral (https://magnetiq.com)\r\n * improved by: marrtins\r\n * improved by: rezna\r\n * fixed by: Mick@el\r\n * bugfixed by: Onno Marsman (https://twitter.com/onnomarsman)\r\n * bugfixed by: Brett Zamir (https://brett-zamir.me)\r\n * input by: Rick Waldron\r\n * input by: Brant Messenger (https://www.brantmessenger.com/)\r\n * reimplemented by: Brett Zamir (https://brett-zamir.me)\r\n * example 1: stripslashes('Kevin\\'s code')\r\n * returns 1: \"Kevin's code\"\r\n * example 2: stripslashes('Kevin\\\\\\'s code')\r\n * returns 2: \"Kevin\\'s code\"\r\n */\r\nexport const stripSlashes = (str: string): string => {\r\n return (str + \"\").replace(/\\\\(.?)/g, function (_s: string, n1: string) {\r\n switch (n1) {\r\n case \"\\\\\":\r\n return \"\\\\\";\r\n case \"0\":\r\n return \"\\u0000\";\r\n case \"\":\r\n return \"\";\r\n default:\r\n return n1;\r\n }\r\n });\r\n};\r\n\r\n/**\r\n * 中英文字符串截取(中文按照 2 个字符长度计算)\r\n * @param {string} str - 要截取的字符串\r\n * @param {number} len - 截取长度\r\n * @param {string} [eclipse_text='...'] - 省略符,默认为 '...'\r\n * @returns {string} 返回截取后的字符串\r\n * @example\r\n * cutString('中文English', 6, '...') // '中文E...'\r\n */\r\nexport const cutString = (str: string, len: number, eclipse_text: string = \"...\"): string => {\r\n let r = /[^\\x00-\\xff]/g;\r\n if (str.replace(r, \"mm\").length <= len) {\r\n return str;\r\n }\r\n let m = Math.floor(len / 2);\r\n for (let i = m; i < str.length; i++) {\r\n if (str.substr(0, i).replace(r, \"mm\").length >= len) {\r\n return str.substr(0, i) + eclipse_text;\r\n }\r\n }\r\n return str;\r\n};\r\n\r\n/**\r\n * 混合ES6模板字符串\r\n * @example extract(\"hello ${user_name}\", {user_name:\"Jack\"});\r\n * @param {String} es_template 模板\r\n * @param {Object} params 数据对象\r\n * @return {String}\r\n */\r\nexport const extract = (es_template: string, params: Record<string, any>): string => {\r\n const names = Object.keys(params);\r\n const values = Object.values(params);\r\n return new Function(...names, `return \\`${es_template}\\`;`)(...values);\r\n};\r\n\r\n/**\r\n * 驼峰命名转换\r\n * @param str - 输入字符串\r\n * @returns 驼峰命名的字符串\r\n * @example\r\n * camelCase('hello-world') // 'helloWorld'\r\n * camelCase('hello_world') // 'helloWorld'\r\n */\r\nexport function camelCase(str: string): string {\r\n return str.replace(/[-_](.)/g, (_, char) => char.toUpperCase());\r\n}\r\n\r\n/**\r\n * 短横线命名转换\r\n * @param str - 输入字符串\r\n * @returns 短横线命名的字符串\r\n * @example\r\n * kebabCase('helloWorld') // 'hello-world'\r\n * kebabCase('HelloWorld') // 'hello-world'\r\n */\r\nexport function kebabCase(str: string): string {\r\n return str\r\n .replace(/([a-z])([A-Z])/g, \"$1-$2\")\r\n .replace(/[\\s_]+/g, \"-\")\r\n .toLowerCase();\r\n}\r\n\r\n/**\r\n * 截断字符串\r\n * @param str - 输入字符串\r\n * @param length - 最大长度\r\n * @param suffix - 后缀,默认为 '...'\r\n * @returns 截断后的字符串\r\n * @example\r\n * truncate('hello world', 5) // 'hello...'\r\n */\r\nexport function truncate(str: string, length: number, suffix: string = \"...\"): string {\r\n if (str.length <= length) return str;\r\n return str.slice(0, length) + suffix;\r\n}\r\n\r\n/**\r\n * 正则表达式转义(将特殊字符转义)\r\n * @param {string} str - 要转义的字符串\r\n * @returns {string} 返回转义后的字符串\r\n * @example\r\n * regQuote('a.b') // 'a\\\\.b'\r\n */\r\nexport const regQuote = (str: string): string => {\r\n return (str + \"\").replace(/([\\\\\\.\\+\\*\\?\\[\\^\\]\\$\\(\\)\\{\\}\\=\\!\\<\\>\\|\\:])/g, \"\\\\$1\");\r\n};\r\n\r\n/**\r\n * UTF-8 解码\r\n * @param {string} srcStr - 要解码的字符串\r\n * @returns {string} 返回解码后的字符串\r\n * @example\r\n * utf8Decode(encodedStr) // 'decoded string'\r\n */\r\nexport const utf8Decode = (srcStr: string): string => {\r\n let t = \"\";\r\n let n = 0;\r\n let r = 0,\r\n c2 = 0,\r\n c3 = 0;\r\n while (n < srcStr.length) {\r\n r = srcStr.charCodeAt(n);\r\n if (r < 128) {\r\n t += String.fromCharCode(r);\r\n n++;\r\n } else if (r > 191 && r < 224) {\r\n c2 = srcStr.charCodeAt(n + 1);\r\n t += String.fromCharCode(((r & 31) << 6) | (c2 & 63));\r\n n += 2;\r\n } else {\r\n c2 = srcStr.charCodeAt(n + 1);\r\n c3 = srcStr.charCodeAt(n + 2);\r\n t += String.fromCharCode(((r & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));\r\n n += 3;\r\n }\r\n }\r\n return t;\r\n};\r\n\r\n/**\r\n * UTF-8 编码\r\n * @param {string} srcStr - 要编码的字符串\r\n * @returns {string} 返回编码后的字符串\r\n * @example\r\n * utf8Encode('string') // 'encoded string'\r\n */\r\nexport const utf8Encode = (srcStr: string): string => {\r\n srcStr = srcStr.replace(/\\r\\n/g, \"n\");\r\n let t = \"\";\r\n for (let n = 0; n < srcStr.length; n++) {\r\n let r = srcStr.charCodeAt(n);\r\n if (r < 128) {\r\n t += String.fromCharCode(r);\r\n } else if (r > 127 && r < 2048) {\r\n t += String.fromCharCode((r >> 6) | 192);\r\n t += String.fromCharCode((r & 63) | 128);\r\n } else {\r\n t += String.fromCharCode((r >> 12) | 224);\r\n t += String.fromCharCode(((r >> 6) & 63) | 128);\r\n t += String.fromCharCode((r & 63) | 128);\r\n }\r\n }\r\n return t;\r\n};\r\n\r\n/**\r\n * 获取 UTF-8 字符串长度(一个中文字按照 3 个字数计算)\r\n * @param {string} str - 要计算的字符串\r\n * @returns {number} 返回字符串长度\r\n * @example\r\n * getUTF8StrLen('中文') // 6\r\n */\r\nexport const getUTF8StrLen = (str: string): number => {\r\n let realLength = 0;\r\n let len = str.length;\r\n let charCode = -1;\r\n for (let i = 0; i < len; i++) {\r\n charCode = str.charCodeAt(i);\r\n if (charCode >= 0 && charCode <= 128) {\r\n realLength += 1;\r\n } else {\r\n realLength += 3;\r\n }\r\n }\r\n return realLength;\r\n};\r\nconst DEFAULT_RANDOM_STRING = \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890\";\r\n\r\n/**\r\n * 产生随机字符串\r\n * @param {Number} length\r\n * @param {String} sourceStr\r\n * @returns {String}\r\n */\r\nexport const randomString = (length = 6, sourceStr = DEFAULT_RANDOM_STRING) => {\r\n let codes = \"\";\r\n for (let i = 0; i < length; i++) {\r\n let rnd = Math.round(Math.random() * (sourceStr.length - 1));\r\n codes += sourceStr.substring(rnd, rnd + 1);\r\n }\r\n return codes;\r\n};\r\n\r\n/**\r\n * 产生随机单词\r\n * @param {Number} count 单词数量\r\n * @param {Number} letterMax 每个单词最大字符数量\r\n * @return {String[]} 单词列表\r\n */\r\nexport const randomWords = (count = 1, letterMax = 8) => {\r\n let words = [];\r\n const possible = \"bcdfghjklmnpqrstvwxyz\";\r\n const possibleVowels = \"aeiou\";\r\n\r\n while (count-- > 0) {\r\n let word = \"\";\r\n for (let i = 0; i < letterMax; i = i + 3) {\r\n word += possible[Math.floor(Math.random() * possible.length)];\r\n word += possibleVowels[Math.floor(Math.random() * possibleVowels.length)];\r\n word += possible[Math.floor(Math.random() * possible.length)];\r\n }\r\n words.push(word);\r\n }\r\n return words;\r\n};\r\n/**\r\n * 字符串转成首字母大写(Pascal Case)\r\n * @param {string} str - 要转换的字符串\r\n * @param {boolean} [capitalize_first=false] - 是否将第一个单词首字母大写\r\n * @returns {string} 返回转换后的字符串\r\n * @example\r\n * strToPascalCase('hello-world', true) // 'HelloWorld'\r\n */\r\nexport const strToPascalCase = (str: string, capitalize_first: boolean = false): string => {\r\n let words: string[] = [];\r\n str.replace(/[-_\\s+]/g, \" \")\r\n .split(\" \")\r\n .forEach((word, idx) => {\r\n words.push(idx === 0 && !capitalize_first ? word : capitalize(word));\r\n });\r\n return words.join(\"\");\r\n};\r\n\r\n// trim 方向常量\r\nexport const TRIM_BOTH = 0;\r\nexport const TRIM_LEFT = 1;\r\nexport const TRIM_RIGHT = 2;\r\n\r\n/**\r\n * 去除字符串首尾指定字符或空白\r\n * @param {string} str - 源字符串\r\n * @param {string} [chars=''] - 指定字符,默认为空白\r\n * @param {number} [dir=TRIM_BOTH] - 方向(TRIM_BOTH/TRIM_LEFT/TRIM_RIGHT)\r\n * @returns {string} 返回去除后的字符串\r\n * @example\r\n * trim('__hello__', '_') // 'hello'\r\n */\r\nexport const trim = (str: string, chars: string = \"\", dir: number = TRIM_BOTH): string => {\r\n if (chars.length) {\r\n let regLeft = new RegExp(\"^[\" + regQuote(chars) + \"]+\"),\r\n regRight = new RegExp(\"[\" + regQuote(chars) + \"]+$\");\r\n return dir === TRIM_LEFT ? str.replace(regLeft, \"\") : dir === TRIM_RIGHT ? str.replace(regRight, \"\") : str.replace(regLeft, \"\").replace(regRight, \"\");\r\n } else {\r\n return dir === TRIM_BOTH ? str.trim() : dir === TRIM_LEFT ? str.trimStart() : str.trimEnd();\r\n }\r\n};\r\n\r\n/**\r\n * 将字符串分割成指定长度的数组\r\n * @param {string} str - 要分割的字符串\r\n * @param {number} size - 每段的长度\r\n * @returns {string[]} 返回分割后的数组\r\n * @example\r\n * strChunk('abcdef', 2) // ['ab', 'cd', 'ef']\r\n */\r\nexport const strChunk = (str: string, size: number): string[] => {\r\n let ret: string[] = [];\r\n for (let i = 0; i < str.length; i += size) {\r\n ret.push(str.slice(i, i + size));\r\n }\r\n return ret;\r\n};\r\n","import { utf8Decode, utf8Encode } from \"./string\";\r\n\r\nconst BASE64_KEY_STR = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\";\r\n\r\n/**\r\n * Base64 解码\r\n * @param {string} text - Base64 编码的字符串\r\n * @returns {string} 解码后的字符串\r\n * @example\r\n * base64Decode('SGVsbG8=') // 'Hello'\r\n */\r\nexport const base64Decode = (text: string): string => {\r\n let t = \"\";\r\n let n, r, i;\r\n let s, o, u, a;\r\n let f = 0;\r\n text = text.replace(/\\+\\+[++^A-Za-z0-9+/=]/g, \"\");\r\n while (f < text.length) {\r\n s = BASE64_KEY_STR.indexOf(text.charAt(f++));\r\n o = BASE64_KEY_STR.indexOf(text.charAt(f++));\r\n u = BASE64_KEY_STR.indexOf(text.charAt(f++));\r\n a = BASE64_KEY_STR.indexOf(text.charAt(f++));\r\n n = (s << 2) | (o >> 4);\r\n r = ((o & 15) << 4) | (u >> 2);\r\n i = ((u & 3) << 6) | a;\r\n t = t + String.fromCharCode(n);\r\n if (u !== 64) {\r\n t = t + String.fromCharCode(r);\r\n }\r\n if (a !== 64) {\r\n t = t + String.fromCharCode(i);\r\n }\r\n }\r\n t = utf8Decode(t);\r\n return t;\r\n};\r\n\r\n/**\r\n * URL 安全模式进行 Base64 编码(替换 + 和 / 为 - 和 _)\r\n * @param {string} text - 要编码的字符串\r\n * @returns {string} URL 安全的 Base64 编码字符串\r\n * @example\r\n * base64UrlSafeEncode('test') // URL安全的Base64字符串\r\n */\r\nexport const base64UrlSafeEncode = (text: string): string => {\r\n return utf8Encode(text).replace(\"+\", \"-\").replace(\"/\", \"_\");\r\n};\r\n\r\n/**\r\n * 字符串转 Base64 编码\r\n * @param {string} text - 要编码的字符串\r\n * @returns {string} Base64 编码后的字符串\r\n * @example\r\n * Base64Encode('Hello') // 'SGVsbG8='\r\n */\r\nexport const Base64Encode = (text: string): string => {\r\n let t = \"\";\r\n let n, r, i, s, o, u, a;\r\n let f = 0;\r\n text = utf8Encode(text);\r\n while (f < text.length) {\r\n n = text.charCodeAt(f++);\r\n r = text.charCodeAt(f++);\r\n i = text.charCodeAt(f++);\r\n s = n >> 2;\r\n o = ((n & 3) << 4) | (r >> 4);\r\n u = ((r & 15) << 2) | (i >> 6);\r\n a = i & 63;\r\n if (isNaN(r)) {\r\n u = a = 64;\r\n } else if (isNaN(i)) {\r\n a = 64;\r\n }\r\n t = t + BASE64_KEY_STR.charAt(s) + BASE64_KEY_STR.charAt(o) + BASE64_KEY_STR.charAt(u) + BASE64_KEY_STR.charAt(a);\r\n }\r\n return t;\r\n};\r\n\r\n/**\r\n * 转换 Blob 数据到 Base64 Data URL\r\n * @param {Blob} blob - Blob 对象\r\n * @returns {Promise<unknown>} 返回 Base64 Data URL 字符串的 Promise\r\n * @example\r\n * blobToBase64(blob).then(base64 => console.log(base64))\r\n */\r\nexport const blobToBase64 = async (blob: Blob): Promise<unknown> => {\r\n return await _blobToBase64(blob);\r\n};\r\n\r\n/**\r\n * 转换 Blob 数据到 Base64 Data URL(内部实现)\r\n * @param {Blob} blob - Blob 对象\r\n * @returns {Promise<unknown>} 返回 Base64 Data URL 字符串的 Promise\r\n */\r\nconst _blobToBase64 = (blob: Blob): Promise<unknown> =>\r\n new Promise((resolve, reject) => {\r\n const reader = new FileReader();\r\n reader.readAsDataURL(blob);\r\n reader.onload = () => resolve(reader.result);\r\n reader.onerror = (error) => reject(error);\r\n });\r\n","\r\n/**\r\n * 进入全屏模式\r\n * @param {HTMLElement} element - 要全屏显示的元素\r\n * @returns {Promise<void>} 返回 Promise,全屏操作完成后 resolve\r\n * @throws {string} 如果浏览器不支持全屏,抛出错误\r\n * @example\r\n * enterFullScreen(document.body)\r\n */\r\nexport const enterFullScreen = (element: any): Promise<void> => {\r\n\tif (element.requestFullscreen) {\r\n\t\treturn element.requestFullscreen();\r\n\t}\r\n\tif (element.webkitRequestFullScreen) {\r\n\t\treturn element.webkitRequestFullScreen();\r\n\t}\r\n\tif (element.mozRequestFullScreen) {\r\n\t\telement.mozRequestFullScreen();\r\n\t}\r\n\tif (element.msRequestFullScreen) {\r\n\t\telement.msRequestFullScreen();\r\n\t}\r\n\tthrow \"Browser no allow full screen\";\r\n}\r\n\r\n/**\r\n * 退出全屏模式\r\n * @returns {Promise<void>} 返回 Promise,退出全屏操作完成后 resolve\r\n * @example\r\n * exitFullScreen()\r\n */\r\nexport const exitFullScreen = () => {\r\n\treturn document.exitFullscreen();\r\n}\r\n\r\n/**\r\n * 切换全屏模式(全屏时退出,非全屏时进入)\r\n * @param {HTMLElement} element - 要全屏显示的元素\r\n * @returns {Promise<unknown>} 返回 Promise\r\n * @example\r\n * toggleFullScreen(document.body)\r\n */\r\nexport const toggleFullScreen = (element: any): Promise<unknown> => {\r\n\treturn new Promise((resolve, reject) => {\r\n\t\tif (!isInFullScreen()) {\r\n\t\t\tenterFullScreen(element).then(resolve).catch(reject);\r\n\t\t} else {\r\n\t\t\texitFullScreen().then(resolve).catch(reject);\r\n\t\t}\r\n\t})\r\n}\r\n/**\r\n * 检测是否正在全屏\r\n * @returns {boolean} 如果当前正在全屏模式,返回 true,否则返回 false\r\n * @example\r\n * isInFullScreen() // false\r\n */\r\nexport const isInFullScreen = () => {\r\n\treturn !!document.fullscreenElement;\r\n}\r\n\r\n/**\r\n * 检测浏览器语言(支持完全匹配和前缀匹配)\r\n * @param {string[]} supportedLngs - 支持的语言列表\r\n * @returns {string} 返回匹配的语言或第一个支持的语言\r\n * @example\r\n * detectLanguage(['en', 'zh-CN', 'zh']) // '根据浏览器语言返回匹配的语言'\r\n */\r\nexport const detectLanguage = (supportedLngs: string[]) => {\r\n const browserLang = navigator.language || (navigator as any).userLanguage;\r\n\r\n // 尝试完全匹配\r\n if (supportedLngs.includes(browserLang)) {\r\n return browserLang;\r\n }\r\n\r\n // 尝试匹配语言代码的前缀 (例如 zh-CN -> zh)\r\n const langPrefix = browserLang.split(\"-\")[0];\r\n const match = supportedLngs.find((lng) => lng.startsWith(langPrefix));\r\n if (match) {\r\n return match;\r\n }\r\n return supportedLngs[0];\r\n};\r\n\r\n/**\r\n * 检测是否为 Firefox 浏览器\r\n * @returns {boolean} 如果是 Firefox 浏览器,返回 true,否则返回 false\r\n * @example\r\n * isFirefox() // false\r\n */\r\nexport const isFirefox = () => {\r\n return navigator.userAgent.toLowerCase().indexOf(\"firefox\") > -1;\r\n};","\r\n/**\r\n * 设置 Cookie\r\n * @param {string} name - Cookie 名称\r\n * @param {string} value - Cookie 值\r\n * @param {number} days - 有效天数,0 表示会话 Cookie\r\n * @param {string} [path='/'] - Cookie 路径,默认为根路径\r\n * @returns {void}\r\n * @example\r\n * setCookie('username', 'john', 7)\r\n */\r\nexport const setCookie = (name: string, value: string, days: number, path: string = '/'): void => {\r\n\tlet expires = \"\";\r\n\tif(days){\r\n\t\tlet date = new Date();\r\n\t\tdate.setTime(Date.now() + (days * 24 * 60 * 60 * 1000));\r\n\t\texpires = \"; expires=\" + date.toUTCString();\r\n\t}\r\n\tdocument.cookie = name + \"=\" + (value || \"\") + expires + \"; path=\" + path;\r\n}\r\n\r\n/**\r\n * 获取 Cookie\r\n * @param {string} name - Cookie 名称\r\n * @returns {string|null} 返回 Cookie 值,未找到返回 null\r\n * @example\r\n * getCookie('username') // 'john'\r\n */\r\nexport const getCookie = (name: string): string | null => {\r\n\tlet nameEQ = name + \"=\";\r\n\tlet ca = document.cookie.split(';');\r\n\tfor(let i = 0; i < ca.length; i++){\r\n\t\tlet c = ca[i];\r\n\t\twhile(c.charAt(0) === ' ') c = c.substring(1, c.length);\r\n\t\tif(c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);\r\n\t}\r\n\treturn null;\r\n}\r\n\r\n/**\r\n * 删除 Cookie\r\n * @param {string} name - Cookie 名称\r\n * @returns {void}\r\n * @example\r\n * deleteCookie('username')\r\n */\r\nexport const deleteCookie = (name: string): void => {\r\n\tdocument.cookie = name + '=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;';\r\n}","import { randomString } from \"./string\";\r\n\r\nlet _guid = 0;\r\n/**\r\n * 生成全局唯一 ID\r\n * @param {string} [prefix=''] - ID 前缀\r\n * @returns {string} 返回唯一 ID\r\n * @example\r\n * guid('user') // 'guid_user123_1'\r\n */\r\nexport const guid = (prefix = \"\") => {\r\n return \"guid_\" + (prefix || randomString(6)) + ++_guid;\r\n};\r\n\r\n/**\r\n * 节流函数\r\n * 规定在一个单位时间内,只能触发一次函数。如果这个函数单位时间内触发多次函数,只有一次生效。\r\n * @param {Function} fn - 要节流的函数\r\n * @param {number} intervalMiSec - 间隔时间(毫秒)\r\n * @returns {Function} 返回节流后的函数\r\n * @example\r\n * const throttled = throttle(() => console.log('called'), 1000)\r\n */\r\nexport const throttle = (fn: Function, intervalMiSec: number): Function => {\r\n let context: any, args: any;\r\n let previous = 0;\r\n return function (this: any) {\r\n let now = +new Date();\r\n context = this;\r\n args = arguments;\r\n if (now - previous > intervalMiSec) {\r\n fn.apply(context, args as any);\r\n previous = now;\r\n }\r\n };\r\n};\r\n\r\n/**\r\n * 更有效果的节流函数\r\n * 区别:如果函数执行间隔还没到期,放入下一个时间周期执行,如果已经有下一周期未执行,当前触发作废。\r\n * 这种效果在 Change 类型函数场景中更有效果,可以确保最后一次变更能够有效执行\r\n * @param {Function} fn - 要节流的函数\r\n * @param {number} intervalMiSec - 间隔时间(毫秒)\r\n * @returns {Function} 返回节流后的函数\r\n * @example\r\n * const throttled = throttleEffect(() => console.log('called'), 1000)\r\n */\r\nexport const throttleEffect = (fn: Function, intervalMiSec: number): Function => {\r\n let context: any, args: any;\r\n let lastExecuteTime = 0;\r\n let queuing = false;\r\n return function (this: any) {\r\n if (queuing) {\r\n return;\r\n }\r\n let now = +new Date();\r\n context = this;\r\n args = arguments;\r\n let remaining = intervalMiSec - (now - lastExecuteTime);\r\n if (remaining <= 0) {\r\n fn.apply(context, args as any);\r\n lastExecuteTime = now;\r\n } else {\r\n queuing = true;\r\n setTimeout(() => {\r\n fn.apply(context, args as any);\r\n queuing = false;\r\n lastExecuteTime = now;\r\n }, remaining);\r\n }\r\n };\r\n};\r\n\r\n/**\r\n * 防抖函数\r\n * 在事件被触发 n 秒后再执行回调,如果在这 n 秒内又被触发,则重新计时。\r\n * @param {Function} fn - 要防抖的函数\r\n * @param {number} intervalMiSec - 间隔时间(毫秒)\r\n * @returns {Function} 返回防抖后的函数\r\n * @example\r\n * const debounced = debounce(() => console.log('called'), 1000)\r\n */\r\nexport const debounce = (fn: Function, intervalMiSec: number): Function => {\r\n let timeout: any;\r\n return function (this: any) {\r\n let context = this;\r\n let args = arguments;\r\n clearTimeout(timeout);\r\n timeout = setTimeout(function () {\r\n fn.apply(context, args);\r\n }, intervalMiSec);\r\n };\r\n};\r\n/**\r\n * 检测对象是否为 Promise 对象\r\n * @param {any} obj - 要检测的对象\r\n * @returns {boolean} 如果是 Promise 返回 true,否则返回 false\r\n * @example\r\n * isPromise(Promise.resolve()) // true\r\n */\r\nexport const isPromise = (obj: any): boolean => {\r\n return obj && typeof obj === \"object\" && obj.then && typeof obj.then === \"function\";\r\n};\r\n\r\n/**\r\n * 检测字符串是否为有效的 JSON\r\n * @param {string} json - 要检测的字符串\r\n * @returns {boolean} 如果是有效 JSON 返回 true,否则返回 false\r\n * @example\r\n * isJson('{\"name\":\"John\"}') // true\r\n */\r\nexport const isJson = (json: string): boolean => {\r\n let is_json = false;\r\n try {\r\n JSON.parse(json);\r\n is_json = true;\r\n } catch (error) {}\r\n return is_json;\r\n};\r\n\r\n/**\r\n * 检测目标是否为 Object(非数组的对象)\r\n * @param {any} item - 要检测的对象\r\n * @returns {boolean} 如果是对象返回 true,否则返回 false\r\n * @example\r\n * isObject({}) // true\r\n * isObject([]) // false\r\n */\r\nexport const isObject = (item: any): boolean => {\r\n return item && typeof item === \"object\" && !Array.isArray(item);\r\n};\r\n\r\n/**\r\n * 检测是否为函数\r\n * @param {any} value - 要检测的值\r\n * @returns {boolean} 如果是函数返回 true,否则返回 false\r\n * @example\r\n * isFunction(() => {}) // true\r\n */\r\nexport const isFunction = (value: any): boolean => {\r\n return value ? Object.prototype.toString.call(value) === \"[object Function]\" || \"function\" === typeof value || value instanceof Function : false;\r\n};\r\n\r\n/**\r\n * 检测是否为 URL(不包含 blob: data: file: 等协议)\r\n * @param {string} str - 要检测的字符串\r\n * @returns {boolean} 如果是 URL 返回 true,否则返回 false\r\n * @example\r\n * isUrl('https://example.com') // true\r\n */\r\nexport const isUrl = (str: string) => {\r\n if (typeof str !== \"string\" || str.trim() === \"\") return false;\r\n // 常见的可作为资源的 URL/路径:http(s)://, //, blob:, data:, file:, 以及以 / 或 ./ ../ 开头的相对路径\r\n return /^(https?:\\/\\/|\\/\\/|\\/|\\.\\.?\\/*)/i.test(str);\r\n};\r\n\r\n/**\r\n * 判断字符串是否符合 JSON 标准\r\n * @param {string} json - 要检测的字符串\r\n * @returns {boolean} 如果是有效 JSON 返回 true,否则返回 false\r\n * @example\r\n * isJSON('{\"name\":\"John\"}') // true\r\n */\r\nexport const isJSON = (json: string): boolean => {\r\n\tlet is_json = false;\r\n\ttry{\r\n\t\tJSON.parse(json);\r\n\t\tis_json = true;\r\n\t}catch(error){\r\n\t}\r\n\treturn is_json;\r\n}\r\n\r\n/**\r\n * 打印调用堆栈\r\n * @returns {void}\r\n * @example\r\n * printStack() // 在控制台输出堆栈信息\r\n */\r\nexport const printStack = () => {\r\n let stack = new Error().stack;\r\n console.log(stack);\r\n};","/** 黄金分割比 0.618 **/\r\nexport const GOLDEN_RATIO = (1 + Math.sqrt(5)) / 2 - 1;\r\n\r\n//标准屏幕DPI\r\nexport const STAND_DPI = 96;\r\n\r\n/**\r\n * 毫米转换成像素\r\n * @param {number} dimension - 毫米值\r\n * @param {number} [dpi=STAND_DPI] - DPI 值,默认为标准 DPI (96)\r\n * @returns {number} 返回像素值\r\n * @example\r\n * mmToPx(25.4) // 96\r\n */\r\nexport const mmToPx = (dimension: number, dpi: number = STAND_DPI): number => {\r\n let px = (dimension / 25.4) * dpi;\r\n return px;\r\n};\r\n\r\n/**\r\n * 将 mm 转换为 TWIP(Twentieth of a Point)\r\n * @param {number} mm - 毫米值\r\n * @returns {number} 返回 TWIP 值\r\n * @example\r\n * mmToTwip(1) // 57\r\n */\r\nexport const mmToTwip = (mm: number): number => Math.round(mm * 56.6929);\r\n\r\n/**\r\n * 将 mm 转换为磅(Point)\r\n * @param {number} mm - 毫米值\r\n * @returns {number} 返回磅值\r\n * @example\r\n * mmToPt(1) // 2.83\r\n */\r\nexport const mmToPt = (mm: number): number => mm * 2.83464566929;\r\n\r\n/**\r\n * 将磅(Point)转换为 mm\r\n * @param {number} pt - 磅值\r\n * @returns {number} 返回毫米值\r\n * @example\r\n * ptToMm(2.83) // 1\r\n */\r\nexport const ptToMm = (pt: number): number => pt / 2.83464566929;\r\n\r\n/**\r\n * 像素转毫米\r\n * @param {number} px - 像素值\r\n * @param {number} [dpi=STAND_DPI] - DPI 值,默认为标准 DPI (96)\r\n * @returns {number} 返回毫米值\r\n * @example\r\n * pxToMm(96) // 25.4\r\n */\r\nexport const pxToMm = (px: number, dpi: number = STAND_DPI): number => {\r\n return (25.4 * px) / dpi;\r\n};\r\n\r\n/**\r\n * 限制数值在指定范围内\r\n * @param {number} num - 要限制的数值\r\n * @param {number} min - 最小值\r\n * @param {number} max - 最大值\r\n * @returns {number} 返回限制后的数值\r\n * @example\r\n * limit(150, 0, 100) // 100\r\n */\r\nexport const limit = (num: number, min: number, max: number): number => {\r\n return Math.min(Math.max(num, min), max);\r\n}\r\n\r\n/**\r\n * 检测指定值是否在指定区间内\r\n * @param {Number} val\r\n * @param {Number} min\r\n * @param {Number} max\r\n * @param {Boolean} includeEqual 是否包含等于判断\r\n * @returns {boolean}\r\n */\r\nexport const between = (val: number, min: number, max: number, includeEqual: boolean = true): boolean => {\r\n\treturn includeEqual ? (val >= min && val <= max) : (val > min && val < max);\r\n};\r\n\r\n/**\r\n * 随机整数\r\n * @param {Number} min\r\n * @param {Number} max\r\n * @return {Number}\r\n */\r\nexport const randomInt = (min: number, max: number): number => {\r\n\treturn Math.floor(Math.random() * (max + 1 - min)) + min;\r\n};\r\n\r\n/**\r\n * 取整\r\n * @param {Number} num\r\n * @param {Number} precision 精度,默认为两位小数\r\n * @returns {number}\r\n */\r\nexport const round = (num: number, precision: number = 2): number => {\r\n\tlet multiple = Math.pow(10, precision);\r\n\treturn Math.round(num * multiple) / multiple;\r\n}\r\n\r\n/**\r\n * 检测数值最大精度\r\n * @param {...any} numbers 待检测数值\r\n * @returns\r\n */\r\nexport const detectedPrecision = (...numbers: number[]): number => {\r\n let maxPrecision = 0;\r\n numbers.forEach((num) => {\r\n if (typeof num === \"number\" && !isNaN(num)) {\r\n const decimalPart = num.toString().split(\".\")[1];\r\n if (decimalPart) {\r\n maxPrecision = Math.max(maxPrecision, decimalPart.length);\r\n }\r\n }\r\n });\r\n return maxPrecision;\r\n};\r\n\r\n/**\r\n * 计算数字位数\r\n * @param {number} n - 要计算的数字\r\n * @returns {number} 返回数字的位数\r\n * @example\r\n * digitCount(123) // 3\r\n */\r\nexport const digitCount = (n: number) => {\r\n n = Math.abs(Number(n)); // 取绝对值,防止负数\r\n if (n === 0) return 1;\r\n return Math.floor(Math.log10(n)) + 1;\r\n};","import { guid } from \"./util\";\r\nimport { between } from \"./math\";\r\n\r\n/**\r\n * 隐藏节点(通过设置 display:none 方式)\r\n * @param {HTMLElement|string} dom - DOM 元素或选择器\r\n * @returns {void}\r\n * @example\r\n * hide('#myElement')\r\n */\r\nexport const hide = (dom: HTMLElement | string): void => {\r\n findOne(dom).style.display = \"none\";\r\n};\r\n/**\r\n * 显示节点(通过设置 display 为空方式)\r\n * @param {HTMLElement|string} dom - DOM 元素或选择器\r\n * @returns {void}\r\n * @example\r\n * show('#myElement')\r\n */\r\nexport const show = (dom: HTMLElement | string): void => {\r\n findOne(dom).style.display = \"\";\r\n};\r\n\r\n/**\r\n * 移除 DOM 节点\r\n * @param {HTMLElement|string} dom - DOM 元素或选择器\r\n * @returns {Node|null} 返回被移除的节点,如果未找到返回 null\r\n * @example\r\n * remove('#myElement')\r\n */\r\nexport const remove = (dom: HTMLElement | string): Node | null => {\r\n let el = findOne(dom);\r\n return el && el.parentNode && el.parentNode.removeChild(el);\r\n};\r\n\r\nconst _el_disabled_class_ = \"disabled\";\r\n\r\n/**\r\n * 禁用元素(禁止交互,设置disabled)\r\n * @param {String|Node} el\r\n * @param {String} disabledClass\r\n */\r\nexport const disabled = (el: HTMLElement | string, disabledClass: string = \"\"): void => {\r\n return toggleDisabled(el, disabledClass, false);\r\n};\r\n\r\n/**\r\n * 启用元素(允许交互,移除disabled)\r\n * @param {String|Node} el\r\n * @param {String} disabledClass\r\n */\r\nexport const enabled = (el: HTMLElement | string, disabledClass: string = \"\"): void => {\r\n return toggleDisabled(el, disabledClass, true);\r\n};\r\n\r\n/**\r\n * 禁用启用元素切换\r\n * @param {String|Node} el\r\n * @param {String} disabledClass\r\n * @param {Boolean|Null} forceEnabled 强制启用、禁用,为空表示自动切换\r\n */\r\nexport const toggleDisabled = (el: HTMLElement | string, disabledClass: string = \"\", forceEnabled: boolean | null = null): void => {\r\n let element = findOne(el) as HTMLElement;\r\n let toDisabled = forceEnabled === null ? !element.classList.contains(_el_disabled_class_) : !forceEnabled;\r\n if (toDisabled) {\r\n insertStyleSheet(`.${_el_disabled_class_} {pointer-event:none !important;}`, \"__element_lock_style__\");\r\n }\r\n element.classList.toggle(_el_disabled_class_, toDisabled);\r\n element[toDisabled ? \"setAttribute\" : \"removeAttribute\"](\"disabled\", \"disabled\");\r\n element[toDisabled ? \"setAttribute\" : \"removeAttribute\"](\"data-disabled\", \"disabled\");\r\n if (disabledClass) {\r\n element.classList.toggle(disabledClass, toDisabled);\r\n }\r\n};\r\n\r\nexport const onHover = (el: HTMLElement | string, onHoverIn: () => void, onHoverOut: () => void): void => {\r\n el = findOne(el) as HTMLElement;\r\n let isHovering = false;\r\n el.addEventListener(\"mouseenter\", () => {\r\n if (!isHovering) {\r\n isHovering = true;\r\n onHoverIn && onHoverIn();\r\n }\r\n });\r\n el.addEventListener(\"mouseleave\", () => {\r\n if (isHovering) {\r\n isHovering = false;\r\n onHoverOut && onHoverOut();\r\n }\r\n });\r\n};\r\n\r\n/**\r\n * 绑定元素,禁止交互\r\n * @param {Node} el\r\n * @param {Function} payload 处理函数,参数为 reset\r\n */\r\nexport const lockElementInteraction = (el: HTMLElement | string, payload: (reset: () => void) => void): void => {\r\n disabled(el);\r\n let reset = () => {\r\n enabled(el);\r\n };\r\n payload(reset);\r\n};\r\n/**\r\n * 获取当前节点在父节点中的索引号\r\n * @param {HTMLElement} node - DOM 节点\r\n * @returns {number} 返回索引号,如果没有父节点返回 -1\r\n * @example\r\n * nodeIndex(element) // 2\r\n */\r\nexport const nodeIndex = (node: HTMLElement): number => {\r\n return node.parentNode ? Array.prototype.indexOf.call(node.parentNode.children, node) : -1;\r\n};\r\n\r\n/**\r\n * 通过选择器查找子节点(强制添加 :scope 来约束必须是子节点)\r\n * @param {string|HTMLElement|HTMLElement[]|NodeList|HTMLCollection} selector - 选择器或 DOM 元素\r\n * @param {Document|HTMLElement} [parent=document] - 父节点,默认为 document\r\n * @returns {HTMLElement[]} 返回查找到的所有元素数组\r\n * @example\r\n * findAll('.item', container)\r\n */\r\nexport const findAll = (\r\n selector: string | HTMLElement | HTMLElement[] | NodeList | HTMLCollection,\r\n parent: Document | HTMLElement = document,\r\n): HTMLElement[] => {\r\n if (typeof selector === \"string\") {\r\n selector = selector.trim();\r\n if (selector.indexOf(\":scope\") !== 0) {\r\n selector = \":scope \" + selector;\r\n }\r\n return Array.from(parent.querySelectorAll(selector));\r\n } else if (Array.isArray(selector)) {\r\n let ns: HTMLElement[] = [];\r\n selector.forEach((sel) => {\r\n ns.push(...findAll(sel));\r\n });\r\n return ns;\r\n } else if (NodeList.prototype.isPrototypeOf(selector) || HTMLCollection.prototype.isPrototypeOf(selector)) {\r\n return Array.from(selector as any) as HTMLElement[];\r\n } else if (selector instanceof HTMLElement) {\r\n return [selector];\r\n } else {\r\n return selector as any;\r\n }\r\n};\r\n\r\n/**\r\n * 通过选择器查找单个节点\r\n * @param {string|HTMLElement} selector - 选择器,如果是 HTMLElement,则直接返回\r\n * @param {Document|HTMLElement} [parent=document] - 父节点,默认为 document\r\n * @returns {HTMLElement} 返回查找到的元素\r\n * @example\r\n * findOne('.item')\r\n */\r\nexport const findOne = (selector: string | HTMLElement, parent: Document | HTMLElement = document): HTMLElement => {\r\n return typeof selector === \"string\" ? (parent.querySelector(selector) as HTMLElement) : selector;\r\n};\r\n/**\r\n * 获取节点的 XPath\r\n * @param {HTMLElement|null} el - DOM 元素\r\n * @returns {string|null} 返回 XPath 字符串,失败返回 null\r\n * @example\r\n * getNodeXPath(element) // '/html[1]/body[1]/div[1]'\r\n */\r\nexport const getNodeXPath = (el: HTMLElement | null): string | null => {\r\n let allNodes = document.getElementsByTagName(\"*\");\r\n let seg_list: string[] = [];\r\n for (seg_list = []; el && el.nodeType === 1; el = el.parentNode as HTMLElement) {\r\n if (el.hasAttribute(\"id\")) {\r\n let uniqueIdCount = 0;\r\n for (let n = 0; n < allNodes.length; n++) {\r\n if (allNodes[n].hasAttribute(\"id\") && allNodes[n].id === el.id) uniqueIdCount++;\r\n if (uniqueIdCount > 1) break;\r\n }\r\n if (uniqueIdCount === 1) {\r\n seg_list.unshift('id(\"' + el.getAttribute(\"id\") + '\")');\r\n return seg_list.join(\"/\");\r\n } else {\r\n seg_list.unshift(el.localName.toLowerCase() + '[@id=\"' + el.getAttribute(\"id\") + '\"]');\r\n }\r\n } else if (el.hasAttribute(\"class\")) {\r\n seg_list.unshift(el.localName.toLowerCase() + '[@class=\"' + el.getAttribute(\"class\") + '\"]');\r\n } else {\r\n let i: number, sib: ChildNode | null;\r\n for (i = 1, sib = el.previousSibling; sib; sib = sib.previousSibling) {\r\n if ((sib as any).localName === el.localName) {\r\n i++;\r\n }\r\n }\r\n seg_list.unshift(el.localName.toLowerCase() + \"[\" + i + \"]\");\r\n }\r\n }\r\n return seg_list.length ? \"/\" + seg_list.join(\"/\") : null;\r\n};\r\n/**\r\n * 监听节点树变更\r\n * @param {HTMLElement} dom - 要监听的 DOM 节点\r\n * @param {Function} callback - 回调函数\r\n * @param {boolean} [includeElementChanged=true] - 是否包含表单元素的值变更\r\n * @returns {void}\r\n * @example\r\n * onDomTreeChange(container, () => console.log('changed'))\r\n */\r\nexport const onDomTreeChange = (dom: HTMLElement, callback: () => void, includeElementChanged: boolean = true): void => {\r\n const PRO_KEY = \"ON_DOM_TREE_CHANGE_BIND_\" + guid();\r\n let watchEl = () => {\r\n findAll(`input:not([${PRO_KEY}]), textarea:not([${PRO_KEY}]), select:not([${PRO_KEY}])`, dom).forEach((el) => {\r\n el.setAttribute(PRO_KEY, \"1\");\r\n el.addEventListener(\"change\", callback);\r\n });\r\n };\r\n mutationEffective(\r\n dom,\r\n { attributes: true, subtree: true, childList: true },\r\n () => {\r\n includeElementChanged && watchEl();\r\n callback();\r\n },\r\n 10,\r\n );\r\n includeElementChanged && watchEl();\r\n};\r\n\r\n/**\r\n * 更低占用执行 mutation 监听,支持指定最小间隔时间执行回调\r\n * @param {HTMLElement} dom - 要监听的 DOM 节点\r\n * @param {MutationObserverInit} option - MutationObserver 配置选项\r\n * @param {Function} payload - 回调函数,接收 MutationObserver 实例作为参数\r\n * @param {number} [minInterval=10] - 执行回调最小间隔时间(毫秒)\r\n * @returns {void}\r\n * @example\r\n * mutationEffective(dom, {attributes: true, childList: true}, (obs) => console.log('changed'))\r\n */\r\nexport const mutationEffective = (dom: HTMLElement, option: MutationObserverInit, payload: (obs: MutationObserver) => void, minInterval: number = 10): void => {\r\n let last_queue_time = 0;\r\n let callback_queueing = false;\r\n let obs = new MutationObserver(() => {\r\n if (callback_queueing) {\r\n return;\r\n }\r\n let r = minInterval - (Date.now() - last_queue_time);\r\n if (r > 0) {\r\n callback_queueing = true;\r\n setTimeout(() => {\r\n callback_queueing = false;\r\n last_queue_time = Date.now();\r\n payload(obs);\r\n }, r);\r\n } else {\r\n last_queue_time = Date.now();\r\n payload(obs);\r\n }\r\n });\r\n obs.observe(dom, option);\r\n};\r\n\r\ninterface Dimension {\r\n left: number;\r\n top: number;\r\n width: number;\r\n height: number;\r\n}\r\n\r\n/**\r\n * 保持对象尽量在容器内部,优先保证上边、左边显示\r\n * @param {Object} objDim\r\n * @param {Number} objDim.left\r\n * @param {Number} objDim.top\r\n * @param {Number} objDim.width\r\n * @param {Number} objDim.height\r\n * @param {Object} ctnDim\r\n * @param {Number} ctnDim.left\r\n * @param {Number} ctnDim.top\r\n * @param {Number} ctnDim.width\r\n * @param {Number} ctnDim.height\r\n * {Array} dimension [dimension.left, dimension.top]\r\n */\r\nexport const keepRectInContainer = (\r\n objDim: Dimension,\r\n ctnDim: Dimension = {\r\n left: 0,\r\n top: 0,\r\n width: window.innerWidth,\r\n height: window.innerHeight,\r\n },\r\n): { left: number; top: number } => {\r\n let ret = { left: objDim.left, top: objDim.top };\r\n\r\n //oversize\r\n if (objDim.width > ctnDim.width || objDim.height > ctnDim.height) {\r\n return ret;\r\n }\r\n\r\n //右边超出\r\n if (objDim.width + objDim.left > ctnDim.width + ctnDim.left) {\r\n ret.left = objDim.left - (objDim.width + objDim.left - (ctnDim.width + ctnDim.left));\r\n }\r\n\r\n //底边超出\r\n if (objDim.height + objDim.top > ctnDim.height + ctnDim.top) {\r\n ret.top = objDim.top - (objDim.height + objDim.top - (ctnDim.height + ctnDim.top));\r\n }\r\n\r\n //优先保证左边露出\r\n if (objDim.left < ctnDim.left) {\r\n ret.left = ctnDim.left;\r\n }\r\n\r\n //优先保证上边露出\r\n if (objDim.top < ctnDim.top) {\r\n ret.top = ctnDim.top;\r\n }\r\n return ret;\r\n};\r\n\r\n/**\r\n * 矩形相交(包括边重叠情况)\r\n * @param {Dimension} rect1 - 第一个矩形对象\r\n * @param {Dimension} rect2 - 第二个矩形对象\r\n * @returns {boolean} 如果两个矩形相交返回 true,否则返回 false\r\n * @example\r\n * rectAssoc({left: 0, top: 0, width: 100, height: 100}, {left: 50, top: 50, width: 100, height: 100}) // true\r\n */\r\nexport const rectAssoc = (rect1: Dimension, rect2: Dimension): boolean => {\r\n if (rect1.left <= rect2.left) {\r\n return (\r\n rect1.left + rect1.width >= rect2.left &&\r\n (between(rect2.top, rect1.top, rect1.top + rect1.height) ||\r\n between(rect2.top + rect2.height, rect1.top, rect1.top + rect1.height) ||\r\n (rect2.top >= rect1.top && rect2.height >= rect1.height))\r\n );\r\n } else {\r\n return (\r\n rect2.left + rect2.width >= rect1.left &&\r\n (between(rect1.top, rect2.top, rect2.top + rect2.height) ||\r\n between(rect1.top + rect1.height, rect2.top, rect2.top + rect2.height) ||\r\n (rect1.top >= rect2.top && rect1.height >= rect2.height))\r\n );\r\n }\r\n};\r\n\r\n/**\r\n * 检测元素是否可聚焦\r\n * @param {HTMLElement} el - DOM 元素\r\n * @returns {boolean} 如果元素可聚焦返回 true,否则返回 false\r\n * @example\r\n * isFocusable(inputElement) // true\r\n */\r\nexport const isFocusable = (el: HTMLElement) => {\r\n if (!el) return false;\r\n if (el.tabIndex >= 0) return true;\r\n if (el instanceof HTMLAnchorElement && el.href) return true;\r\n if (el instanceof HTMLButtonElement && !el.disabled) return true;\r\n if (el instanceof HTMLInputElement && !el.disabled) return true;\r\n if (el instanceof HTMLTextAreaElement && !el.disabled) return true;\r\n return false;\r\n};\r\n\r\nlet _c: Record<string, Promise<void>> = {};\r\n\r\n/**\r\n * 挂载 CSS 文件\r\n * @param {string} file - CSS 文件路径\r\n * @param {boolean} [forceReload=false] - 是否强制重新挂载,缺省不重复挂载\r\n * @returns {Promise<void>} 返回 Promise,加载完成后 resolve\r\n * @example\r\n * loadCss('/styles/theme.css')\r\n */\r\nexport const loadCss = (file: string, forceReload: boolean = false): Promise<void> => {\r\n if (!forceReload && file in _c) {\r\n return _c[file];\r\n }\r\n _c[file] = new Promise((resolve, reject) => {\r\n let link = document.createElement(\"link\");\r\n link.rel = \"stylesheet\";\r\n link.href = file;\r\n link.onload = () => {\r\n resolve();\r\n };\r\n link.onerror = () => {\r\n reject();\r\n };\r\n document.head.append(link);\r\n });\r\n return _c[file];\r\n};\r\n\r\n/**\r\n * 加载 Script 脚本\r\n * @param {string} src - 脚本地址\r\n * @param {boolean} [forceReload=false] - 是否强制重新加载,缺省为去重加载\r\n * @returns {Promise<void>} 返回 Promise,加载完成后 resolve\r\n * @example\r\n * loadScript('/scripts/lib.js')\r\n */\r\nexport const loadScript = (src: string, forceReload: boolean = false): Promise<void> => {\r\n if (!forceReload && src in _c) {\r\n return _c[src];\r\n }\r\n _c[src] = new Promise((resolve, reject) => {\r\n let script = document.createElement(\"script\");\r\n script.src = src;\r\n script.onload = () => {\r\n resolve();\r\n };\r\n script.onerror = () => {\r\n reject();\r\n };\r\n document.head.append(script);\r\n });\r\n return _c[src];\r\n};\r\n\r\n/**\r\n * 获取对象宽、高(通过设置 visibility 方式进行获取)\r\n * @param {HTMLElement} dom - DOM 元素\r\n * @returns {{width: number, height: number}} 返回元素的宽度和高度\r\n * @example\r\n * getDomDimension(element) // {width: 100, height: 50}\r\n */\r\nexport const getDomDimension = (dom: HTMLElement): { width: number; height: number } => {\r\n let org_visibility = dom.style.visibility;\r\n let org_display = dom.style.display;\r\n let width, height;\r\n\r\n dom.style.visibility = \"hidden\";\r\n dom.style.display = \"block\";\r\n width = dom.clientWidth;\r\n height = dom.clientHeight;\r\n dom.style.visibility = org_visibility;\r\n dom.style.display = org_display;\r\n return { width, height };\r\n};\r\n\r\n/**\r\n * 在头部插入样式\r\n * @param {string} styleSheetStr - 样式代码\r\n * @param {string} [id=''] - 样式 ID,如果提供 ID,将会检测是否已经插入,可以避免重复插入\r\n * @param {Document} [doc=document] - 文档上下文\r\n * @returns {HTMLStyleElement|null} 返回创建的 style 元素\r\n * @example\r\n * insertStyleSheet('.test { color: red; }', 'my-style')\r\n */\r\nexport const insertStyleSheet = (styleSheetStr: string, id: string = \"\", doc: Document = document): HTMLStyleElement | null => {\r\n if (id && doc.querySelector(`#${id}`)) {\r\n return doc.querySelector(`#${id}`) as HTMLStyleElement;\r\n }\r\n let style = doc.createElement(\"style\");\r\n doc.head.appendChild(style);\r\n style.innerHTML = styleSheetStr;\r\n if (id) {\r\n style.id = id;\r\n }\r\n return style;\r\n};\r\n\r\n/**\r\n * 检测矩形是否在指定布局内部\r\n * @param {Dimension} rect - 要检测的矩形\r\n * @param {Dimension} layout - 布局矩形\r\n * @returns {boolean} 如果矩形在布局内部返回 true,否则返回 false\r\n * @example\r\n * rectInLayout(rect, layout) // true\r\n */\r\nexport const rectInLayout = (rect: Dimension, layout: Dimension): boolean => {\r\n return (\r\n between(rect.top, layout.top, layout.top + layout.height) &&\r\n between(rect.left, layout.left, layout.left + layout.width) && //左上角\r\n between(rect.top + rect.height, layout.top, layout.top + layout.height) &&\r\n between(rect.left + rect.width, layout.left, layout.left + layout.width)\r\n ); //右下角\r\n};\r\n\r\n/**\r\n * 精度位数转小数表示法\r\n * @param {number} precision - 精度位数\r\n * @returns {number} 精度小数表示法,如 0.01\r\n * @example\r\n * precisionToStep(2) // 0.01\r\n */\r\nexport const precisionToStep = (precision: number): number => {\r\n return Math.pow(10, -precision);\r\n};\r\n\r\n/**\r\n * 修复基本 URL(将相对路径转换为绝对 URL)\r\n * @param {string} url - 要修复的 URL\r\n * @param {string} baseUrl - 基本 URL\r\n * @returns {string} 返回修复后的 URL\r\n * @example\r\n * fixBaseUrl('/path', 'https://example.com') // 'https://example.com/path'\r\n */\r\nexport const fixBaseUrl = (url: string, baseUrl: string): string => {\r\n try {\r\n const fixedUrl = new URL(url, baseUrl);\r\n return fixedUrl.href;\r\n } catch {\r\n return url;\r\n }\r\n};\r\n\r\n/**\r\n * 创建 HTML 节点\r\n * @param {string} html - HTML 字符串\r\n * @param {HTMLElement|null} [parentNode=null] - 父级节点,如果提供则自动添加到父节点\r\n * @returns {Node|Node[]} 返回创建的节点,单个或多个\r\n * @example\r\n * createDomByHtml('<div>Hello</div>')\r\n */\r\nexport const createDomByHtml = (html: string, parentNode: HTMLElement | null = null): Node | Node[] => {\r\n let tpl = document.createElement(\"template\");\r\n html = html.trim();\r\n tpl.innerHTML = html;\r\n let nodes: Node[] = [];\r\n if (parentNode) {\r\n tpl.content.childNodes.forEach((node) => {\r\n nodes.push(parentNode.appendChild(node));\r\n });\r\n } else {\r\n nodes = Array.from(tpl.content.childNodes);\r\n }\r\n return nodes.length === 1 ? nodes[0] : nodes;\r\n};\r\n\r\ninterface RectObject {\r\n top: number;\r\n left: number;\r\n right: number;\r\n bottom: number;\r\n width: number;\r\n height: number;\r\n}\r\n\r\n/**\r\n * 获取元素的位置(相对于视口)\r\n * @param {HTMLElement} el - DOM 元素\r\n * @param {boolean} [autoFixInvisible=false] - 是否自动修正隐藏元素无法测量的 bug\r\n * @returns {RectObject} 返回元素的位置和尺寸信息\r\n * @example\r\n * getBoundingClientRect(element) // {top: 100, left: 50, width: 200, height: 100, ...}\r\n */\r\nexport const getBoundingClientRect = (el: HTMLElement, autoFixInvisible = false): RectObject => {\r\n if (!el) {\r\n throw new Error(\"el is null\");\r\n }\r\n const rect = el.getBoundingClientRect();\r\n\r\n //自动修正隐藏元素无法测量bug\r\n if (autoFixInvisible && !rect.height) {\r\n const originalVisibility = el.style.visibility;\r\n const originalDisplay = el.style.display;\r\n el.style.visibility = \"hidden\";\r\n el.style.display = \"block\";\r\n const overlayRect = getBoundingClientRect(el);\r\n el.style.visibility = originalVisibility;\r\n el.style.display = originalDisplay;\r\n return overlayRect;\r\n }\r\n\r\n return {\r\n top: rect.top,\r\n left: rect.left,\r\n right: rect.right,\r\n bottom: rect.bottom,\r\n width: rect.width,\r\n height: rect.height,\r\n };\r\n};\r\n\r\n/**\r\n * 构建 CSS 变量对象(自动添加 -- 前缀和 px 单位)\r\n * @param {Record<string, number|string|undefined>} vars - CSS 变量对象\r\n * @returns {Record<string, string>} 返回格式化后的 CSS 变量对象\r\n * @example\r\n * buildStyleVars({width: 100, color: 'red'}) // {'--width': '100px', '--color': 'red'}\r\n */\r\nexport const buildStyleVars = (vars: Record<string, number | string | undefined>) => {\r\n let styles = {} as Record<string, string>;\r\n for (let k in vars) {\r\n const v = vars[k];\r\n if (v !== undefined) {\r\n styles[`--${k}`] = `${v}` + (typeof v === \"number\" ? \"px\" : \"\");\r\n }\r\n }\r\n return styles;\r\n};\r\n","import { isUrl } from \"./util\";\r\n\r\n/**\r\n * 过滤字符串为合法文件名\r\n * 替换 Windows/Unix 不允许的字符为下划线\r\n * 包括:\\ / : * ? \" < > | 以及控制字符\r\n * @param {string} name\r\n * @returns {string}\r\n */\r\nexport const sanitizeFileName = (name: string): string => {\r\n return name\r\n .replace(/[\\\\/:*?\"<>|]/g, \"_\")\r\n .replace(/[\\0-\\x1F]/g, \"_\") // 单独替换控制字符\r\n .replace(/\\s+/g, \" \") // 替换多个空格为一个空格\r\n .replace(/^\\.+/, \"\") // 去除开头的点\r\n .replace(/\\.+$/, \"\") // 去除结尾的点\r\n .trim();\r\n};\r\n\r\n/**\r\n * 将 Blob 转换为 Data URI\r\n * @param {Blob} blob - Blob 对象\r\n * @returns {Promise<string>} 返回 Data URI 字符串\r\n * @example\r\n * blobToDataUri(blob).then(uri => console.log(uri))\r\n */\r\nexport const blobToDataUri = (blob: Blob): Promise<string> =>\r\n new Promise((resolve, reject) => {\r\n const reader = new FileReader();\r\n reader.onload = () => resolve(reader.result as string);\r\n reader.onerror = (e) => reject(e);\r\n reader.readAsDataURL(blob);\r\n });\r\n\r\n// 缓存通过 URL 获取的文件数据\r\nconst FILE_B64_CACHE_DATA: Record<string, string> = {};\r\n\r\n/**\r\n * URL 转 Base64 Data URL 数据缓存\r\n * @param {string} url - 文件 URL\r\n * @param {string|null} [b64Data=null] - Base64 Data URL 数据,传入 null 则为读取缓存\r\n * @returns {string|null} 读取缓存时返回 Base64 Data URL 字符串,未命中返回 null\r\n * @example\r\n * urlB64DataCache('http://example.com/img.png', dataUrl) // 设置缓存\r\n * urlB64DataCache('http://example.com/img.png') // 读取缓存\r\n */\r\nexport const urlB64DataCache = (url: string, b64Data: string | null = null): string | null => {\r\n if (b64Data !== null) {\r\n FILE_B64_CACHE_DATA[url] = b64Data;\r\n return null;\r\n } else {\r\n return FILE_B64_CACHE_DATA[url] || null;\r\n }\r\n};\r\n\r\n/**\r\n * 将文件转换为 Base64 Data URI\r\n * 支持 File/Blob 对象,或字符串 URL(http(s)/相对/blob:)\r\n * @param {File|Blob|string} file - 文件对象或 URL 字符串\r\n * @returns {Promise<string|null>} 返回 Data URL 字符串,失败返回 null\r\n * @example\r\n * fileToBase64DataUri(file).then(uri => console.log(uri))\r\n */\r\nexport const fileToBase64DataUri = async (file: File | Blob | string) => {\r\n if (!file) {\r\n return null;\r\n }\r\n\r\n // 已经是 data URL\r\n if (typeof file === \"string\" && file.startsWith(\"data:\")) {\r\n return file;\r\n }\r\n\r\n try {\r\n // 字符串 URL(http(s)/相对/blob:)\r\n if (typeof file === \"string\" && isUrl(file)) {\r\n // fetch -> blob -> dataURL\r\n const resp = await fetch(file);\r\n if (!resp.ok) {\r\n throw new Error(`Fetch failed: ${resp.status}`);\r\n }\r\n const blob = await resp.blob();\r\n return await blobToDataUri(blob);\r\n }\r\n\r\n // File 或 Blob\r\n if (file instanceof Blob) {\r\n return await blobToDataUri(file);\r\n }\r\n\r\n // 不能处理的类型,返回 null\r\n return null;\r\n } catch (err) {\r\n console.warn(\"file2Base64DataURL failed:\", err);\r\n return null;\r\n }\r\n};\r\n\r\n/**\r\n * 下载文件\r\n * @param {string} uri - 文件 URI(支持 Data URI 和普通 URL)\r\n * @param {string} fileName - 保存的文件名\r\n * @returns {void}\r\n * @example\r\n * downloadFile('data:text/plain;base64,SGVsbG8=', 'hello.txt')\r\n */\r\nexport const downloadFile = (uri: string, fileName: string) => {\r\n const link = document.createElement(\"a\");\r\n\tlink.rel = 'noopener noreferrer';\r\n link.href = uri;\r\n link.download = fileName;\r\n document.body.appendChild(link);\r\n link.click();\r\n document.body.removeChild(link);\r\n};\r\n","import { regQuote } from \"./string\";\r\n\r\n/**\r\n * 块元素\r\n * 用大写定义,方便直接匹配 node.tagName\r\n * @type {string[]}\r\n */\r\nexport const BLOCK_TAGS = [\r\n \"ADDRESS\",\r\n \"ARTICLE\",\r\n \"ASIDE\",\r\n \"BLOCKQUOTE\",\r\n \"CANVAS\",\r\n \"DD\",\r\n \"DIV\",\r\n \"DL\",\r\n \"DT\",\r\n \"FIELDSET\",\r\n \"FIGCAPTION\",\r\n \"FIGURE\",\r\n \"FOOTER\",\r\n \"FORM\",\r\n \"H1\",\r\n \"H2\",\r\n \"H3\",\r\n \"H4\",\r\n \"H5\",\r\n \"H6\",\r\n \"HEADER\",\r\n \"HR\",\r\n \"LI\",\r\n \"MAIN\",\r\n \"NAV\",\r\n \"NOSCRIPT\",\r\n \"OL\",\r\n \"P\",\r\n \"PRE\",\r\n \"SECTION\",\r\n \"TABLE\",\r\n \"TFOOT\",\r\n \"UL\",\r\n \"VIDEO\",\r\n];\r\n\r\n/**\r\n * 非自关闭标签\r\n * https://www.w3schools.com/html/html_blocks.asp\r\n * @type {*[]}\r\n */\r\nexport const PAIR_TAGS = [\r\n \"A\",\r\n \"ABBR\",\r\n \"ACRONYM\",\r\n \"B\",\r\n \"BDO\",\r\n \"BIG\",\r\n \"BUTTON\",\r\n \"CITE\",\r\n \"CODE\",\r\n \"DFN\",\r\n \"EM\",\r\n \"I\",\r\n \"KBD\",\r\n \"LABEL\",\r\n \"MAP\",\r\n \"OBJECT\",\r\n \"OUTPUT\",\r\n \"Q\",\r\n \"S\",\r\n \"SAMP\",\r\n \"SCRIPT\",\r\n \"SELECT\",\r\n \"SMALL\",\r\n \"SPAN\",\r\n \"STRONG\",\r\n \"SUB\",\r\n \"SUP\",\r\n \"TEXTAREA\",\r\n \"TIME\",\r\n \"TT\",\r\n \"U\",\r\n \"VAR\",\r\n].concat(...BLOCK_TAGS);\r\n\r\n/**\r\n * 自关闭标签\r\n * @type {string[]}\r\n */\r\nexport const SELF_CLOSING_TAGS = [\"AREA\", \"BASE\", \"BR\", \"COL\", \"EMBED\", \"HR\", \"IMG\", \"INPUT\", \"LINK\", \"META\", \"PARAM\", \"SOURCE\", \"TRACK\", \"WBR\"];\r\n\r\n/**\r\n * 非内容可清理标签\r\n * @type {string[]}\r\n */\r\nexport const REMOVABLE_TAGS = [\"STYLE\", \"COMMENT\", \"SELECT\", \"OPTION\", \"SCRIPT\", \"TITLE\", \"HEAD\", \"BUTTON\", \"META\", \"LINK\", \"PARAM\", \"SOURCE\"];\r\n\r\n/**\r\n * 将 HTML 转换为纯文本(移除所有标签和样式)\r\n * @param {string} html - HTML 字符串\r\n * @returns {string} 返回纯文本\r\n * @example\r\n * html2Text('<p>Hello <b>World</b></p>') // 'Hello World'\r\n */\r\nexport const html2Text = (html: string): string => {\r\n //remove removable tags\r\n REMOVABLE_TAGS.forEach((tag) => {\r\n html = html.replace(new RegExp(tag, \"ig\"), \"\");\r\n });\r\n\r\n //remove text line break\r\n html = html.replace(/[\\r|\\n]/g, \"\");\r\n\r\n //convert block tags to line break\r\n html = html.replace(/<(\\w+)([^>]*)>/g, function (_ms: string, tag: string, _tail: string) {\r\n if (BLOCK_TAGS.includes(tag.toUpperCase())) {\r\n return \"\\n\";\r\n }\r\n return \"\";\r\n });\r\n\r\n //remove tag's postfix\r\n html = html.replace(/<\\/(\\w+)([^>]*)>/g, function (_ms: string, _tag: string, _tail: string) {\r\n return \"\";\r\n });\r\n\r\n //remove other tags, likes <img>, input, etc...\r\n html = html.replace(/<[^>]+>/g, \"\");\r\n\r\n //convert entity by names\r\n let entityNamesMap: [RegExp, string][] = [\r\n [/&nbsp;/gi, \" \"],\r\n [/&lt;/gi, \"<\"],\r\n [/&gt;/gi, \">\"],\r\n [/&quot;/gi, '\"'],\r\n [/&apos;/gi, \"'\"],\r\n ];\r\n entityNamesMap.forEach(([matchReg, replacement]) => {\r\n html = html.replace(matchReg, replacement);\r\n });\r\n\r\n //convert entity dec code\r\n html = html.replace(/&#(\\d+);/, function (_ms: string, dec: string) {\r\n return String.fromCharCode(parseInt(dec));\r\n });\r\n\r\n //replace last &amp;\r\n html = html.replace(/&amp;/gi, \"&\");\r\n\r\n //trim head & tail space\r\n html = html.trim();\r\n\r\n return html;\r\n};\r\n\r\n/**\r\n * CSS 选择器转义(处理特殊字符)\r\n * @param {string} str - 要转义的字符串\r\n * @returns {string} 转义后的字符串\r\n * @example\r\n * cssSelectorEscape('my#id') // 'my\\\\#id'\r\n */\r\nexport const cssSelectorEscape = (str: string): string => {\r\n return window.CSS && CSS.escape ? CSS.escape(str) : str.replace(/[!\"#$%&'()*+,.\\/:;<=>?@[\\\\\\]^`{|}~]/g, \"\\\\$&\");\r\n};\r\n\r\n/**\r\n * HTML 实体转字符串\r\n * @param {string} entity - HTML 实体字符串(如 &#72;&#101;&#108;&#108;&#111;)\r\n * @returns {string} 返回解码后的字符串\r\n * @example\r\n * entityToString('&#72;&#101;') // 'He'\r\n */\r\nexport const entityToString = (entity: string): string => {\r\n let entities = entity.split(\";\");\r\n entities.pop();\r\n return entities.map((item: string) => String.fromCharCode(item[2] === \"x\" ? parseInt(item.slice(3), 16) : parseInt(item.slice(2)))).join(\"\");\r\n};\r\n\r\nlet _helper_div: HTMLDivElement | undefined;\r\n/**\r\n * 解码 HTML 实体(包括 script 和 HTML 标签过滤)\r\n * @param {string} str - 包含 HTML 实体的字符串\r\n * @returns {string} 返回解码后的字符串\r\n * @example\r\n * decodeHTMLEntities('&lt;div&gt;') // '<div>'\r\n */\r\nexport const decodeHTMLEntities = (str: string): string => {\r\n if (!_helper_div) {\r\n _helper_div = document.createElement(\"div\");\r\n }\r\n // strip script/html tags\r\n str = str.replace(/<script[^>]*>([\\S\\s]*?)<\\/script>/gim, \"\");\r\n str = str.replace(/<\\/?\\w(?:[^\"'>]|\"[^\"]*\"|'[^']*')*>/gim, \"\");\r\n _helper_div.innerHTML = str;\r\n str = _helper_div.textContent || \"\";\r\n _helper_div.textContent = \"\";\r\n return str;\r\n};\r\n\r\n/**\r\n * 构建 HTML Input:hidden 标签\r\n * @param {Record<string, any>} maps - 键值对对象\r\n * @returns {string} 返回 HTML 字符串\r\n * @example\r\n * buildHtmlHidden({name: 'John', age: 30}) // '<input type=\"hidden\" name=\"name\" value=\"John\"/>...'\r\n */\r\nexport const buildHtmlHidden = (maps: Record<string, any>): string => {\r\n let html = \"\";\r\n for (let key in maps) {\r\n let val = maps[key] === null ? \"\" : maps[key];\r\n html += `<input type=\"hidden\" name=\"${escapeAttr(key)}\" value=\"${escapeAttr(val)}\"/>`;\r\n }\r\n return html;\r\n};\r\n\r\n/**\r\n * 转义 HTML(将特殊字符转换为 HTML 实体)\r\n * @param {string} str - 要转义的字符串\r\n * @param {number} [tabSize=2] - Tab 宽度,如果设置为 0,表示去除 tab\r\n * @param {boolean} [allowLineBreaker=true] - 是否允许换行\r\n * @returns {string} 返回转义后的 HTML\r\n * @example\r\n * escapeHtml('<div>Hello</div>') // '&lt;div&gt;Hello&lt;/div&gt;'\r\n */\r\nexport const escapeHtml = (str: string, tabSize: number = 2, allowLineBreaker: boolean = true): string => {\r\n let s = String(str).replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\").replace(/\"/g, \"&quot;\").replace(/'/g, \"&#039;\");\r\n if (allowLineBreaker) {\r\n s = s.replace(/[\\r\\n]/g, \"<br/>\");\r\n }\r\n if (tabSize) {\r\n s = s.replace(/\\t/g, \"&nbsp;\".repeat(tabSize));\r\n }\r\n s = s.replace(/\\s/g, \"&nbsp;\");\r\n return s;\r\n};\r\n\r\n/**\r\n * 反转义 HTML(将 HTML 实体转换为字符)\r\n * @param {string} html - 包含 HTML 实体的字符串\r\n * @returns {string} 返回反转义后的字符串\r\n * @example\r\n * unescapeHtml('&lt;div&gt;') // '<div>'\r\n */\r\nexport const unescapeHtml = (html: string): string => {\r\n return String(html)\r\n .replace(/&quot;/g, '\"')\r\n .replace(/&#39;/g, \"'\")\r\n .replace(/&lt;/g, \"<\")\r\n .replace(/&gt;/g, \">\")\r\n .replace(/&nbsp;/g, \" \")\r\n .replace(/&amp;/g, \"&\")\r\n .replace(/<br.*>/, \"\\n\");\r\n};\r\n\r\n/**\r\n * 转义 HTML 到属性值(处理属性中的特殊字符)\r\n * @param {string} s - 要转义的字符串\r\n * @param {string} [preserveCR=''] - 是否保留回车符\r\n * @returns {string} 返回转义后的字符串\r\n * @example\r\n * escapeAttr('Hello \"World\"') // 'Hello &quot;World&quot;'\r\n */\r\nexport const escapeAttr = (s: string, preserveCR: string = \"\"): string => {\r\n preserveCR = preserveCR ? \"&#13;\" : \"\\n\";\r\n return (\r\n (\"\" + s) /* Forces the conversion to string. */\r\n .replace(/&/g, \"&amp;\") /* This MUST be the 1st replacement. */\r\n .replace(/'/g, \"&apos;\") /* The 4 other predefined entities, required. */\r\n .replace(/\"/g, \"&quot;\")\r\n .replace(/</g, \"&lt;\")\r\n .replace(/>/g, \"&gt;\")\r\n /*\r\n\t\tYou may add other replacements here for HTML only\r\n\t\t(but it's not necessary).\r\n\t\tOr for XML, only if the named entities are defined in its DTD.\r\n\t\t*/\r\n .replace(/\\r\\n/g, preserveCR) /* Must be before the next replacement. */\r\n .replace(/[\\r\\n]/g, preserveCR)\r\n );\r\n};\r\n\r\n/**\r\n * 字符串转换为 HTML 实体\r\n * @param {string} str - 要转换的字符串\r\n * @param {number} [radix] - 进制,为 16 时使用十六进制\r\n * @returns {string} 返回 HTML 实体字符串\r\n * @example\r\n * stringToEntity('AB', 16) // '&#x41;&#x42;'\r\n */\r\nexport const stringToEntity = (str: string, radix?: number): string => {\r\n let arr = str.split(\"\");\r\n radix = radix || 0;\r\n return arr.map((item: string) => `&#${radix ? \"x\" + item.charCodeAt(0).toString(16) : item.charCodeAt(0)};`).join(\"\");\r\n};\r\n\r\n/**\r\n * 高亮文本(将关键字用指定模板包裹)\r\n * @param {string} text - 原始文本\r\n * @param {string} kw - 关键字\r\n * @param {string} [replaceTpl='<span class=\"matched\">%s</span>'] - 替换模板,%s 为占位符\r\n * @returns {string} 返回高亮后的 HTML\r\n * @example\r\n * highlightText('Hello World', 'World') // 'Hello <span class=\"matched\">World</span>'\r\n */\r\nexport const highlightText = (text: string, kw: string, replaceTpl: string = '<span class=\"matched\">%s</span>'): string => {\r\n if (!kw) {\r\n return text;\r\n }\r\n return text.replace(new RegExp(regQuote(kw), \"ig\"), (match: string) => {\r\n return replaceTpl.replace(\"%s\", match);\r\n });\r\n};\r\n","import { blobToBase64 } from \"./base64\";\r\nimport { urlB64DataCache } from \"./file\";\r\n\r\n/**\r\n * 通过 Image 元素获取 Base64 数据\r\n * @param {HTMLImageElement} img - 图片元素\r\n * @returns {string|null} 返回 Base64 Data URL,失败返回 null\r\n * @example\r\n * imgToBase64(imageElement) // 'data:image/png;base64,...'\r\n */\r\nexport const imgToBase64 = (img: HTMLImageElement): string | null => {\r\n if (!img.src) {\r\n return null;\r\n }\r\n if (img.src.indexOf(\"data:\") === 0) {\r\n return img.src;\r\n }\r\n let canvas = document.createElement(\"canvas\");\r\n canvas.width = img.width;\r\n canvas.height = img.height;\r\n let ctx = canvas.getContext(\"2d\");\r\n if (!ctx) return null;\r\n ctx.drawImage(img, 0, 0, img.width, img.height);\r\n return canvas.toDataURL(\"image/png\");\r\n};\r\n\r\n/**\r\n * 通过图片 URL 获取 Base64(网络请求模式)\r\n * @param {string} src - 图片 URL\r\n * @param {boolean} [cache=false] - 是否缓存结果\r\n * @returns {Promise<unknown>} 返回 Base64 Data URL 的 Promise\r\n * @example\r\n * srcToBase64('https://example.com/image.png').then(base64 => console.log(base64))\r\n */\r\nexport const srcToBase64 = (src: string, cache: boolean = false): Promise<unknown> => {\r\n return new Promise((resolve, reject) => {\r\n if (cache) {\r\n const cached = urlB64DataCache(src);\r\n if (cached) {\r\n return resolve(cached);\r\n }\r\n }\r\n let xhr = new XMLHttpRequest();\r\n xhr.open(\"GET\", src, true);\r\n xhr.responseType = \"blob\";\r\n xhr.onload = function () {\r\n if (this.status === 200) {\r\n let blob = this.response;\r\n blobToBase64(blob)\r\n .then((base64) => {\r\n if (cache) {\r\n urlB64DataCache(src, base64 as string);\r\n }\r\n resolve(base64);\r\n })\r\n .catch((error) => {\r\n reject(error);\r\n });\r\n }\r\n };\r\n xhr.onerror = function () {\r\n reject(\"Error:\" + this.statusText);\r\n };\r\n xhr.onabort = function () {\r\n reject(\"Request abort\");\r\n };\r\n xhr.send();\r\n });\r\n};\r\n","/**\r\n * 将整数相加,在 2^32 处溢出(使用 16 位运算避免 JS 解释器 bug)\r\n * @param {number} x - 第一个整数\r\n * @param {number} y - 第二个整数\r\n * @returns {number} 返回相加结果\r\n */\r\nconst safeAdd = (x: number, y: number): number => {\r\n\tlet lsw = (x & 0xffff) + (y & 0xffff);\r\n\tlet msw = (x >> 16) + (y >> 16) + (lsw >> 16);\r\n\treturn (msw << 16) | (lsw & 0xffff)\r\n}\r\n\r\n/**\r\n * 将 32 位数字向左旋转\r\n * @param {number} num - 要旋转的数字\r\n * @param {number} cnt - 旋转的位数\r\n * @returns {number} 返回旋转后的结果\r\n */\r\nconst bitRotateLeft = (num: number, cnt: number): number => {\r\n\treturn (num << cnt) | (num >>> (32 - cnt))\r\n}\r\n\r\n/**\r\n* These functions implement the four basic operations the algorithm uses.\r\n*/\r\nconst md5cmn = (q: number, a: number, b: number, x: number, s: number, t: number): number => {\r\n\treturn safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b)\r\n}\r\n\r\nconst md5ff = (a: number, b: number, c: number, d: number, x: number, s: number, t: number): number => {\r\n\treturn md5cmn((b & c) | (~b & d), a, b, x, s, t)\r\n}\r\n\r\nconst md5gg = (a: number, b: number, c: number, d: number, x: number, s: number, t: number): number => {\r\n\treturn md5cmn((b & d) | (c & ~d), a, b, x, s, t)\r\n}\r\n\r\nconst md5hh = (a: number, b: number, c: number, d: number, x: number, s: number, t: number): number => {\r\n\treturn md5cmn(b ^ c ^ d, a, b, x, s, t)\r\n}\r\n\r\nconst md5ii = (a: number, b: number, c: number, d: number, x: number, s: number, t: number): number => {\r\n\treturn md5cmn(c ^ (b | ~d), a, b, x, s, t)\r\n}\r\n\r\n/**\r\n* Calculate the MD5 of an array of little-endian words, and a bit length.\r\n*/\r\nconst binlMD5 = (x: number[], len: number): number[] => {\r\n\t/* append padding */\r\n\tx[len >> 5] |= 0x80 << (len % 32);\r\n\tx[((len + 64) >>> 9 << 4) + 14] = len;\r\n\r\n\tlet i: number;\r\n\tlet olda: number;\r\n\tlet oldb: number;\r\n\tlet oldc: number;\r\n\tlet oldd: number;\r\n\tlet a: number = 1732584193;\r\n\tlet b: number = -271733879;\r\n\tlet c: number = -1732584194;\r\n\tlet d: number = 271733878;\r\n\r\n\tfor(i = 0; i < x.length; i += 16){\r\n\t\tolda = a;\r\n\t\toldb = b;\r\n\t\toldc = c;\r\n\t\toldd = d;\r\n\r\n\t\ta = md5ff(a, b, c, d, x[i], 7, -680876936);\r\n\t\td = md5ff(d, a, b, c, x[i + 1], 12, -389564586);\r\n\t\tc = md5ff(c, d, a, b, x[i + 2], 17, 606105819);\r\n\t\tb = md5ff(b, c, d, a, x[i + 3], 22, -1044525330);\r\n\t\ta = md5ff(a, b, c, d, x[i + 4], 7, -176418897);\r\n\t\td = md5ff(d, a, b, c, x[i + 5], 12, 1200080426);\r\n\t\tc = md5ff(c, d, a, b, x[i + 6], 17, -1473231341);\r\n\t\tb = md5ff(b, c, d, a, x[i + 7], 22, -45705983);\r\n\t\ta = md5ff(a, b, c, d, x[i + 8], 7, 1770035416);\r\n\t\td = md5ff(d, a, b, c, x[i + 9], 12, -1958414417);\r\n\t\tc = md5ff(c, d, a, b, x[i + 10], 17, -42063);\r\n\t\tb = md5ff(b, c, d, a, x[i + 11], 22, -1990404162);\r\n\t\ta = md5ff(a, b, c, d, x[i + 12], 7, 1804603682);\r\n\t\td = md5ff(d, a, b, c, x[i + 13], 12, -40341101);\r\n\t\tc = md5ff(c, d, a, b, x[i + 14], 17, -1502002290);\r\n\t\tb = md5ff(b, c, d, a, x[i + 15], 22, 1236535329);\r\n\r\n\t\ta = md5gg(a, b, c, d, x[i + 1], 5, -165796510);\r\n\t\td = md5gg(d, a, b, c, x[i + 6], 9, -1069501632);\r\n\t\tc = md5gg(c, d, a, b, x[i + 11], 14, 643717713);\r\n\t\tb = md5gg(b, c, d, a, x[i], 20, -373897302);\r\n\t\ta = md5gg(a, b, c, d, x[i + 5], 5, -701558691);\r\n\t\td = md5gg(d, a, b, c, x[i + 10], 9, 38016083);\r\n\t\tc = md5gg(c, d, a, b, x[i + 15], 14, -660478335);\r\n\t\tb = md5gg(b, c, d, a, x[i + 4], 20, -405537848);\r\n\t\ta = md5gg(a, b, c, d, x[i + 9], 5, 568446438);\r\n\t\td = md5gg(d, a, b, c, x[i + 14], 9, -1019803690);\r\n\t\tc = md5gg(c, d, a, b, x[i + 3], 14, -187363961);\r\n\t\tb = md5gg(b, c, d, a, x[i + 8], 20, 1163531501);\r\n\t\ta = md5gg(a, b, c, d, x[i + 13], 5, -1444681467);\r\n\t\td = md5gg(d, a, b, c, x[i + 2], 9, -51403784);\r\n\t\tc = md5gg(c, d, a, b, x[i + 7], 14, 1735328473);\r\n\t\tb = md5gg(b, c, d, a, x[i + 12], 20, -1926607734);\r\n\r\n\t\ta = md5hh(a, b, c, d, x[i + 5], 4, -378558);\r\n\t\td = md5hh(d, a, b, c, x[i + 8], 11, -2022574463);\r\n\t\tc = md5hh(c, d, a, b, x[i + 11], 16, 1839030562);\r\n\t\tb = md5hh(b, c, d, a, x[i + 14], 23, -35309556);\r\n\t\ta = md5hh(a, b, c, d, x[i + 1], 4, -1530992060);\r\n\t\td = md5hh(d, a, b, c, x[i + 4], 11, 1272893353);\r\n\t\tc = md5hh(c, d, a, b, x[i + 7], 16, -155497632);\r\n\t\tb = md5hh(b, c, d, a, x[i + 10], 23, -1094730640);\r\n\t\ta = md5hh(a, b, c, d, x[i + 13], 4, 681279174);\r\n\t\td = md5hh(d, a, b, c, x[i], 11, -358537222);\r\n\t\tc = md5hh(c, d, a, b, x[i + 3], 16, -722521979);\r\n\t\tb = md5hh(b, c, d, a, x[i + 6], 23, 76029189);\r\n\t\ta = md5hh(a, b, c, d, x[i + 9], 4, -640364487);\r\n\t\td = md5hh(d, a, b, c, x[i + 12], 11, -421815835);\r\n\t\tc = md5hh(c, d, a, b, x[i + 15], 16, 530742520);\r\n\t\tb = md5hh(b, c, d, a, x[i + 2], 23, -995338651);\r\n\r\n\t\ta = md5ii(a, b, c, d, x[i], 6, -198630844);\r\n\t\td = md5ii(d, a, b, c, x[i + 7], 10, 1126891415);\r\n\t\tc = md5ii(c, d, a, b, x[i + 14], 15, -1416354905);\r\n\t\tb = md5ii(b, c, d, a, x[i + 5], 21, -57434055);\r\n\t\ta = md5ii(a, b, c, d, x[i + 12], 6, 1700485571);\r\n\t\td = md5ii(d, a, b, c, x[i + 3], 10, -1894986606);\r\n\t\tc = md5ii(c, d, a, b, x[i + 10], 15, -1051523);\r\n\t\tb = md5ii(b, c, d, a, x[i + 1], 21, -2054922799);\r\n\t\ta = md5ii(a, b, c, d, x[i + 8], 6, 1873313359);\r\n\t\td = md5ii(d, a, b, c, x[i + 15], 10, -30611744);\r\n\t\tc = md5ii(c, d, a, b, x[i + 6], 15, -1560198380);\r\n\t\tb = md5ii(b, c, d, a, x[i + 13], 21, 1309151649);\r\n\t\ta = md5ii(a, b, c, d, x[i + 4], 6, -145523070);\r\n\t\td = md5ii(d, a, b, c, x[i + 11], 10, -1120210379);\r\n\t\tc = md5ii(c, d, a, b, x[i + 2], 15, 718787259);\r\n\t\tb = md5ii(b, c, d, a, x[i + 9], 21, -343485551);\r\n\r\n\t\ta = safeAdd(a, olda)\r\n\t\tb = safeAdd(b, oldb)\r\n\t\tc = safeAdd(c, oldc)\r\n\t\td = safeAdd(d, oldd)\r\n\t}\r\n\treturn [a, b, c, d]\r\n}\r\n\r\n/**\r\n* Convert an array of little-endian words to a string\r\n*/\r\nconst binl2rstr = (input: number[]): string => {\r\n\tlet i: number;\r\n\tlet output: string = '';\r\n\tlet length32: number = input.length * 32;\r\n\tfor(i = 0; i < length32; i += 8){\r\n\t\toutput += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xff)\r\n\t}\r\n\treturn output\r\n}\r\n\r\n/**\r\n* Convert a raw string to an array of little-endian words\r\n* Characters >255 have their high-byte silently ignored.\r\n*/\r\nconst rstr2binl = (input: string): number[] => {\r\n\tlet i: number;\r\n\tlet output: number[] = [];\r\n\toutput[(input.length >> 2) - 1] = undefined as any;\r\n\tfor(i = 0; i < output.length; i += 1){\r\n\t\toutput[i] = 0\r\n\t}\r\n\tlet length8: number = input.length * 8;\r\n\tfor(i = 0; i < length8; i += 8){\r\n\t\toutput[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << (i % 32)\r\n\t}\r\n\treturn output\r\n}\r\n\r\n/**\r\n* Calculate the MD5 of a raw string\r\n*/\r\nconst rstrMD5 = (s: string): string => {\r\n\treturn binl2rstr(binlMD5(rstr2binl(s), s.length * 8))\r\n}\r\n\r\n/**\r\n* Calculate the HMAC-MD5, of a key and some data (raw strings)\r\n*/\r\nconst rstrHMACMD5 = (key: string, data: string): string => {\r\n\tlet i: number;\r\n\tlet bkey: number[] = rstr2binl(key);\r\n\tlet ipad: number[] = [];\r\n\tlet opad: number[] = [];\r\n\tlet hash: number[];\r\n\tipad[15] = opad[15] = undefined as any;\r\n\tif(bkey.length > 16){\r\n\t\tbkey = binlMD5(bkey, key.length * 8)\r\n\t}\r\n\tfor(i = 0; i < 16; i += 1){\r\n\t\tipad[i] = bkey[i] ^ 0x36363636;\r\n\t\topad[i] = bkey[i] ^ 0x5c5c5c5c\r\n\t}\r\n\thash = binlMD5(ipad.concat(rstr2binl(data)), 512 + data.length * 8);\r\n\treturn binl2rstr(binlMD5(opad.concat(hash), 512 + 128))\r\n}\r\n\r\n/**\r\n* Convert a raw string to a hex string\r\n*/\r\nconst rstr2hex = (input: string): string => {\r\n\tlet hexTab: string = '0123456789abcdef';\r\n\tlet output: string = '';\r\n\tlet x: number;\r\n\tlet i: number;\r\n\tfor(i = 0; i < input.length; i += 1){\r\n\t\tx = input.charCodeAt(i);\r\n\t\toutput += hexTab.charAt((x >>> 4) & 0x0f) + hexTab.charAt(x & 0x0f)\r\n\t}\r\n\treturn output\r\n}\r\n\r\n/**\r\n* Encode a string as utf-8\r\n*/\r\nconst str2rstrUTF8 = (input: string): string => {\r\n\treturn unescape(encodeURIComponent(input))\r\n}\r\n\r\n/**\r\n* Take string arguments and return either raw or hex encoded strings\r\n*/\r\nconst rawMD5 = (s: string): string => {\r\n\treturn rstrMD5(str2rstrUTF8(s))\r\n}\r\n\r\nconst hexMD5 = (s: string): string => {\r\n\treturn rstr2hex(rawMD5(s))\r\n}\r\n\r\nconst rawHMACMD5 = (k: string, d: string): string => {\r\n\treturn rstrHMACMD5(str2rstrUTF8(k), str2rstrUTF8(d))\r\n}\r\n\r\nconst hexHMACMD5 = (k: string, d: string): string => {\r\n\treturn rstr2hex(rawHMACMD5(k, d))\r\n}\r\n\r\n/**\r\n * 计算字符串的 MD5 哈希值\r\n * @param {string} string - 要计算 MD5 的字符串\r\n * @param {string} [key] - HMAC 密钥(可选)\r\n * @param {boolean} [raw] - 是否返回原始字符串,默认返回十六进制字符串\r\n * @returns {string} 返回 MD5 哈希值\r\n * @example\r\n * md5('Hello World') // 'b10a8db164e0754105b7a99be72e3fe5'\r\n */\r\nexport const md5 = (string: string, key?: string, raw?: boolean): string => {\r\n\tif(!key){\r\n\t\tif(!raw){\r\n\t\t\treturn hexMD5(string)\r\n\t\t}\r\n\t\treturn rawMD5(string)\r\n\t}\r\n\tif(!raw){\r\n\t\treturn hexHMACMD5(key, string)\r\n\t}\r\n\treturn rawHMACMD5(key, string)\r\n};\r\n","/**\r\n * 缺省二进制文件MIME\r\n * @see https://datatracker.ietf.org/doc/html/rfc2046\r\n * @type {String}\r\n */\r\nexport const MIME_BINARY_DEFAULT = 'application/octet-stream';\r\n\r\nexport const MIME_JSON = \"application/json\";\r\nexport const MIME_FORM = \"application/x-www-form-urlencoded\";\r\nexport const MIME_MULTIPART = \"multipart/form-data\";\r\nexport const MIME_TEXT = \"text/plain\";\r\nexport const MIME_HTML = \"text/html\";\r\n\r\n\r\n/**\r\n * MIME常见扩展名映射表\r\n * @type {Object}\r\n */\r\nexport const MIME_EXTENSION_MAP = {\r\n\t\"323\": \"text/h323\",\r\n\t\"accdb\": \"application/msaccess\",\r\n\t\"accde\": \"application/msaccess\",\r\n\t\"accdt\": \"application/msaccess\",\r\n\t\"acx\": \"application/internet-property-stream\",\r\n\t\"ai\": \"application/postscript\",\r\n\t\"aif\": \"audio/x-aiff\",\r\n\t\"aifc\": \"audio/aiff\",\r\n\t\"aiff\": \"audio/aiff\",\r\n\t\"application\": \"application/x-ms-application\",\r\n\t\"art\": \"image/x-jg\",\r\n\t\"asf\": \"video/x-ms-asf\",\r\n\t\"asm\": \"text/plain\",\r\n\t\"asr\": \"video/x-ms-asf\",\r\n\t\"asx\": \"video/x-ms-asf\",\r\n\t\"atom\": \"application/atom+xml\",\r\n\t\"au\": \"audio/basic\",\r\n\t\"avi\": \"video/x-msvideo\",\r\n\t\"axs\": \"application/olescript\",\r\n\t\"bas\": \"text/plain\",\r\n\t\"bcpio\": \"application/x-bcpio\",\r\n\t\"bmp\": \"image/bmp\",\r\n\t\"c\": \"text/plain\",\r\n\t\"calx\": \"application/vnd.ms-office.calx\",\r\n\t\"cat\": \"application/vnd.ms-pki.seccat\",\r\n\t\"cdf\": \"application/x-cdf\",\r\n\t\"class\": \"application/x-java-applet\",\r\n\t\"clp\": \"application/x-msclip\",\r\n\t\"cmx\": \"image/x-cmx\",\r\n\t\"cnf\": \"text/plain\",\r\n\t\"cod\": \"image/cis-cod\",\r\n\t\"cpio\": \"application/x-cpio\",\r\n\t\"cpp\": \"text/plain\",\r\n\t\"crd\": \"application/x-mscardfile\",\r\n\t\"crl\": \"application/pkix-crl\",\r\n\t\"crt\": \"application/x-x509-ca-cert\",\r\n\t\"csh\": \"application/x-csh\",\r\n\t\"css\": \"text/css\",\r\n\t\"dcr\": \"application/x-director\",\r\n\t\"der\": \"application/x-x509-ca-cert\",\r\n\t\"dib\": \"image/bmp\",\r\n\t\"dir\": \"application/x-director\",\r\n\t\"disco\": \"text/xml\",\r\n\t\"dll\": \"application/x-msdownload\",\r\n\t\"dll.config\": \"text/xml\",\r\n\t\"dlm\": \"text/dlm\",\r\n\t\"doc\": \"application/msword\",\r\n\t\"docm\": \"application/vnd.ms-word.document.macroEnabled.12\",\r\n\t\"docx\": \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\r\n\t\"dot\": \"application/msword\",\r\n\t\"dotm\": \"application/vnd.ms-word.template.macroEnabled.12\",\r\n\t\"dotx\": \"application/vnd.openxmlformats-officedocument.wordprocessingml.template\",\r\n\t\"dtd\": \"text/xml\",\r\n\t\"dvi\": \"application/x-dvi\",\r\n\t\"dwf\": \"drawing/x-dwf\",\r\n\t\"dxr\": \"application/x-director\",\r\n\t\"eml\": \"message/rfc822\",\r\n\t\"eps\": \"application/postscript\",\r\n\t\"etx\": \"text/x-setext\",\r\n\t\"evy\": \"application/envoy\",\r\n\t\"exe.config\": \"text/xml\",\r\n\t\"fdf\": \"application/vnd.fdf\",\r\n\t\"fif\": \"application/fractals\",\r\n\t\"flr\": \"x-world/x-vrml\",\r\n\t\"flv\": \"video/x-flv\",\r\n\t\"gif\": \"image/gif\",\r\n\t\"gtar\": \"application/x-gtar\",\r\n\t\"gz\": \"application/x-gzip\",\r\n\t\"h\": \"text/plain\",\r\n\t\"hdf\": \"application/x-hdf\",\r\n\t\"hdml\": \"text/x-hdml\",\r\n\t\"hhc\": \"application/x-oleobject\",\r\n\t\"hlp\": \"application/winhlp\",\r\n\t\"hqx\": \"application/mac-binhex40\",\r\n\t\"hta\": \"application/hta\",\r\n\t\"htc\": \"text/x-component\",\r\n\t\"htm\": \"text/html\",\r\n\t\"html\": \"text/html\",\r\n\t\"htt\": \"text/webviewhtml\",\r\n\t\"hxt\": \"text/html\",\r\n\t\"ico\": \"image/x-icon\",\r\n\t\"ief\": \"image/ief\",\r\n\t\"iii\": \"application/x-iphone\",\r\n\t\"ins\": \"application/x-internet-signup\",\r\n\t\"isp\": \"application/x-internet-signup\",\r\n\t\"IVF\": \"video/x-ivf\",\r\n\t\"jar\": \"application/java-archive\",\r\n\t\"jck\": \"application/liquidmotion\",\r\n\t\"jcz\": \"application/liquidmotion\",\r\n\t\"jfif\": \"image/pjpeg\",\r\n\t\"jpe\": \"image/jpeg\",\r\n\t\"jpeg\": \"image/jpeg\",\r\n\t\"jpg\": \"image/jpeg\",\r\n\t\"js\": \"application/x-javascript\",\r\n\t\"jsx\": \"text/jscript\",\r\n\t\"latex\": \"application/x-latex\",\r\n\t\"lit\": \"application/x-ms-reader\",\r\n\t\"lsf\": \"video/x-la-asf\",\r\n\t\"lsx\": \"video/x-la-asf\",\r\n\t\"m13\": \"application/x-msmediaview\",\r\n\t\"m14\": \"application/x-msmediaview\",\r\n\t\"m1v\": \"video/mpeg\",\r\n\t\"m3u\": \"audio/x-mpegurl\",\r\n\t\"man\": \"application/x-troff-man\",\r\n\t\"manifest\": \"application/x-ms-manifest\",\r\n\t\"map\": \"text/plain\",\r\n\t\"mdb\": \"application/x-msaccess\",\r\n\t\"me\": \"application/x-troff-me\",\r\n\t\"mht\": \"message/rfc822\",\r\n\t\"mhtml\": \"message/rfc822\",\r\n\t\"mid\": \"audio/mid\",\r\n\t\"midi\": \"audio/mid\",\r\n\t\"mmf\": \"application/x-smaf\",\r\n\t\"mno\": \"text/xml\",\r\n\t\"mny\": \"application/x-msmoney\",\r\n\t\"mov\": \"video/quicktime\",\r\n\t\"movie\": \"video/x-sgi-movie\",\r\n\t\"mp2\": \"video/mpeg\",\r\n\t\"mp3\": \"audio/mpeg\",\r\n\t\"mpa\": \"video/mpeg\",\r\n\t\"mpe\": \"video/mpeg\",\r\n\t\"mpeg\": \"video/mpeg\",\r\n\t\"mpg\": \"video/mpeg\",\r\n\t\"mpp\": \"application/vnd.ms-project\",\r\n\t\"mpv2\": \"video/mpeg\",\r\n\t\"ms\": \"application/x-troff-ms\",\r\n\t\"mvb\": \"application/x-msmediaview\",\r\n\t\"mvc\": \"application/x-miva-compiled\",\r\n\t\"nc\": \"application/x-netcdf\",\r\n\t\"nsc\": \"video/x-ms-asf\",\r\n\t\"nws\": \"message/rfc822\",\r\n\t\"oda\": \"application/oda\",\r\n\t\"odc\": \"text/x-ms-odc\",\r\n\t\"ods\": \"application/oleobject\",\r\n\t\"one\": \"application/onenote\",\r\n\t\"onea\": \"application/onenote\",\r\n\t\"onetoc\": \"application/onenote\",\r\n\t\"onetoc2\": \"application/onenote\",\r\n\t\"onetmp\": \"application/onenote\",\r\n\t\"onepkg\": \"application/onenote\",\r\n\t\"osdx\": \"application/opensearchdescription+xml\",\r\n\t\"p10\": \"application/pkcs10\",\r\n\t\"p12\": \"application/x-pkcs12\",\r\n\t\"p7b\": \"application/x-pkcs7-certificates\",\r\n\t\"p7c\": \"application/pkcs7-mime\",\r\n\t\"p7m\": \"application/pkcs7-mime\",\r\n\t\"p7r\": \"application/x-pkcs7-certreqresp\",\r\n\t\"p7s\": \"application/pkcs7-signature\",\r\n\t\"pbm\": \"image/x-portable-bitmap\",\r\n\t\"pdf\": \"application/pdf\",\r\n\t\"pfx\": \"application/x-pkcs12\",\r\n\t\"pgm\": \"image/x-portable-graymap\",\r\n\t\"pko\": \"application/vnd.ms-pki.pko\",\r\n\t\"pma\": \"application/x-perfmon\",\r\n\t\"pmc\": \"application/x-perfmon\",\r\n\t\"pml\": \"application/x-perfmon\",\r\n\t\"pmr\": \"application/x-perfmon\",\r\n\t\"pmw\": \"application/x-perfmon\",\r\n\t\"png\": \"image/png\",\r\n\t\"pnm\": \"image/x-portable-anymap\",\r\n\t\"pnz\": \"image/png\",\r\n\t\"pot\": \"application/vnd.ms-powerpoint\",\r\n\t\"potm\": \"application/vnd.ms-powerpoint.template.macroEnabled.12\",\r\n\t\"potx\": \"application/vnd.openxmlformats-officedocument.presentationml.template\",\r\n\t\"ppam\": \"application/vnd.ms-powerpoint.addin.macroEnabled.12\",\r\n\t\"ppm\": \"image/x-portable-pixmap\",\r\n\t\"pps\": \"application/vnd.ms-powerpoint\",\r\n\t\"ppsm\": \"application/vnd.ms-powerpoint.slideshow.macroEnabled.12\",\r\n\t\"ppsx\": \"application/vnd.openxmlformats-officedocument.presentationml.slideshow\",\r\n\t\"ppt\": \"application/vnd.ms-powerpoint\",\r\n\t\"pptm\": \"application/vnd.ms-powerpoint.presentation.macroEnabled.12\",\r\n\t\"pptx\": \"application/vnd.openxmlformats-officedocument.presentationml.presentation\",\r\n\t\"prf\": \"application/pics-rules\",\r\n\t\"ps\": \"application/postscript\",\r\n\t\"pub\": \"application/x-mspublisher\",\r\n\t\"qt\": \"video/quicktime\",\r\n\t\"qtl\": \"application/x-quicktimeplayer\",\r\n\t\"ra\": \"audio/x-pn-realaudio\",\r\n\t\"ram\": \"audio/x-pn-realaudio\",\r\n\t\"ras\": \"image/x-cmu-raster\",\r\n\t\"rf\": \"image/vnd.rn-realflash\",\r\n\t\"rgb\": \"image/x-rgb\",\r\n\t\"rm\": \"application/vnd.rn-realmedia\",\r\n\t\"rmi\": \"audio/mid\",\r\n\t\"roff\": \"application/x-troff\",\r\n\t\"rpm\": \"audio/x-pn-realaudio-plugin\",\r\n\t\"rtf\": \"application/rtf\",\r\n\t\"rtx\": \"text/richtext\",\r\n\t\"scd\": \"application/x-msschedule\",\r\n\t\"sct\": \"text/scriptlet\",\r\n\t\"setpay\": \"application/set-payment-initiation\",\r\n\t\"setreg\": \"application/set-registration-initiation\",\r\n\t\"sgml\": \"text/sgml\",\r\n\t\"sh\": \"application/x-sh\",\r\n\t\"shar\": \"application/x-shar\",\r\n\t\"sit\": \"application/x-stuffit\",\r\n\t\"sldm\": \"application/vnd.ms-powerpoint.slide.macroEnabled.12\",\r\n\t\"sldx\": \"application/vnd.openxmlformats-officedocument.presentationml.slide\",\r\n\t\"smd\": \"audio/x-smd\",\r\n\t\"smx\": \"audio/x-smd\",\r\n\t\"smz\": \"audio/x-smd\",\r\n\t\"snd\": \"audio/basic\",\r\n\t\"spc\": \"application/x-pkcs7-certificates\",\r\n\t\"spl\": \"application/futuresplash\",\r\n\t\"src\": \"application/x-wais-source\",\r\n\t\"ssm\": \"application/streamingmedia\",\r\n\t\"sst\": \"application/vnd.ms-pki.certstore\",\r\n\t\"stl\": \"application/vnd.ms-pki.stl\",\r\n\t\"sv4cpio\": \"application/x-sv4cpio\",\r\n\t\"sv4crc\": \"application/x-sv4crc\",\r\n\t\"svg\": \"image/svg+xml\",\r\n\t\"swf\": \"application/x-shockwave-flash\",\r\n\t\"t\": \"application/x-troff\",\r\n\t\"tar\": \"application/x-tar\",\r\n\t\"tcl\": \"application/x-tcl\",\r\n\t\"tex\": \"application/x-tex\",\r\n\t\"texi\": \"application/x-texinfo\",\r\n\t\"texinfo\": \"application/x-texinfo\",\r\n\t\"tgz\": \"application/x-compressed\",\r\n\t\"thmx\": \"application/vnd.ms-officetheme\",\r\n\t\"tif\": \"image/tiff\",\r\n\t\"tiff\": \"image/tiff\",\r\n\t\"tr\": \"application/x-troff\",\r\n\t\"trm\": \"application/x-msterminal\",\r\n\t\"tsv\": \"text/tab-separated-values\",\r\n\t\"txt\": \"text/plain\",\r\n\t\"uls\": \"text/iuls\",\r\n\t\"ustar\": \"application/x-ustar\",\r\n\t\"vbs\": \"text/vbscript\",\r\n\t\"vcf\": \"text/x-vcard\",\r\n\t\"vcs\": \"text/plain\",\r\n\t\"vdx\": \"application/vnd.ms-visio.viewer\",\r\n\t\"vml\": \"text/xml\",\r\n\t\"vsd\": \"application/vnd.visio\",\r\n\t\"vss\": \"application/vnd.visio\",\r\n\t\"vst\": \"application/vnd.visio\",\r\n\t\"vsto\": \"application/x-ms-vsto\",\r\n\t\"vsw\": \"application/vnd.visio\",\r\n\t\"vsx\": \"application/vnd.visio\",\r\n\t\"vtx\": \"application/vnd.visio\",\r\n\t\"wav\": \"audio/wav\",\r\n\t\"wax\": \"audio/x-ms-wax\",\r\n\t\"wbmp\": \"image/vnd.wap.wbmp\",\r\n\t\"wcm\": \"application/vnd.ms-works\",\r\n\t\"wdb\": \"application/vnd.ms-works\",\r\n\t\"wks\": \"application/vnd.ms-works\",\r\n\t\"wm\": \"video/x-ms-wm\",\r\n\t\"wma\": \"audio/x-ms-wma\",\r\n\t\"wmd\": \"application/x-ms-wmd\",\r\n\t\"wmf\": \"application/x-msmetafile\",\r\n\t\"wml\": \"text/vnd.wap.wml\",\r\n\t\"wmlc\": \"application/vnd.wap.wmlc\",\r\n\t\"wmls\": \"text/vnd.wap.wmlscript\",\r\n\t\"wmlsc\": \"application/vnd.wap.wmlscriptc\",\r\n\t\"wmp\": \"video/x-ms-wmp\",\r\n\t\"wmv\": \"video/x-ms-wmv\",\r\n\t\"wmx\": \"video/x-ms-wmx\",\r\n\t\"wmz\": \"application/x-ms-wmz\",\r\n\t\"wps\": \"application/vnd.ms-works\",\r\n\t\"wri\": \"application/x-mswrite\",\r\n\t\"wrl\": \"x-world/x-vrml\",\r\n\t\"wrz\": \"x-world/x-vrml\",\r\n\t\"wsdl\": \"text/xml\",\r\n\t\"wvx\": \"video/x-ms-wvx\",\r\n\t\"x\": \"application/directx\",\r\n\t\"xaf\": \"x-world/x-vrml\",\r\n\t\"xaml\": \"application/xaml+xml\",\r\n\t\"xap\": \"application/x-silverlight-app\",\r\n\t\"xbap\": \"application/x-ms-xbap\",\r\n\t\"xbm\": \"image/x-xbitmap\",\r\n\t\"xdr\": \"text/plain\",\r\n\t\"xht\": \"application/xhtml+xml\",\r\n\t\"xhtml\": \"application/xhtml+xml\",\r\n\t\"xla\": \"application/vnd.ms-excel\",\r\n\t\"xlam\": \"application/vnd.ms-excel.addin.macroEnabled.12\",\r\n\t\"xlc\": \"application/vnd.ms-excel\",\r\n\t\"xlm\": \"application/vnd.ms-excel\",\r\n\t\"xls\": \"application/vnd.ms-excel\",\r\n\t\"xlsb\": \"application/vnd.ms-excel.sheet.binary.macroEnabled.12\",\r\n\t\"xlsm\": \"application/vnd.ms-excel.sheet.macroEnabled.12\",\r\n\t\"xlsx\": \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\r\n\t\"xlt\": \"application/vnd.ms-excel\",\r\n\t\"xltm\": \"application/vnd.ms-excel.template.macroEnabled.12\",\r\n\t\"xltx\": \"application/vnd.openxmlformats-officedocument.spreadsheetml.template\",\r\n\t\"xlw\": \"application/vnd.ms-excel\",\r\n\t\"xml\": \"text/xml\",\r\n\t\"xof\": \"x-world/x-vrml\",\r\n\t\"xpm\": \"image/x-xpixmap\",\r\n\t\"xps\": \"application/vnd.ms-xpsdocument\",\r\n\t\"xsd\": \"text/xml\",\r\n\t\"xsf\": \"text/xml\",\r\n\t\"xsl\": \"text/xml\",\r\n\t\"xslt\": \"text/xml\",\r\n\t\"xwd\": \"image/x-xwindowdump\",\r\n\t\"z\": \"application/x-compress\",\r\n\t\"zip\": \"application/x-zip-compressed\"\r\n}","import { MIME_FORM, MIME_JSON, MIME_MULTIPART } from \"./mime\";\r\n\r\n/**\r\n * 将 URL 查询字符串转换为对象\r\n * @param {string} query - 查询字符串\r\n * @returns {Record<string, string>} 返回键值对对象\r\n * @example\r\n * queryToObj('name=John&age=30') // {name: 'John', age: '30'}\r\n */\r\nexport const queryToObj = (query: string): Record<string, string> => {\r\n const obj: Record<string, string> = {};\r\n query\r\n .replace(/^\\?/, \"\")\r\n .split(\"&\")\r\n .forEach((pair) => {\r\n const [key, value] = pair.split(\"=\");\r\n if (key) {\r\n obj[decodeURIComponent(key)] = decodeURIComponent(value || \"\");\r\n }\r\n });\r\n return obj;\r\n};\r\n\r\n/**\r\n * 替换 URL 中的查询参数\r\n * @param {string} url - 原始 URL\r\n * @param {Record<string, any>} newQuery - 新的查询参数对象\r\n * @returns {string} 返回更新后的 URL\r\n * @example\r\n * queryReplace('http://example.com?a=1', {b: 2}) // 'http://example.com?a=1&b=2'\r\n */\r\nexport const queryReplace = (url: string, newQuery: Record<string, any>): string => {\r\n const [baseUrl, queryString] = url.split(\"?\");\r\n const currentQuery = queryString ? queryToObj(queryString) : {};\r\n const mergedQuery = { ...currentQuery, ...newQuery };\r\n const newQueryString = objToQuery(mergedQuery);\r\n return `${baseUrl}?${newQueryString}`;\r\n};\r\n\r\n/**\r\n * 将对象转换为 URL 查询字符串\r\n * @param {Record<string, any>} data - 数据对象\r\n * @returns {string} 返回查询字符串\r\n * @example\r\n * objToQuery({name: 'John', age: 30}) // 'name=John&age=30'\r\n */\r\nexport const objToQuery = (data: Record<string, any>): string => {\r\n if (typeof data === \"undefined\" || typeof data !== \"object\") {\r\n return data;\r\n }\r\n let query = [];\r\n for (let param in data) {\r\n if (data.hasOwnProperty(param)) {\r\n if (data[param] === null) {\r\n continue; //null数据不提交\r\n }\r\n if (typeof data[param] === \"object\" && data[param].length) {\r\n data[param].forEach((item: any) => {\r\n query.push(encodeURI(param + \"=\" + item));\r\n });\r\n } else if (typeof data[param] === \"object\") {\r\n //todo 不处理子级object、空数组情况\r\n } else {\r\n query.push(encodeURI(param + \"=\" + data[param]));\r\n }\r\n }\r\n }\r\n return query.join(\"&\");\r\n};\r\n\r\n/**\r\n * 可中止的 Fetch 请求\r\n */\r\nexport interface AbortablePromise<T> extends Promise<T> {\r\n abort: () => void;\r\n}\r\n\r\n/**\r\n * 拓展原生 Fetch API 实现可中止的请求,支持超时设置\r\n * @param {string} url - 请求 URL\r\n * @param {RequestInit} [fetchOption={}] - fetch请求选项,包括 method、headers、body 等\r\n * @param {number} [timeout=0] - 超时时间,单位毫秒,0 表示不设置超时\r\n * @returns {AbortablePromise<any>} 返回可中止的 Promise 对象\r\n * @example\r\n * const req = abortableFetch('/api/data');\r\n * req.abort('cancled'); // 中止请求\r\n */\r\nexport const abortableFetch = (url: string, fetchOption: RequestInit = {}, timeout = 0): AbortablePromise<any> => {\r\n const controller = new AbortController();\r\n\r\n let timeoutId: number | null = null;\r\n if (timeout) {\r\n timeoutId = setTimeout(() => controller.abort(), timeout);\r\n }\r\n\r\n const clearTimer = () => {\r\n if (timeoutId !== null) {\r\n clearTimeout(timeoutId);\r\n timeoutId = null;\r\n }\r\n };\r\n\r\n const addAbortMethod = (promise: Promise<any>): AbortablePromise<any> => {\r\n const abortablePromise = promise as AbortablePromise<any>;\r\n\r\n // 保存原始方法\r\n const originalThen = abortablePromise.then.bind(abortablePromise);\r\n const originalCatch = abortablePromise.catch.bind(abortablePromise);\r\n const originalFinally = abortablePromise.finally.bind(abortablePromise);\r\n\r\n // 重写方法,确保返回的 Promise 也具有 abort 方法\r\n abortablePromise.then = function (onfulfilled, onrejected) {\r\n return addAbortMethod(originalThen(onfulfilled, onrejected));\r\n };\r\n\r\n abortablePromise.catch = function (onrejected) {\r\n return addAbortMethod(originalCatch(onrejected));\r\n };\r\n\r\n abortablePromise.finally = function (onfinally) {\r\n return addAbortMethod(originalFinally(onfinally));\r\n };\r\n\r\n // 添加 abort 方法\r\n abortablePromise.abort = (reason?: string) => {\r\n clearTimer();\r\n controller.abort(reason || \"Request aborted by user\");\r\n };\r\n\r\n return abortablePromise;\r\n };\r\n\r\n const fetchPromise = fetch(url, {\r\n ...fetchOption,\r\n signal: controller.signal,\r\n })\r\n .then((res) => {\r\n clearTimer();\r\n return res;\r\n })\r\n .catch((err) => {\r\n clearTimer();\r\n throw err;\r\n });\r\n\r\n return addAbortMethod(fetchPromise);\r\n};\r\n\r\n// 扩展 RequestInit,添加 timeout 和其他自定义属性,timeout 用于设置请求超时时间,其他自定义属性可以直接添加到 headers 中\r\ninterface RequestOption extends RequestInit {\r\n timeout?: number;\r\n [key: string]: any;\r\n}\r\n\r\nconst appendHeader = (key: string, value: any, headers: Headers): void => {\r\n if (value == null) return;\r\n // 将驼峰命名转换为 HTTP 头格式 (例如: ContentType -> content-type)\r\n const headerName = key\r\n .replace(/([A-Z])/g, \"-$1\")\r\n .replace(/^-/, \"\")\r\n .toLowerCase();\r\n headers.set(headerName, String(value));\r\n};\r\n\r\n// 判断属性是否为 RequestInit 的标准属性\r\nconst isRequestInitProp = (key: string): boolean => {\r\n return [\r\n \"method\",\r\n \"headers\",\r\n \"body\",\r\n \"mode\",\r\n \"credentials\",\r\n \"cache\",\r\n \"redirect\",\r\n \"referrer\",\r\n \"referrerPolicy\",\r\n \"integrity\",\r\n \"keepalive\",\r\n \"signal\",\r\n \"window\",\r\n ].includes(key);\r\n};\r\n\r\n/**\r\n * 发送 HTTP 请求\r\n * @param {string} url - 请求 URL\r\n * @param {BodyInit|null} [data=null] - 请求数据,可以是字符串、FormData、URLSearchParams、Blob、ArrayBuffer 等,如果是对象会根据 ContentType 自动转换(例如 application/json 会自动 JSON.stringify)\r\n * @param {RequestOption} option - 请求选项\r\n * @returns {AbortablePromise<Response>} 返回可中止的 Promise\r\n * @example\r\n * request('/api/data', null, {method: 'GET'})\r\n */\r\nexport const request = (url: string, data: BodyInit | null = null, option: RequestOption): AbortablePromise<Response> => {\r\n let { timeout, ...fetchOption } = option;\r\n fetchOption = fetchOption || {};\r\n fetchOption.method = fetchOption.method || \"GET\";\r\n\r\n const IS_GET = fetchOption.method.toUpperCase() === \"GET\";\r\n\r\n const headers = new Headers(fetchOption.headers || {});\r\n\r\n //如果 key 不是RequestInit的属性,则添加到 headers 中\r\n for (let key in fetchOption) {\r\n if (!isRequestInitProp(key)) {\r\n appendHeader(key, fetchOption[key], headers);\r\n }\r\n }\r\n\r\n if (IS_GET && data) {\r\n url = queryReplace(url, typeof data === \"string\" ? queryToObj(data) : data);\r\n data = null;\r\n }\r\n\r\n return abortableFetch(\r\n url,\r\n {\r\n headers,\r\n ...{\r\n body: !IS_GET ? fixData(data, headers.get(\"content-type\") || undefined) : undefined,\r\n },\r\n ...fetchOption,\r\n },\r\n timeout,\r\n ).then((response) => {\r\n if (!response.ok) {\r\n throw new Error(`HTTP error! status: ${response.status}`);\r\n }\r\n return response;\r\n }) as AbortablePromise<Response>;\r\n};\r\n\r\n/**\r\n * 检测值是否为 BodyInit 可接受的类型\r\n * @param {any} value - 要检测的值\r\n * @returns {boolean} 如果是 BodyInit 可接受的类型返回 true,否则返回 false\r\n */\r\nexport const isBodyInit = (value: any): value is BodyInit => {\r\n return (\r\n typeof value === \"string\" ||\r\n value instanceof FormData ||\r\n value instanceof URLSearchParams ||\r\n value instanceof Blob ||\r\n value instanceof ArrayBuffer ||\r\n ArrayBuffer.isView(value)\r\n );\r\n};\r\n\r\nconst fixData = (data: any, contentType?: string) => {\r\n if (isBodyInit(data)) {\r\n return data;\r\n }\r\n if (typeof data !== \"object\") {\r\n return data;\r\n }\r\n switch (contentType?.toLowerCase()) {\r\n case MIME_JSON:\r\n return JSON.stringify(data);\r\n case MIME_FORM:\r\n case MIME_MULTIPART:\r\n default:\r\n return objToQuery(data);\r\n }\r\n};\r\n\r\n/**\r\n * 发送 GET 请求并获取 JSON 响应\r\n * @param {string} url - 请求 URL\r\n * @param {any} [data=null] - 请求数据\r\n * @param {RequestOption} [option={}] - 请求选项\r\n * @returns {Promise<any>} 返回解析后的 JSON 数据\r\n * @example\r\n * getJson('/api/users').then(data => console.log(data))\r\n */\r\nexport const getJson = (url: string, data: any = null, option: RequestOption = {}) => {\r\n return request(url, data, { ...option, ContentType: MIME_JSON, Accept: MIME_JSON }).then((response) => response.json());\r\n};\r\n\r\n/**\r\n * 发送 POST 请求并获取 JSON 响应\r\n * @param {string} url - 请求 URL\r\n * @param {any} [data=null] - 请求数据\r\n * @param {RequestOption} [option={}] - 请求选项\r\n * @returns {Promise<any>} 返回解析后的 JSON 数据\r\n * @example\r\n * postJson('/api/users', {name: 'John'}).then(data => console.log(data))\r\n */\r\nexport const postJson = (url: string, data: any = null, option: RequestOption = {}) => {\r\n return request(url, data, { ...option, method: \"POST\", ContentType: MIME_JSON, Accept: MIME_JSON }).then((response) => response.json());\r\n};\r\n\r\n/**\r\n * 上传文件\r\n * @param {string} url - 请求 URL\r\n * @param {Record<string, File>} fileMap - 文件对象映射\r\n * @param {any} [data=null] - 额外的表单数据\r\n * @param {RequestOption} [option={}] - 请求选项\r\n * @returns {Promise<any>} 返回解析后的 JSON 数据\r\n * @example\r\n * postFiles('/api/upload', {avatar: fileObject})\r\n */\r\nexport const postFiles = (url: string, fileMap: Record<string, File>, data: any = null, option: RequestOption = {}) => {\r\n const formData = new FormData();\r\n Object.keys(fileMap).forEach((key) => {\r\n formData.append(key, fileMap[key], fileMap[key].name);\r\n });\r\n if (data) {\r\n for (let key in data) {\r\n if (data.hasOwnProperty(key)) {\r\n formData.append(key, data[key]);\r\n }\r\n }\r\n }\r\n return request(url, formData, { ...option, method: \"POST\" }).then((response) => response.json());\r\n};\r\n","/**\r\n * 深拷贝对象\r\n * @param obj - 要拷贝的对象\r\n * @returns 拷贝后的新对象\r\n * @example\r\n * deepClone({ a: 1, b: { c: 2 } })\r\n */\r\nexport function deepClone<T>(obj: T): T {\r\n if (obj === null || typeof obj !== \"object\") return obj;\r\n if (obj instanceof Date) return new Date(obj.getTime()) as T;\r\n if (obj instanceof Array) return obj.map((item) => deepClone(item)) as T;\r\n if (obj instanceof Object) {\r\n const clonedObj = {} as T;\r\n for (const key in obj) {\r\n if (obj.hasOwnProperty(key)) {\r\n clonedObj[key] = deepClone(obj[key]);\r\n }\r\n }\r\n return clonedObj;\r\n }\r\n return obj;\r\n}\r\n\r\n/**\r\n * 判断对象是否为空\r\n * @param obj - 要判断的对象\r\n * @returns 是否为空对象\r\n * @example\r\n * isEmptyObject({}) // true\r\n * isEmptyObject({ a: 1 }) // false\r\n */\r\nexport function isEmptyObject(obj: object): boolean {\r\n return Object.keys(obj).length === 0;\r\n}\r\n\r\n/**\r\n * 对象属性名转换(根据映射表重命名属性)\r\n * @param {Record<string, any>} obj - 源对象\r\n * @param {Record<string, string>} mapping - 属性名映射表\r\n * @returns {Record<string, any>} 返回转换后的对象\r\n * @example\r\n * objectKeyMapping({a: 1, b: 2}, {a: 'x'}) // {x: 1, b: 2}\r\n */\r\nexport const objectKeyMapping = (obj: Record<string, any>, mapping: Record<string, string>): Record<string, any> => {\r\n let ret: Record<string, any> = {};\r\n for (let key in obj) {\r\n if (mapping[key] !== undefined) {\r\n ret[mapping[key]] = obj[key];\r\n } else {\r\n ret[key] = obj[key];\r\n }\r\n }\r\n return ret;\r\n};\r\n\r\n/**\r\n * 获取对象指定路径的值\r\n * @param obj - 对象\r\n * @param path - 路径,例如 'a.b.c'\r\n * @param defaultValue - 默认值\r\n * @returns 获取到的值或默认值\r\n * @example\r\n * get({ a: { b: { c: 1 } } }, 'a.b.c') // 1\r\n * get({ a: { b: 1 } }, 'a.b.c', 0) // 0\r\n */\r\nexport function objectGet<T = any>(obj: any, path: string, defaultValue?: T): T {\r\n const keys = path.split(\".\");\r\n let result = obj;\r\n\r\n for (const key of keys) {\r\n if (result === null || result === undefined) {\r\n return defaultValue as T;\r\n }\r\n result = result[key];\r\n }\r\n\r\n return result !== undefined ? result : (defaultValue as T);\r\n}\r\n\r\n/**\r\n * 设置对象指定路径的值\r\n * @param obj - 对象\r\n * @param path - 路径,例如 'a.b.c'\r\n * @param value - 要设置的值\r\n * @example\r\n * set({}, 'a.b.c', 1) // { a: { b: { c: 1 } } }\r\n */\r\nexport function objectSet(obj: any, path: string, value: any): void {\r\n const keys = path.split(\".\");\r\n const lastKey = keys.pop()!;\r\n let current = obj;\r\n\r\n for (const key of keys) {\r\n if (!(key in current) || typeof current[key] !== \"object\") {\r\n current[key] = {};\r\n }\r\n current = current[key];\r\n }\r\n\r\n current[lastKey] = value;\r\n}\r\n\r\n/**\r\n * 合并对象\r\n * @param target - 目标对象\r\n * @param sources - 源对象\r\n * @returns 合并后的对象\r\n * @example\r\n * merge({ a: 1 }, { b: 2 }, { c: 3 }) // { a: 1, b: 2, c: 3 }\r\n */\r\nexport function objectMerge<T extends object>(target: T, ...sources: Partial<T>[]): T {\r\n for (const source of sources) {\r\n for (const key in source) {\r\n if (source.hasOwnProperty(key)) {\r\n const sourceValue = source[key];\r\n const targetValue = (target as any)[key];\r\n\r\n if (\r\n sourceValue &&\r\n typeof sourceValue === \"object\" &&\r\n !Array.isArray(sourceValue) &&\r\n targetValue &&\r\n typeof targetValue === \"object\" &&\r\n !Array.isArray(targetValue)\r\n ) {\r\n (target as any)[key] = objectMerge(targetValue, sourceValue);\r\n } else {\r\n (target as any)[key] = sourceValue;\r\n }\r\n }\r\n }\r\n }\r\n return target;\r\n}\r\n\r\n/**\r\n * 清理对象中的 null 值\r\n * @param {any} obj - 要清理的对象\r\n * @param {boolean} [recursive=false] - 是否递归清理子对象\r\n * @returns {any} 返回清理后的对象\r\n * @example\r\n * cleanNull({a: 1, b: null, c: {d: null}}, true) // {a: 1, c: {}}\r\n */\r\nexport const cleanNull = (obj: any, recursive = false) => {\r\n for (const key in obj) {\r\n if (obj[key] === null) {\r\n delete obj[key];\r\n } else if (recursive && typeof obj[key] === \"object\") {\r\n cleanNull(obj[key], true);\r\n }\r\n }\r\n return obj;\r\n};\r\n","export const YEAR_NOW = new Date().getFullYear();\r\nexport const MONTH_NOW = new Date().getMonth() + 1;\r\nexport const DATE_NOW = new Date().getDate();\r\n\r\nexport const ONE_MINUTE = 60 * 1000;\r\nexport const ONE_HOUR = 60 * 60 * 1000;\r\nexport const ONE_DAY = 24 * 60 * 60 * 1000;\r\nexport const ONE_WEEK = 7 * ONE_DAY;\r\nexport const ONE_MONTH30 = 30 * ONE_DAY;\r\nexport const ONE_MONTH31 = 31 * ONE_DAY;\r\nexport const ONE_YEAR365 = 365 * ONE_DAY;\r\nexport const ONE_YEAR366 = 366 * ONE_DAY;\r\n\r\nexport const DAY_SUNDAY = 0;\r\nexport const DAY_MONDAY = 1;\r\nexport const DAY_TUESDAY = 2;\r\nexport const DAY_WEDNESDAY = 3;\r\nexport const DAY_THURSDAY = 4;\r\nexport const DAY_FRIDAY = 5;\r\nexport const DAY_SATURDAY = 6;\r\n\r\n// 星期和月份的常量定义\r\nconst WEEK_DAY_NAMES_EN = [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"];\r\nconst WEEK_DAY_NAMES_SHORT_EN = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\r\n\r\nconst MONTH_NAMES_EN = [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"];\r\nconst MONTH_NAMES_SHORT_EN = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"];\r\n\r\nexport const MONTH_NAMES_CN = [\"一月\", \"二月\", \"三月\", \"四月\", \"五月\", \"六月\", \"七月\", \"八月\", \"九月\", \"十月\", \"十一月\", \"十二月\"];\r\nexport const MONTH_NAMES_SHORT_CN = [\"1月\", \"2月\", \"3月\", \"4月\", \"5月\", \"6月\", \"7月\", \"8月\", \"9月\", \"10月\", \"11月\", \"12月\"];\r\n\r\nexport const WEEK_DAY_NAMES_SHORT_CN = [\"日\", \"一\", \"二\", \"三\", \"四\", \"五\", \"六\"];\r\nexport const WEEK_DAY_NAMES_CN = [\"星期日\", \"星期一\", \"星期二\", \"星期三\", \"星期四\", \"星期五\", \"星期六\"];\r\n\r\n/**\r\n * 倒计时函数(该方法采用 setTimeout 方式,不够精准)\r\n * @param {number} timeout - 倒计时总秒数\r\n * @param {Function} [tickFunc] - 每秒回调函数,接收剩余秒数作为参数\r\n * @param {Function} [onFinish] - 倒计时结束回调函数\r\n * @returns {void}\r\n * @example\r\n * countDown(10, (sec) => console.log(sec), () => console.log('done'))\r\n */\r\nexport const countDown = (timeout: number, tickFunc?: (timeout: number) => void, onFinish?: () => void) => {\r\n let loop = () => {\r\n tickFunc && tickFunc(timeout);\r\n if (timeout-- > 0) {\r\n setTimeout(loop, 1000);\r\n return;\r\n }\r\n onFinish && onFinish();\r\n };\r\n loop();\r\n};\r\n\r\n/**\r\n * 毫秒转换为“时分秒前”格式\r\n * @param {number} ms - 毫秒数\r\n * @returns {string} 返回格式化后的字符串\r\n * @example\r\n * msToHMS(3661000) // '1小时0分钟1秒前'\r\n */\r\nexport const msToHMS = (ms: number) => {\r\n if (!ms || ms < 10) {\r\n return \"刚刚\";\r\n }\r\n ms = Math.floor(ms / 1000); // 转为秒\r\n const h = Math.floor(ms / 3600);\r\n const m = Math.floor((ms % 3600) / 60);\r\n const s = ms % 60;\r\n let str = \"\";\r\n if (h > 0) str += h + \"小时\";\r\n if (m > 0 || h > 0) str += m + \"分钟\";\r\n str += s + \"秒前\";\r\n return str;\r\n};\r\n\r\n/**\r\n * PHP 时间函数映射\r\n * 具体含义可以参考:http://php.net/manual/en/function.date.php\r\n * 或者 php.date.en.md\r\n */\r\nconst PHP_DATE_CHAR_MAP: Record<string, (dateObj: Date) => string | number | boolean> = {\r\n d: (dateObj: Date) => {\r\n let d = dateObj.getDate();\r\n return (d < 10 ? \"0\" : \"\") + d;\r\n },\r\n D: (dateObj: Date) => {\r\n return WEEK_DAY_NAMES_SHORT_EN[dateObj.getDay()];\r\n },\r\n j: (dateObj: Date) => {\r\n return dateObj.getDate();\r\n },\r\n l: (dateObj: Date) => {\r\n return WEEK_DAY_NAMES_EN[dateObj.getDay()];\r\n },\r\n N: (dateObj: Date) => {\r\n let N = dateObj.getDay();\r\n return N === 0 ? 7 : N;\r\n },\r\n S: (dateObj: Date) => {\r\n let S = dateObj.getDate();\r\n return S % 10 === 1 && S !== 11 ? \"st\" : S % 10 === 2 && S !== 12 ? \"nd\" : S % 10 === 3 && S !== 13 ? \"rd\" : \"th\";\r\n },\r\n w: (dateObj: Date) => {\r\n return dateObj.getDay();\r\n },\r\n z: (dateObj: Date) => {\r\n let d = new Date(dateObj.getFullYear(), 0, 1);\r\n return Math.ceil((dateObj.getTime() - d.getTime()) / 86400000);\r\n },\r\n // Week\r\n W: (dateObj: Date) => {\r\n let target = new Date(dateObj.valueOf());\r\n let dayNr = (dateObj.getDay() + 6) % 7;\r\n target.setDate(target.getDate() - dayNr + 3);\r\n let firstThursday = target.valueOf();\r\n target.setMonth(0, 1);\r\n if (target.getDay() !== 4) {\r\n target.setMonth(0, 1 + ((4 - target.getDay() + 7) % 7));\r\n }\r\n let retVal = 1 + Math.ceil((firstThursday - target.getTime()) / 604800000);\r\n\r\n return retVal < 10 ? \"0\" + retVal : retVal;\r\n },\r\n // Month\r\n F: (dateObj: Date) => {\r\n return MONTH_NAMES_EN[dateObj.getMonth()];\r\n },\r\n m: (dateObj: Date) => {\r\n let m = dateObj.getMonth();\r\n return (m < 9 ? \"0\" : \"\") + (m + 1);\r\n },\r\n M: (dateObj: Date) => {\r\n return MONTH_NAMES_SHORT_EN[dateObj.getMonth()];\r\n },\r\n n: (dateObj: Date) => {\r\n return dateObj.getMonth() + 1;\r\n },\r\n t: (dateObj: Date) => {\r\n let year = dateObj.getFullYear();\r\n let nextMonth = dateObj.getMonth() + 1;\r\n if (nextMonth === 12) {\r\n year = year++;\r\n nextMonth = 0;\r\n }\r\n return new Date(year, nextMonth, 0).getDate();\r\n },\r\n // Year\r\n L: (dateObj: Date) => {\r\n let L = dateObj.getFullYear();\r\n return L % 400 === 0 || (L % 100 !== 0 && L % 4 === 0);\r\n },\r\n o: (dateObj: Date) => {\r\n let d = new Date(dateObj.valueOf());\r\n d.setDate(d.getDate() - ((dateObj.getDay() + 6) % 7) + 3);\r\n return d.getFullYear();\r\n },\r\n Y: (dateObj: Date) => {\r\n return dateObj.getFullYear();\r\n },\r\n y: (dateObj: Date) => {\r\n return (\"\" + dateObj.getFullYear()).substr(2);\r\n },\r\n // Time\r\n a: (dateObj: Date) => {\r\n return dateObj.getHours() < 12 ? \"am\" : \"pm\";\r\n },\r\n A: (dateObj: Date) => {\r\n return dateObj.getHours() < 12 ? \"AM\" : \"PM\";\r\n },\r\n B: (dateObj: Date) => {\r\n return Math.floor(((((dateObj.getUTCHours() + 1) % 24) + dateObj.getUTCMinutes() / 60 + dateObj.getUTCSeconds() / 3600) * 1000) / 24);\r\n },\r\n g: (dateObj: Date) => {\r\n return dateObj.getHours() % 12 || 12;\r\n },\r\n G: (dateObj: Date) => {\r\n return dateObj.getHours();\r\n },\r\n h: (dateObj: Date) => {\r\n let h = dateObj.getHours();\r\n return ((h % 12 || 12) < 10 ? \"0\" : \"\") + (h % 12 || 12);\r\n },\r\n H: (dateObj: Date) => {\r\n let H = dateObj.getHours();\r\n return (H < 10 ? \"0\" : \"\") + H;\r\n },\r\n i: (dateObj: Date) => {\r\n let i = dateObj.getMinutes();\r\n return (i < 10 ? \"0\" : \"\") + i;\r\n },\r\n s: (dateObj: Date) => {\r\n let s = dateObj.getSeconds();\r\n return (s < 10 ? \"0\" : \"\") + s;\r\n },\r\n v: (dateObj: Date) => {\r\n let v = dateObj.getMilliseconds();\r\n return (v < 10 ? \"00\" : v < 100 ? \"0\" : \"\") + v;\r\n },\r\n // Timezone\r\n e: (_dateObj: Date) => {\r\n return Intl.DateTimeFormat().resolvedOptions().timeZone;\r\n },\r\n I: (dateObj: Date) => {\r\n let DST = null;\r\n for (let i = 0; i < 12; ++i) {\r\n let d = new Date(dateObj.getFullYear(), i, 1);\r\n let offset = d.getTimezoneOffset();\r\n\r\n if (DST === null) DST = offset;\r\n else if (offset < DST) {\r\n DST = offset;\r\n break;\r\n } else if (offset > DST) break;\r\n }\r\n return dateObj.getTimezoneOffset() === DST ? 1 : 0;\r\n },\r\n O: (dateObj: Date) => {\r\n let O = dateObj.getTimezoneOffset();\r\n return (\r\n (-O < 0 ? \"-\" : \"+\") +\r\n (Math.abs(O / 60) < 10 ? \"0\" : \"\") +\r\n Math.floor(Math.abs(O / 60)) +\r\n (Math.abs(O % 60) === 0 ? \"00\" : (Math.abs(O % 60) < 10 ? \"0\" : \"\") + Math.abs(O % 60))\r\n );\r\n },\r\n P: (dateObj: Date) => {\r\n let P = dateObj.getTimezoneOffset();\r\n return (\r\n (-P < 0 ? \"-\" : \"+\") +\r\n (Math.abs(P / 60) < 10 ? \"0\" : \"\") +\r\n Math.floor(Math.abs(P / 60)) +\r\n \":\" +\r\n (Math.abs(P % 60) === 0 ? \"00\" : (Math.abs(P % 60) < 10 ? \"0\" : \"\") + Math.abs(P % 60))\r\n );\r\n },\r\n T: (dateObj: Date) => {\r\n let tz = dateObj.toLocaleTimeString(navigator.language, { timeZoneName: \"short\" }).split(\" \");\r\n return tz[tz.length - 1];\r\n },\r\n Z: (dateObj: Date) => {\r\n return -dateObj.getTimezoneOffset() * 60;\r\n },\r\n // Full Date/Time\r\n c: (dateObj: Date) => {\r\n return formatDate(\"Y-m-d\\\\TH:i:sP\", dateObj);\r\n },\r\n r: (dateObj: Date) => {\r\n return dateObj.toString();\r\n },\r\n U: (dateObj: Date) => {\r\n return Math.floor(dateObj.getTime() / 1000);\r\n },\r\n};\r\n\r\n/**\r\n * 格式化日期(以 PHP 方式格式化)\r\n * @param {string} format - 格式化字符串(支持 PHP date 函数的格式)\r\n * @param {Date|number|string|null} [date=null] - 日期,可以是日期对象、毫秒数或者日期字符串,缺省为今天\r\n * @returns {string} 返回格式化后的日期字符串\r\n * @example\r\n * formatDate('Y-m-d H:i:s') // '2024-03-11 15:30:00'\r\n */\r\nexport const formatDate = function (format: string, date: Date | number | string | null = null): string {\r\n let dateObj = null;\r\n if (typeof date === \"object\" && date !== null) {\r\n dateObj = date;\r\n } else {\r\n dateObj = new Date(date || Date.now());\r\n }\r\n return format.replace(/(\\\\?)(.)/g, function (_: string, esc: string, chr: string): string {\r\n return esc === \"\" && PHP_DATE_CHAR_MAP[chr] ? String(PHP_DATE_CHAR_MAP[chr](dateObj)) : chr;\r\n });\r\n};\r\n\r\n/**\r\n * 获取日期所在周数(ISO 8601 标准)\r\n * @param {Date} date - 日期对象\r\n * @returns {number} 返回周数\r\n * @example\r\n * getWeekNumber(new Date('2024-03-11')) // 11\r\n */\r\nexport const getWeekNumber = (date: Date): number => {\r\n return formatDate(\"W\", date) as unknown as number;\r\n}"],"names":["arrayColumn","arr","col_name","data","arrayIndex","val","i","arrayDistinct","tmpMap","item","arrayGroup","by_key","limit","tmp_rst","k","rst","arraySortByKey","obj","result","key","arrayChunk","list","size","len","res","integer","rest","arrayTrimTail","lastNonZeroIndex","capitalize","str","stripSlashes","_s","n1","cutString","eclipse_text","r","m","extract","es_template","params","names","values","camelCase","_","char","kebabCase","truncate","length","suffix","regQuote","utf8Decode","srcStr","t","c2","c3","utf8Encode","getUTF8StrLen","realLength","charCode","DEFAULT_RANDOM_STRING","randomString","sourceStr","codes","rnd","randomWords","count","letterMax","words","possible","possibleVowels","word","strToPascalCase","capitalize_first","idx","TRIM_BOTH","TRIM_LEFT","TRIM_RIGHT","trim","chars","dir","regLeft","regRight","strChunk","ret","BASE64_KEY_STR","base64Decode","text","s","o","u","a","f","base64UrlSafeEncode","Base64Encode","blobToBase64","blob","_blobToBase64","resolve","reject","reader","error","enterFullScreen","element","exitFullScreen","toggleFullScreen","isInFullScreen","detectLanguage","supportedLngs","browserLang","langPrefix","match","lng","isFirefox","setCookie","name","value","days","path","expires","date","getCookie","nameEQ","ca","c","deleteCookie","_guid","guid","prefix","throttle","fn","intervalMiSec","context","args","previous","now","throttleEffect","lastExecuteTime","queuing","remaining","debounce","timeout","isPromise","isJson","json","is_json","isObject","isFunction","isUrl","isJSON","printStack","stack","GOLDEN_RATIO","STAND_DPI","mmToPx","dimension","dpi","mmToTwip","mm","mmToPt","ptToMm","pt","pxToMm","px","num","min","max","between","includeEqual","randomInt","round","precision","multiple","detectedPrecision","numbers","maxPrecision","decimalPart","digitCount","n","hide","dom","findOne","show","remove","el","_el_disabled_class_","disabled","disabledClass","toggleDisabled","enabled","forceEnabled","toDisabled","insertStyleSheet","onHover","onHoverIn","onHoverOut","isHovering","lockElementInteraction","payload","nodeIndex","node","findAll","selector","parent","ns","sel","getNodeXPath","allNodes","seg_list","uniqueIdCount","sib","onDomTreeChange","callback","includeElementChanged","PRO_KEY","watchEl","mutationEffective","option","minInterval","last_queue_time","callback_queueing","obs","keepRectInContainer","objDim","ctnDim","rectAssoc","rect1","rect2","isFocusable","_c","loadCss","file","forceReload","link","loadScript","src","script","getDomDimension","org_visibility","org_display","width","height","styleSheetStr","id","doc","style","rectInLayout","rect","layout","precisionToStep","fixBaseUrl","url","baseUrl","createDomByHtml","html","parentNode","tpl","nodes","getBoundingClientRect","autoFixInvisible","originalVisibility","originalDisplay","overlayRect","buildStyleVars","vars","styles","v","sanitizeFileName","blobToDataUri","e","FILE_B64_CACHE_DATA","urlB64DataCache","b64Data","fileToBase64DataUri","resp","err","downloadFile","uri","fileName","BLOCK_TAGS","PAIR_TAGS","SELF_CLOSING_TAGS","REMOVABLE_TAGS","html2Text","tag","_ms","_tail","_tag","matchReg","replacement","dec","cssSelectorEscape","entityToString","entity","entities","_helper_div","decodeHTMLEntities","buildHtmlHidden","maps","escapeAttr","escapeHtml","tabSize","allowLineBreaker","unescapeHtml","preserveCR","stringToEntity","radix","highlightText","kw","replaceTpl","imgToBase64","img","canvas","ctx","srcToBase64","cache","cached","xhr","base64","safeAdd","x","y","lsw","bitRotateLeft","cnt","md5cmn","q","b","md5ff","d","md5gg","md5hh","md5ii","binlMD5","olda","oldb","oldc","oldd","binl2rstr","input","output","length32","rstr2binl","length8","rstrMD5","rstrHMACMD5","bkey","ipad","opad","hash","rstr2hex","hexTab","str2rstrUTF8","rawMD5","hexMD5","rawHMACMD5","hexHMACMD5","md5","string","raw","MIME_BINARY_DEFAULT","MIME_JSON","MIME_FORM","MIME_MULTIPART","MIME_TEXT","MIME_HTML","MIME_EXTENSION_MAP","queryToObj","query","pair","queryReplace","newQuery","queryString","mergedQuery","newQueryString","objToQuery","param","abortableFetch","fetchOption","controller","timeoutId","clearTimer","addAbortMethod","promise","abortablePromise","originalThen","originalCatch","originalFinally","onfulfilled","onrejected","onfinally","reason","fetchPromise","appendHeader","headers","headerName","isRequestInitProp","request","IS_GET","fixData","response","isBodyInit","contentType","getJson","postJson","postFiles","fileMap","formData","deepClone","clonedObj","isEmptyObject","objectKeyMapping","mapping","objectGet","defaultValue","keys","objectSet","lastKey","current","objectMerge","target","sources","source","sourceValue","targetValue","cleanNull","recursive","YEAR_NOW","MONTH_NOW","DATE_NOW","ONE_MINUTE","ONE_HOUR","ONE_DAY","ONE_WEEK","ONE_MONTH30","ONE_MONTH31","ONE_YEAR365","ONE_YEAR366","DAY_SUNDAY","DAY_MONDAY","DAY_TUESDAY","DAY_WEDNESDAY","DAY_THURSDAY","DAY_FRIDAY","DAY_SATURDAY","WEEK_DAY_NAMES_EN","WEEK_DAY_NAMES_SHORT_EN","MONTH_NAMES_EN","MONTH_NAMES_SHORT_EN","MONTH_NAMES_CN","MONTH_NAMES_SHORT_CN","WEEK_DAY_NAMES_SHORT_CN","WEEK_DAY_NAMES_CN","countDown","tickFunc","onFinish","loop","msToHMS","ms","h","PHP_DATE_CHAR_MAP","dateObj","N","S","dayNr","firstThursday","retVal","year","nextMonth","L","H","_dateObj","DST","offset","O","P","tz","formatDate","format","esc","chr","getWeekNumber"],"mappings":"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"}