ly-utils-lib 1.0.12 → 2.4.0
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.
- package/LICENSE +21 -0
- package/README.md +889 -686
- package/dist/array.cjs +237 -0
- package/dist/array.cjs.map +1 -0
- package/dist/array.d.cts +2 -0
- package/dist/array.d.ts +2 -0
- package/dist/array.js +150 -0
- package/dist/array.js.map +1 -0
- package/dist/crypto.cjs +193 -0
- package/dist/crypto.cjs.map +1 -0
- package/dist/crypto.d.cts +3 -0
- package/dist/crypto.d.ts +3 -0
- package/dist/crypto.js +144 -0
- package/dist/crypto.js.map +1 -0
- package/dist/date.cjs +563 -0
- package/dist/date.cjs.map +1 -0
- package/dist/date.d.cts +2 -0
- package/dist/date.d.ts +2 -0
- package/dist/date.js +451 -0
- package/dist/date.js.map +1 -0
- package/dist/excel.cjs +227 -0
- package/dist/excel.cjs.map +1 -0
- package/dist/excel.d.cts +2 -0
- package/dist/excel.d.ts +2 -0
- package/dist/excel.js +196 -0
- package/dist/excel.js.map +1 -0
- package/dist/index-B80SEVzM.d.cts +382 -0
- package/dist/index-B80SEVzM.d.ts +382 -0
- package/dist/index-Ba1rjTzj.d.cts +299 -0
- package/dist/index-Ba1rjTzj.d.ts +299 -0
- package/dist/index-Bg1ise7y.d.cts +253 -0
- package/dist/index-Bg1ise7y.d.ts +253 -0
- package/dist/index-BoqNpwNa.d.cts +203 -0
- package/dist/index-BoqNpwNa.d.ts +203 -0
- package/dist/index-C0qUnb9Y.d.cts +533 -0
- package/dist/index-C0qUnb9Y.d.ts +533 -0
- package/dist/index-Cy-mb5v_.d.cts +262 -0
- package/dist/index-Cy-mb5v_.d.ts +262 -0
- package/dist/index-D1f9Sym2.d.cts +148 -0
- package/dist/index-D1f9Sym2.d.ts +148 -0
- package/dist/index-Dan5oF-5.d.cts +213 -0
- package/dist/index-Dan5oF-5.d.ts +213 -0
- package/dist/index-XABfrs7z.d.cts +596 -0
- package/dist/index-XABfrs7z.d.ts +596 -0
- package/dist/index-YXWfKCK7.d.cts +109 -0
- package/dist/index-YXWfKCK7.d.ts +109 -0
- package/dist/index.cjs +3355 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +21 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +3294 -0
- package/dist/index.js.map +1 -0
- package/dist/map.cjs +839 -0
- package/dist/map.cjs.map +1 -0
- package/dist/map.d.cts +6 -0
- package/dist/map.d.ts +6 -0
- package/dist/map.js +811 -0
- package/dist/map.js.map +1 -0
- package/dist/object.cjs +316 -0
- package/dist/object.cjs.map +1 -0
- package/dist/object.d.cts +2 -0
- package/dist/object.d.ts +2 -0
- package/dist/object.js +247 -0
- package/dist/object.js.map +1 -0
- package/dist/pdf.cjs +197 -0
- package/dist/pdf.cjs.map +1 -0
- package/dist/pdf.d.cts +3 -0
- package/dist/pdf.d.ts +3 -0
- package/dist/pdf.js +173 -0
- package/dist/pdf.js.map +1 -0
- package/dist/storage.cjs +255 -0
- package/dist/storage.cjs.map +1 -0
- package/dist/storage.d.cts +1 -0
- package/dist/storage.d.ts +1 -0
- package/dist/storage.js +226 -0
- package/dist/storage.js.map +1 -0
- package/dist/string.cjs +232 -0
- package/dist/string.cjs.map +1 -0
- package/dist/string.d.cts +2 -0
- package/dist/string.d.ts +2 -0
- package/dist/string.js +170 -0
- package/dist/string.js.map +1 -0
- package/dist/utils.cjs +429 -0
- package/dist/utils.cjs.map +1 -0
- package/dist/utils.d.cts +2 -0
- package/dist/utils.d.ts +2 -0
- package/dist/utils.js +371 -0
- package/dist/utils.js.map +1 -0
- package/package.json +159 -33
- package/dist/ly-utils-lib.cjs.js +0 -115
- package/dist/ly-utils-lib.cjs.js.map +0 -1
- package/dist/ly-utils-lib.es.js +0 -58589
- package/dist/ly-utils-lib.es.js.map +0 -1
- package/dist/ly-utils-lib.umd.js +0 -115
- package/dist/ly-utils-lib.umd.js.map +0 -1
- package/dist/types/index.d.ts +0 -15
- package/dist/types/utils/esToolkit.d.ts +0 -2
- package/dist/types/utils/ol.d.ts +0 -175
- package/dist/types/utils/router.d.ts +0 -10
- package/dist/types/utils/storage.d.ts +0 -42
- package/dist/types/utils/time.d.ts +0 -66
- package/dist/types/utils/tool.d.ts +0 -80
- package/dist/vite.svg +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/modules/utils/index.ts"],"names":["min","max"],"mappings":"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","file":"utils.cjs","sourcesContent":["/**\n * 通用工具模块\n * 提供颜色转换、图片处理、文件下载、类型判断、数组/对象操作等通用功能\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n// clone 函数的类型断言使用 any 是合理的\n\nimport { debounce, throttle, type DebouncedFunction, type ThrottledFunction } from 'es-toolkit'\n\n// ==================== 防抖与节流 ====================\n\n/**\n * 防抖函数(使用 es-toolkit)\n * @param fn 要防抖的函数\n * @param wait 等待时间(毫秒)\n * @returns 防抖后的函数\n */\nexport { debounce, type DebouncedFunction }\n\n/**\n * 节流函数(使用 es-toolkit)\n * @param fn 要节流的函数\n * @param wait 等待时间(毫秒)\n * @returns 节流后的函数\n */\nexport { throttle, type ThrottledFunction }\n\n// ==================== 对象深操作 ====================\n\n/**\n * 深度克隆对象\n * @param obj 要克隆的对象\n * @returns 克隆后的对象\n */\nexport const clone = <T>(obj: T): T => {\n if (obj === null || typeof obj !== 'object') {\n return obj\n }\n if (obj instanceof Date) {\n return new Date(obj.getTime()) as T\n }\n if (obj instanceof Array) {\n return obj.map((item) => clone(item)) as T\n }\n if (obj instanceof Object) {\n const copy = {} as T\n Object.keys(obj).forEach((key) => {\n ;(copy as any)[key] = clone((obj as any)[key])\n })\n return copy\n }\n return obj\n}\n\n/**\n * 深度比较两个对象是否相等\n * @param a 对象 a\n * @param b 对象 b\n * @returns 是否相等\n */\nexport const isEqual = (a: any, b: any): boolean => {\n if (a === b) return true\n if (a === null || b === null) return false\n if (typeof a !== typeof b) return false\n\n if (typeof a !== 'object') return a === b\n if (Array.isArray(a) !== Array.isArray(b)) return false\n\n if (Array.isArray(a)) {\n if (a.length !== b.length) return false\n for (let i = 0; i < a.length; i++) {\n if (!isEqual(a[i], b[i])) return false\n }\n return true\n }\n\n const keysA = Object.keys(a)\n const keysB = Object.keys(b)\n if (keysA.length !== keysB.length) return false\n\n for (const key of keysA) {\n if (!keysB.includes(key)) return false\n if (!isEqual(a[key], b[key])) return false\n }\n return true\n}\n\n/**\n * 深度合并对象\n * @param objects 要合并的对象\n * @returns 合并后的对象\n */\nexport const deepMerge = <T extends Record<string, any>>(...objects: Partial<T>[]): T => {\n const result = {} as T\n objects.forEach((obj) => {\n if (isObject(obj)) {\n Object.keys(obj).forEach((key) => {\n const value = obj[key]\n if (isObject(value) && isObject(result[key])) {\n ;(result as any)[key] = deepMerge(result[key], value)\n } else {\n ;(result as any)[key] = clone(value)\n }\n })\n }\n })\n return result\n}\n\n/**\n * 获取对象的路径值\n * @param obj 对象\n * @param path 路径(例如:'user.name')\n * @returns 路径对应的值\n */\nexport const get = (obj: any, path: string): any => {\n return path.split('.').reduce((acc, key) => acc?.[key], obj)\n}\n\n/**\n * 设置对象的路径值\n * @param obj 对象\n * @param path 路径(例如:'user.name')\n * @param value 要设置的值\n */\nexport const set = (obj: any, path: string, value: any): void => {\n const keys = path.split('.')\n const lastKey = keys.pop()!\n const target = keys.reduce((acc, key) => {\n if (!acc[key]) acc[key] = {}\n return acc[key]\n }, obj)\n target[lastKey] = value\n}\n\n/**\n * 省略对象中的某些属性\n * @param obj 对象\n * @param keys 要省略的键\n * @returns 省略后的对象\n */\nexport const omit = <T extends Record<string, any>, K extends keyof T>(\n obj: T,\n keys: K[]\n): Omit<T, K> => {\n const result = { ...obj }\n keys.forEach((key) => delete result[key])\n return result\n}\n\n/**\n * 选择对象中的某些属性\n * @param obj 对象\n * @param keys 要选择的键\n * @returns 选择后的对象\n */\nexport const pick = <T extends Record<string, any>, K extends keyof T>(\n obj: T,\n keys: K[]\n): Pick<T, K> => {\n const result = {} as Pick<T, K>\n keys.forEach((key) => {\n if (key in obj) {\n result[key] = obj[key]\n }\n })\n return result\n}\n\n// ==================== 类型判断 ====================\n\n/**\n * 判断是否为对象\n * @param value 要判断的值\n * @returns 是否为对象\n */\nexport const isObject = (value: any): value is Record<string, any> => {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n\n/**\n * 判断是否为数组\n * @param value 要判断的值\n * @returns 是否为数组\n */\nexport const isArray = (value: any): value is any[] => {\n return Array.isArray(value)\n}\n\n/**\n * 判断是否为字符串\n * @param value 要判断的值\n * @returns 是否为字符串\n */\nexport const isString = (value: any): value is string => {\n return typeof value === 'string'\n}\n\n/**\n * 判断是否为数字\n * @param value 要判断的值\n * @returns 是否为数字\n */\nexport const isNumber = (value: any): value is number => {\n return typeof value === 'number' && !isNaN(value)\n}\n\n/**\n * 判断是否为布尔值\n * @param value 要判断的值\n * @returns 是否为布尔值\n */\nexport const isBoolean = (value: any): value is boolean => {\n return typeof value === 'boolean'\n}\n\n/**\n * 判断是否为函数\n * @param value 要判断的值\n * @returns 是否为函数\n */\nexport const isFunction = (value: any): value is Function => {\n return typeof value === 'function'\n}\n\n/**\n * 判断是否为空值\n * @param value 要判断的值\n * @returns 是否为空\n */\nexport const isEmpty = (value: any): boolean => {\n if (value === null || value === undefined) return true\n if (isString(value) || Array.isArray(value)) return value.length === 0\n if (isObject(value)) return Object.keys(value).length === 0\n return false\n}\n\n// ==================== 数组操作 ====================\n\n/**\n * 数组去重\n * @param array 数组\n * @returns 去重后的数组\n */\nexport const uniq = <T>(array: T[]): T[] => {\n return [...new Set(array)]\n}\n\n/**\n * 数组排序\n * @param array 数组\n * @param key 排序键\n * @returns 排序后的数组\n */\nexport const sortBy = <T>(array: T[], key: keyof T | ((item: T) => any)): T[] => {\n const sortFn = typeof key === 'function' ? key : (item: T) => item[key]\n return [...array].sort((a, b) => {\n const valueA = sortFn(a)\n const valueB = sortFn(b)\n if (valueA < valueB) return -1\n if (valueA > valueB) return 1\n return 0\n })\n}\n\n/**\n * 数组分块\n * @param array 数组\n * @param size 分块大小\n * @returns 分块后的二维数组\n */\nexport const chunk = <T>(array: T[], size: number): T[][] => {\n const result: T[][] = []\n for (let i = 0; i < array.length; i += size) {\n result.push(array.slice(i, i + size))\n }\n return result\n}\n\n/**\n * 数组分组\n * @param array 数组\n * @param key 分组键\n * @returns 分组后的对象\n */\nexport const groupBy = <T>(\n array: T[],\n key: keyof T | ((item: T) => string)\n): Record<string, T[]> => {\n const groupFn = typeof key === 'function' ? key : (item: T) => String(item[key])\n return array.reduce(\n (result, item) => {\n const groupKey = groupFn(item)\n if (!result[groupKey]) {\n result[groupKey] = []\n }\n result[groupKey].push(item)\n return result\n },\n {} as Record<string, T[]>\n )\n}\n\n/**\n * 数组求和\n * @param array 数组\n * @returns 总和\n */\nexport const sum = (array: number[]): number => {\n return array.reduce((acc, num) => acc + num, 0)\n}\n\n/**\n * 数组平均值\n * @param array 数组\n * @returns 平均值\n */\nexport const avg = (array: number[]): number => {\n return array.length > 0 ? sum(array) / array.length : 0\n}\n\n/**\n * 数组最大值\n * @param array 数组\n * @returns 最大值\n */\nexport const max = (array: number[]): number => {\n return Math.max(...array)\n}\n\n/**\n * 数组最小值\n * @param array 数组\n * @returns 最小值\n */\nexport const min = (array: number[]): number => {\n return Math.min(...array)\n}\n\n// ==================== 字符串转换 ====================\n\n/**\n * 驼峰转下划线\n * @param str 字符串\n * @returns 转换后的字符串\n */\nexport const camelToSnake = (str: string): string => {\n return str.replace(/[A-Z]/g, (match) => `_${match.toLowerCase()}`)\n}\n\n/**\n * 下划线转驼峰\n * @param str 字符串\n * @returns 转换后的字符串\n */\nexport const snakeToCamel = (str: string): string => {\n return str.replace(/_([a-z])/g, (_, match) => match.toUpperCase())\n}\n\n/**\n * 首字母大写\n * @param str 字符串\n * @returns 转换后的字符串\n */\nexport const capitalize = (str: string): string => {\n return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase()\n}\n\n/**\n * 截断字符串\n * @param str 字符串\n * @param length 最大长度\n * @param suffix 后缀\n * @returns 截断后的字符串\n */\nexport const truncate = (str: string, length: number = 100, suffix: string = '...'): string => {\n if (str.length <= length) return str\n return `${str.slice(0, length)}${suffix}`\n}\n\n// ==================== 格式化函数 ====================\n\n/**\n * 格式化文件大小\n * @param bytes 字节数\n * @returns 格式化后的字符串\n */\nexport const formatFileSize = (bytes: number): string => {\n if (bytes === 0) return '0 B'\n const k = 1024\n const sizes = ['B', 'KB', 'MB', 'GB', 'TB']\n const i = Math.floor(Math.log(bytes) / Math.log(k))\n return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}`\n}\n\n/**\n * 格式化数字(千分位)\n * @param num 数字\n * @returns 格式化后的字符串\n */\nexport const formatNumber = (num: number): string => {\n return num.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',')\n}\n\n// ==================== 验证函数 ====================\n\n/**\n * 检查是否为有效的 URL\n * @param str 字符串\n * @returns 是否为有效 URL\n */\nexport const isValidUrl = (str: string): boolean => {\n try {\n new URL(str)\n return true\n } catch {\n return false\n }\n}\n\n/**\n * 检查是否为有效的邮箱\n * @param email 邮箱地址\n * @returns 是否为有效邮箱\n */\nexport const isValidEmail = (email: string): boolean => {\n const regex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\n return regex.test(email)\n}\n\n/**\n * 检查是否为有效的手机号(中国)\n * @param phone 手机号\n * @returns 是否为有效手机号\n */\nexport const isValidPhone = (phone: string): boolean => {\n const regex = /^1[3-9]\\d{9}$/\n return regex.test(phone)\n}\n\n// ==================== 其他工具函数 ====================\n\n/**\n * 生成范围内的随机整数\n * @param min 最小值\n * @param max 最大值\n * @returns 随机整数\n */\nexport const randomInt = (min: number, max: number): number => {\n return Math.floor(Math.random() * (max - min + 1)) + min\n}\n\n/**\n * 生成唯一 ID\n * @param prefix 前缀\n * @returns 唯一 ID\n */\nexport const uniqueId = (prefix: string = ''): string => {\n return `${prefix}${Date.now()}-${Math.random().toString(36).substr(2, 9)}`\n}\n\n/**\n * 延迟执行\n * @param ms 延迟时间(毫秒)\n * @returns Promise\n */\nexport const delay = (ms: number): Promise<void> => {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\n/**\n * 重试函数\n * @param fn 要执行的函数\n * @param retries 重试次数\n * @param delayMs 重试延迟\n * @returns Promise\n */\nexport const retry = async <T>(\n fn: () => Promise<T>,\n retries: number = 3,\n delayMs: number = 1000\n): Promise<T> => {\n try {\n return await fn()\n } catch (error) {\n if (retries <= 0) {\n throw error\n }\n await delay(delayMs)\n return retry(fn, retries - 1, delayMs)\n }\n}\n\n// ==================== 颜色转换 ====================\n\n/**\n * Hex 颜色转 RGB 颜色\n * @param str Hex 颜色(如 #FFFFFF 或 FFFFFF)\n * @returns RGB 颜色数组 [r, g, b]\n */\nexport const hexToRgb = (str: string): number[] | null => {\n const hexRegex = /^#?([0-9A-Fa-f]{6})$/\n if (!hexRegex.test(str)) {\n return null\n }\n\n const hex = str.replace('#', '')\n const r = parseInt(hex.substring(0, 2), 16)\n const g = parseInt(hex.substring(2, 4), 16)\n const b = parseInt(hex.substring(4, 6), 16)\n\n return [r, g, b]\n}\n\n/**\n * Hex 颜色转 RGB 字符串\n * @param str Hex 颜色(如 #FFFFFF 或 FFFFFF)\n * @returns RGB 字符串(如 rgb(255, 255, 255))\n */\nexport const hexToRgbString = (str: string): string | null => {\n const rgb = hexToRgb(str)\n if (!rgb) {\n return null\n }\n return `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`\n}\n\n/**\n * RGB 颜色转 Hex 颜色\n * @param r 红色值 (0-255)\n * @param g 绿色值 (0-255)\n * @param b 蓝色值 (0-255)\n * @returns Hex 颜色字符串(如 #FFFFFF)\n */\nexport const rgbToHex = (r: number, g: number, b: number): string | null => {\n const numRegex = /^\\d{1,3}$/\n if (!numRegex.test(r.toString()) || !numRegex.test(g.toString()) || !numRegex.test(b.toString())) {\n return null\n }\n\n if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) {\n return null\n }\n\n const toHex = (num: number): string => {\n const hex = num.toString(16)\n return hex.length === 1 ? `0${hex}` : hex\n }\n\n return `#${toHex(r)}${toHex(g)}${toHex(b)}`\n}\n\n/**\n * RGB 颜色转 Hex 颜色(数组版本)\n * @param rgb RGB 数组 [r, g, b]\n * @returns Hex 颜色字符串(如 #FFFFFF)\n */\nexport const rgbArrayToHex = (rgb: number[]): string | null => {\n if (rgb.length !== 3) {\n return null\n }\n return rgbToHex(rgb[0], rgb[1], rgb[2])\n}\n\n/**\n * 变浅颜色值\n * @param color Hex 颜色(如 #FFFFFF 或 FFFFFF)\n * @param alpha 透明度因子 (0-1),值越大颜色越浅\n * @returns 变浅后的 Hex 颜色\n */\nexport const getLightColor = (color: string, alpha: number): string | null => {\n const rgb = hexToRgb(color)\n if (!rgb) {\n return null\n }\n\n const [r, g, b] = rgb\n const newR = Math.floor((255 - r) * alpha + r)\n const newG = Math.floor((255 - g) * alpha + g)\n const newB = Math.floor((255 - b) * alpha + b)\n\n return rgbToHex(newR, newG, newB)\n}\n\n/**\n * 变深颜色值\n * @param color Hex 颜色(如 #FFFFFF 或 FFFFFF)\n * @param alpha 暗化因子 (0-1),值越大颜色越深\n * @returns 变深后的 Hex 颜色\n */\nexport const getDarkColor = (color: string, alpha: number): string | null => {\n const rgb = hexToRgb(color)\n if (!rgb) {\n return null\n }\n\n const [r, g, b] = rgb\n const newR = Math.floor(r * (1 - alpha))\n const newG = Math.floor(g * (1 - alpha))\n const newB = Math.floor(b * (1 - alpha))\n\n return rgbToHex(newR, newG, newB)\n}\n\n// ==================== 图片处理 ====================\n\n/**\n * 图片转 Base64\n * @param url 图片 URL\n * @param type 图片类型(默认 image/png)\n * @returns Base64 字符串\n */\nexport const imgToBase64 = (url: string, type: 'image/jpeg' | 'image/png' = 'image/png'): Promise<string> => {\n return new Promise((resolve, reject) => {\n const image = new Image()\n image.crossOrigin = 'anonymous'\n\n image.onload = () => {\n const canvas = document.createElement('canvas')\n canvas.width = image.naturalWidth\n canvas.height = image.naturalHeight\n\n const ctx = canvas.getContext('2d')\n if (!ctx) {\n reject(new Error('Failed to get canvas context'))\n return\n }\n\n ctx.drawImage(image, 0, 0)\n const base64 = canvas.toDataURL(type)\n resolve(base64)\n }\n\n image.onerror = (err) => {\n reject(new Error(`Failed to load image: ${String(err)}`))\n }\n\n image.src = url\n })\n}\n\n/**\n * Base64 转 File 对象\n * @param base64 Base64 字符串\n * @param fileName 文件名\n * @param mimeType MIME 类型(默认 image/jpeg)\n * @returns File 对象\n */\nexport const base64toFile = (\n base64: string,\n fileName: string,\n mimeType: string = 'image/jpeg'\n): File => {\n const dataArr = base64.split(',')\n const byteString = atob(dataArr[1])\n const u8Arr = new Uint8Array(byteString.length)\n\n for (let i = 0; i < byteString.length; i++) {\n u8Arr[i] = byteString.charCodeAt(i)\n }\n\n return new File([u8Arr], fileName, { type: mimeType })\n}\n\n/**\n * Base64 转 Blob 对象\n * @param base64 Base64 字符串\n * @param mimeType MIME 类型\n * @returns Blob 对象\n */\nexport const base64toBlob = (base64: string, mimeType: string = 'image/jpeg'): Blob => {\n const dataArr = base64.split(',')\n const byteString = atob(dataArr[1])\n const u8Arr = new Uint8Array(byteString.length)\n\n for (let i = 0; i < byteString.length; i++) {\n u8Arr[i] = byteString.charCodeAt(i)\n }\n\n return new Blob([u8Arr], { type: mimeType })\n}\n\n// ==================== 文件下载 ====================\n\n/**\n * 下载文件\n * @param url 文件 URL 或 Data URL\n * @param fileName 文件名\n * @param target 是否在新标签页打开(默认 false)\n */\nexport const downloadFile = (url: string, fileName: string = '文件', target = false): void => {\n const link = document.createElement('a')\n link.style.display = 'none'\n link.href = url\n\n if (target) {\n link.target = '_blank'\n } else {\n link.setAttribute('download', fileName)\n }\n\n document.body.appendChild(link)\n link.click()\n document.body.removeChild(link)\n}\n\n/**\n * 下载 Blob 文件\n * @param blob Blob 对象\n * @param fileName 文件名\n */\nexport const downloadBlob = (blob: Blob, fileName: string): void => {\n const url = URL.createObjectURL(blob)\n downloadFile(url, fileName)\n URL.revokeObjectURL(url)\n}\n\n/**\n * 下载 Base64 文件\n * @param base64 Base64 字符串\n * @param fileName 文件名\n * @param mimeType MIME 类型\n */\nexport const downloadBase64 = (base64: string, fileName: string, mimeType: string = 'image/jpeg'): void => {\n const blob = base64toBlob(base64, mimeType)\n downloadBlob(blob, fileName)\n}\n\n// ==================== 剪贴板操作 ====================\n\n/**\n * 复制文本到剪贴板\n * @param text 要复制的文本\n * @returns 是否成功\n */\nexport const copyToClipboard = async (text: string): Promise<boolean> => {\n try {\n if (navigator.clipboard && navigator.clipboard.writeText) {\n await navigator.clipboard.writeText(text)\n return true\n }\n\n // 降级方案\n const textarea = document.createElement('textarea')\n textarea.value = text\n textarea.style.position = 'fixed'\n textarea.style.opacity = '0'\n document.body.appendChild(textarea)\n textarea.select()\n const success = document.execCommand('copy')\n document.body.removeChild(textarea)\n return success\n } catch {\n return false\n }\n}\n\n/**\n * 从剪贴板读取文本\n * @returns 剪贴板文本\n */\nexport const readFromClipboard = async (): Promise<string> => {\n try {\n if (navigator.clipboard && navigator.clipboard.readText) {\n return await navigator.clipboard.readText()\n }\n\n // 降级方案(需要用户权限)\n return ''\n } catch {\n return ''\n }\n}\n"]}
|
package/dist/utils.d.cts
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export { DebouncedFunction, ThrottledFunction, debounce, throttle } from 'es-toolkit';
|
|
2
|
+
export { a as avg, b as base64toBlob, c as base64toFile, d as camelToSnake, e as capitalize, f as chunk, g as clone, h as copyToClipboard, j as deepMerge, k as delay, l as downloadBase64, m as downloadBlob, n as downloadFile, o as formatFileSize, p as formatNumber, q as get, r as getDarkColor, s as getLightColor, t as groupBy, u as hexToRgb, v as hexToRgbString, w as imgToBase64, x as isArray, y as isBoolean, z as isEmpty, A as isEqual, B as isFunction, C as isNumber, D as isObject, E as isString, F as isValidEmail, G as isValidPhone, H as isValidUrl, I as max, J as min, K as omit, L as pick, M as randomInt, N as readFromClipboard, O as retry, P as rgbArrayToHex, Q as rgbToHex, R as set, S as snakeToCamel, T as sortBy, U as sum, V as truncate, W as uniq, X as uniqueId } from './index-B80SEVzM.cjs';
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export { DebouncedFunction, ThrottledFunction, debounce, throttle } from 'es-toolkit';
|
|
2
|
+
export { a as avg, b as base64toBlob, c as base64toFile, d as camelToSnake, e as capitalize, f as chunk, g as clone, h as copyToClipboard, j as deepMerge, k as delay, l as downloadBase64, m as downloadBlob, n as downloadFile, o as formatFileSize, p as formatNumber, q as get, r as getDarkColor, s as getLightColor, t as groupBy, u as hexToRgb, v as hexToRgbString, w as imgToBase64, x as isArray, y as isBoolean, z as isEmpty, A as isEqual, B as isFunction, C as isNumber, D as isObject, E as isString, F as isValidEmail, G as isValidPhone, H as isValidUrl, I as max, J as min, K as omit, L as pick, M as randomInt, N as readFromClipboard, O as retry, P as rgbArrayToHex, Q as rgbToHex, R as set, S as snakeToCamel, T as sortBy, U as sum, V as truncate, W as uniq, X as uniqueId } from './index-B80SEVzM.js';
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
export { debounce, throttle } from 'es-toolkit';
|
|
2
|
+
|
|
3
|
+
// src/modules/utils/index.ts
|
|
4
|
+
var clone = (obj) => {
|
|
5
|
+
if (obj === null || typeof obj !== "object") {
|
|
6
|
+
return obj;
|
|
7
|
+
}
|
|
8
|
+
if (obj instanceof Date) {
|
|
9
|
+
return new Date(obj.getTime());
|
|
10
|
+
}
|
|
11
|
+
if (obj instanceof Array) {
|
|
12
|
+
return obj.map((item) => clone(item));
|
|
13
|
+
}
|
|
14
|
+
if (obj instanceof Object) {
|
|
15
|
+
const copy = {};
|
|
16
|
+
Object.keys(obj).forEach((key) => {
|
|
17
|
+
copy[key] = clone(obj[key]);
|
|
18
|
+
});
|
|
19
|
+
return copy;
|
|
20
|
+
}
|
|
21
|
+
return obj;
|
|
22
|
+
};
|
|
23
|
+
var isEqual = (a, b) => {
|
|
24
|
+
if (a === b) return true;
|
|
25
|
+
if (a === null || b === null) return false;
|
|
26
|
+
if (typeof a !== typeof b) return false;
|
|
27
|
+
if (typeof a !== "object") return a === b;
|
|
28
|
+
if (Array.isArray(a) !== Array.isArray(b)) return false;
|
|
29
|
+
if (Array.isArray(a)) {
|
|
30
|
+
if (a.length !== b.length) return false;
|
|
31
|
+
for (let i = 0; i < a.length; i++) {
|
|
32
|
+
if (!isEqual(a[i], b[i])) return false;
|
|
33
|
+
}
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
const keysA = Object.keys(a);
|
|
37
|
+
const keysB = Object.keys(b);
|
|
38
|
+
if (keysA.length !== keysB.length) return false;
|
|
39
|
+
for (const key of keysA) {
|
|
40
|
+
if (!keysB.includes(key)) return false;
|
|
41
|
+
if (!isEqual(a[key], b[key])) return false;
|
|
42
|
+
}
|
|
43
|
+
return true;
|
|
44
|
+
};
|
|
45
|
+
var deepMerge = (...objects) => {
|
|
46
|
+
const result = {};
|
|
47
|
+
objects.forEach((obj) => {
|
|
48
|
+
if (isObject(obj)) {
|
|
49
|
+
Object.keys(obj).forEach((key) => {
|
|
50
|
+
const value = obj[key];
|
|
51
|
+
if (isObject(value) && isObject(result[key])) {
|
|
52
|
+
result[key] = deepMerge(result[key], value);
|
|
53
|
+
} else {
|
|
54
|
+
result[key] = clone(value);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
return result;
|
|
60
|
+
};
|
|
61
|
+
var get = (obj, path) => {
|
|
62
|
+
return path.split(".").reduce((acc, key) => acc?.[key], obj);
|
|
63
|
+
};
|
|
64
|
+
var set = (obj, path, value) => {
|
|
65
|
+
const keys = path.split(".");
|
|
66
|
+
const lastKey = keys.pop();
|
|
67
|
+
const target = keys.reduce((acc, key) => {
|
|
68
|
+
if (!acc[key]) acc[key] = {};
|
|
69
|
+
return acc[key];
|
|
70
|
+
}, obj);
|
|
71
|
+
target[lastKey] = value;
|
|
72
|
+
};
|
|
73
|
+
var omit = (obj, keys) => {
|
|
74
|
+
const result = { ...obj };
|
|
75
|
+
keys.forEach((key) => delete result[key]);
|
|
76
|
+
return result;
|
|
77
|
+
};
|
|
78
|
+
var pick = (obj, keys) => {
|
|
79
|
+
const result = {};
|
|
80
|
+
keys.forEach((key) => {
|
|
81
|
+
if (key in obj) {
|
|
82
|
+
result[key] = obj[key];
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
return result;
|
|
86
|
+
};
|
|
87
|
+
var isObject = (value) => {
|
|
88
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
89
|
+
};
|
|
90
|
+
var isArray = (value) => {
|
|
91
|
+
return Array.isArray(value);
|
|
92
|
+
};
|
|
93
|
+
var isString = (value) => {
|
|
94
|
+
return typeof value === "string";
|
|
95
|
+
};
|
|
96
|
+
var isNumber = (value) => {
|
|
97
|
+
return typeof value === "number" && !isNaN(value);
|
|
98
|
+
};
|
|
99
|
+
var isBoolean = (value) => {
|
|
100
|
+
return typeof value === "boolean";
|
|
101
|
+
};
|
|
102
|
+
var isFunction = (value) => {
|
|
103
|
+
return typeof value === "function";
|
|
104
|
+
};
|
|
105
|
+
var isEmpty = (value) => {
|
|
106
|
+
if (value === null || value === void 0) return true;
|
|
107
|
+
if (isString(value) || Array.isArray(value)) return value.length === 0;
|
|
108
|
+
if (isObject(value)) return Object.keys(value).length === 0;
|
|
109
|
+
return false;
|
|
110
|
+
};
|
|
111
|
+
var uniq = (array) => {
|
|
112
|
+
return [...new Set(array)];
|
|
113
|
+
};
|
|
114
|
+
var sortBy = (array, key) => {
|
|
115
|
+
const sortFn = typeof key === "function" ? key : (item) => item[key];
|
|
116
|
+
return [...array].sort((a, b) => {
|
|
117
|
+
const valueA = sortFn(a);
|
|
118
|
+
const valueB = sortFn(b);
|
|
119
|
+
if (valueA < valueB) return -1;
|
|
120
|
+
if (valueA > valueB) return 1;
|
|
121
|
+
return 0;
|
|
122
|
+
});
|
|
123
|
+
};
|
|
124
|
+
var chunk = (array, size) => {
|
|
125
|
+
const result = [];
|
|
126
|
+
for (let i = 0; i < array.length; i += size) {
|
|
127
|
+
result.push(array.slice(i, i + size));
|
|
128
|
+
}
|
|
129
|
+
return result;
|
|
130
|
+
};
|
|
131
|
+
var groupBy = (array, key) => {
|
|
132
|
+
const groupFn = typeof key === "function" ? key : (item) => String(item[key]);
|
|
133
|
+
return array.reduce(
|
|
134
|
+
(result, item) => {
|
|
135
|
+
const groupKey = groupFn(item);
|
|
136
|
+
if (!result[groupKey]) {
|
|
137
|
+
result[groupKey] = [];
|
|
138
|
+
}
|
|
139
|
+
result[groupKey].push(item);
|
|
140
|
+
return result;
|
|
141
|
+
},
|
|
142
|
+
{}
|
|
143
|
+
);
|
|
144
|
+
};
|
|
145
|
+
var sum = (array) => {
|
|
146
|
+
return array.reduce((acc, num) => acc + num, 0);
|
|
147
|
+
};
|
|
148
|
+
var avg = (array) => {
|
|
149
|
+
return array.length > 0 ? sum(array) / array.length : 0;
|
|
150
|
+
};
|
|
151
|
+
var max = (array) => {
|
|
152
|
+
return Math.max(...array);
|
|
153
|
+
};
|
|
154
|
+
var min = (array) => {
|
|
155
|
+
return Math.min(...array);
|
|
156
|
+
};
|
|
157
|
+
var camelToSnake = (str) => {
|
|
158
|
+
return str.replace(/[A-Z]/g, (match) => `_${match.toLowerCase()}`);
|
|
159
|
+
};
|
|
160
|
+
var snakeToCamel = (str) => {
|
|
161
|
+
return str.replace(/_([a-z])/g, (_, match) => match.toUpperCase());
|
|
162
|
+
};
|
|
163
|
+
var capitalize = (str) => {
|
|
164
|
+
return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
|
|
165
|
+
};
|
|
166
|
+
var truncate = (str, length = 100, suffix = "...") => {
|
|
167
|
+
if (str.length <= length) return str;
|
|
168
|
+
return `${str.slice(0, length)}${suffix}`;
|
|
169
|
+
};
|
|
170
|
+
var formatFileSize = (bytes) => {
|
|
171
|
+
if (bytes === 0) return "0 B";
|
|
172
|
+
const k = 1024;
|
|
173
|
+
const sizes = ["B", "KB", "MB", "GB", "TB"];
|
|
174
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
175
|
+
return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}`;
|
|
176
|
+
};
|
|
177
|
+
var formatNumber = (num) => {
|
|
178
|
+
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
179
|
+
};
|
|
180
|
+
var isValidUrl = (str) => {
|
|
181
|
+
try {
|
|
182
|
+
new URL(str);
|
|
183
|
+
return true;
|
|
184
|
+
} catch {
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
var isValidEmail = (email) => {
|
|
189
|
+
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
190
|
+
return regex.test(email);
|
|
191
|
+
};
|
|
192
|
+
var isValidPhone = (phone) => {
|
|
193
|
+
const regex = /^1[3-9]\d{9}$/;
|
|
194
|
+
return regex.test(phone);
|
|
195
|
+
};
|
|
196
|
+
var randomInt = (min2, max2) => {
|
|
197
|
+
return Math.floor(Math.random() * (max2 - min2 + 1)) + min2;
|
|
198
|
+
};
|
|
199
|
+
var uniqueId = (prefix = "") => {
|
|
200
|
+
return `${prefix}${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
201
|
+
};
|
|
202
|
+
var delay = (ms) => {
|
|
203
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
204
|
+
};
|
|
205
|
+
var retry = async (fn, retries = 3, delayMs = 1e3) => {
|
|
206
|
+
try {
|
|
207
|
+
return await fn();
|
|
208
|
+
} catch (error) {
|
|
209
|
+
if (retries <= 0) {
|
|
210
|
+
throw error;
|
|
211
|
+
}
|
|
212
|
+
await delay(delayMs);
|
|
213
|
+
return retry(fn, retries - 1, delayMs);
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
var hexToRgb = (str) => {
|
|
217
|
+
const hexRegex = /^#?([0-9A-Fa-f]{6})$/;
|
|
218
|
+
if (!hexRegex.test(str)) {
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
const hex = str.replace("#", "");
|
|
222
|
+
const r = parseInt(hex.substring(0, 2), 16);
|
|
223
|
+
const g = parseInt(hex.substring(2, 4), 16);
|
|
224
|
+
const b = parseInt(hex.substring(4, 6), 16);
|
|
225
|
+
return [r, g, b];
|
|
226
|
+
};
|
|
227
|
+
var hexToRgbString = (str) => {
|
|
228
|
+
const rgb = hexToRgb(str);
|
|
229
|
+
if (!rgb) {
|
|
230
|
+
return null;
|
|
231
|
+
}
|
|
232
|
+
return `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`;
|
|
233
|
+
};
|
|
234
|
+
var rgbToHex = (r, g, b) => {
|
|
235
|
+
const numRegex = /^\d{1,3}$/;
|
|
236
|
+
if (!numRegex.test(r.toString()) || !numRegex.test(g.toString()) || !numRegex.test(b.toString())) {
|
|
237
|
+
return null;
|
|
238
|
+
}
|
|
239
|
+
if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) {
|
|
240
|
+
return null;
|
|
241
|
+
}
|
|
242
|
+
const toHex = (num) => {
|
|
243
|
+
const hex = num.toString(16);
|
|
244
|
+
return hex.length === 1 ? `0${hex}` : hex;
|
|
245
|
+
};
|
|
246
|
+
return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
|
|
247
|
+
};
|
|
248
|
+
var rgbArrayToHex = (rgb) => {
|
|
249
|
+
if (rgb.length !== 3) {
|
|
250
|
+
return null;
|
|
251
|
+
}
|
|
252
|
+
return rgbToHex(rgb[0], rgb[1], rgb[2]);
|
|
253
|
+
};
|
|
254
|
+
var getLightColor = (color, alpha) => {
|
|
255
|
+
const rgb = hexToRgb(color);
|
|
256
|
+
if (!rgb) {
|
|
257
|
+
return null;
|
|
258
|
+
}
|
|
259
|
+
const [r, g, b] = rgb;
|
|
260
|
+
const newR = Math.floor((255 - r) * alpha + r);
|
|
261
|
+
const newG = Math.floor((255 - g) * alpha + g);
|
|
262
|
+
const newB = Math.floor((255 - b) * alpha + b);
|
|
263
|
+
return rgbToHex(newR, newG, newB);
|
|
264
|
+
};
|
|
265
|
+
var getDarkColor = (color, alpha) => {
|
|
266
|
+
const rgb = hexToRgb(color);
|
|
267
|
+
if (!rgb) {
|
|
268
|
+
return null;
|
|
269
|
+
}
|
|
270
|
+
const [r, g, b] = rgb;
|
|
271
|
+
const newR = Math.floor(r * (1 - alpha));
|
|
272
|
+
const newG = Math.floor(g * (1 - alpha));
|
|
273
|
+
const newB = Math.floor(b * (1 - alpha));
|
|
274
|
+
return rgbToHex(newR, newG, newB);
|
|
275
|
+
};
|
|
276
|
+
var imgToBase64 = (url, type = "image/png") => {
|
|
277
|
+
return new Promise((resolve, reject) => {
|
|
278
|
+
const image = new Image();
|
|
279
|
+
image.crossOrigin = "anonymous";
|
|
280
|
+
image.onload = () => {
|
|
281
|
+
const canvas = document.createElement("canvas");
|
|
282
|
+
canvas.width = image.naturalWidth;
|
|
283
|
+
canvas.height = image.naturalHeight;
|
|
284
|
+
const ctx = canvas.getContext("2d");
|
|
285
|
+
if (!ctx) {
|
|
286
|
+
reject(new Error("Failed to get canvas context"));
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
ctx.drawImage(image, 0, 0);
|
|
290
|
+
const base64 = canvas.toDataURL(type);
|
|
291
|
+
resolve(base64);
|
|
292
|
+
};
|
|
293
|
+
image.onerror = (err) => {
|
|
294
|
+
reject(new Error(`Failed to load image: ${String(err)}`));
|
|
295
|
+
};
|
|
296
|
+
image.src = url;
|
|
297
|
+
});
|
|
298
|
+
};
|
|
299
|
+
var base64toFile = (base64, fileName, mimeType = "image/jpeg") => {
|
|
300
|
+
const dataArr = base64.split(",");
|
|
301
|
+
const byteString = atob(dataArr[1]);
|
|
302
|
+
const u8Arr = new Uint8Array(byteString.length);
|
|
303
|
+
for (let i = 0; i < byteString.length; i++) {
|
|
304
|
+
u8Arr[i] = byteString.charCodeAt(i);
|
|
305
|
+
}
|
|
306
|
+
return new File([u8Arr], fileName, { type: mimeType });
|
|
307
|
+
};
|
|
308
|
+
var base64toBlob = (base64, mimeType = "image/jpeg") => {
|
|
309
|
+
const dataArr = base64.split(",");
|
|
310
|
+
const byteString = atob(dataArr[1]);
|
|
311
|
+
const u8Arr = new Uint8Array(byteString.length);
|
|
312
|
+
for (let i = 0; i < byteString.length; i++) {
|
|
313
|
+
u8Arr[i] = byteString.charCodeAt(i);
|
|
314
|
+
}
|
|
315
|
+
return new Blob([u8Arr], { type: mimeType });
|
|
316
|
+
};
|
|
317
|
+
var downloadFile = (url, fileName = "\u6587\u4EF6", target = false) => {
|
|
318
|
+
const link = document.createElement("a");
|
|
319
|
+
link.style.display = "none";
|
|
320
|
+
link.href = url;
|
|
321
|
+
if (target) {
|
|
322
|
+
link.target = "_blank";
|
|
323
|
+
} else {
|
|
324
|
+
link.setAttribute("download", fileName);
|
|
325
|
+
}
|
|
326
|
+
document.body.appendChild(link);
|
|
327
|
+
link.click();
|
|
328
|
+
document.body.removeChild(link);
|
|
329
|
+
};
|
|
330
|
+
var downloadBlob = (blob, fileName) => {
|
|
331
|
+
const url = URL.createObjectURL(blob);
|
|
332
|
+
downloadFile(url, fileName);
|
|
333
|
+
URL.revokeObjectURL(url);
|
|
334
|
+
};
|
|
335
|
+
var downloadBase64 = (base64, fileName, mimeType = "image/jpeg") => {
|
|
336
|
+
const blob = base64toBlob(base64, mimeType);
|
|
337
|
+
downloadBlob(blob, fileName);
|
|
338
|
+
};
|
|
339
|
+
var copyToClipboard = async (text) => {
|
|
340
|
+
try {
|
|
341
|
+
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
342
|
+
await navigator.clipboard.writeText(text);
|
|
343
|
+
return true;
|
|
344
|
+
}
|
|
345
|
+
const textarea = document.createElement("textarea");
|
|
346
|
+
textarea.value = text;
|
|
347
|
+
textarea.style.position = "fixed";
|
|
348
|
+
textarea.style.opacity = "0";
|
|
349
|
+
document.body.appendChild(textarea);
|
|
350
|
+
textarea.select();
|
|
351
|
+
const success = document.execCommand("copy");
|
|
352
|
+
document.body.removeChild(textarea);
|
|
353
|
+
return success;
|
|
354
|
+
} catch {
|
|
355
|
+
return false;
|
|
356
|
+
}
|
|
357
|
+
};
|
|
358
|
+
var readFromClipboard = async () => {
|
|
359
|
+
try {
|
|
360
|
+
if (navigator.clipboard && navigator.clipboard.readText) {
|
|
361
|
+
return await navigator.clipboard.readText();
|
|
362
|
+
}
|
|
363
|
+
return "";
|
|
364
|
+
} catch {
|
|
365
|
+
return "";
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
export { avg, base64toBlob, base64toFile, camelToSnake, capitalize, chunk, clone, copyToClipboard, deepMerge, delay, downloadBase64, downloadBlob, downloadFile, formatFileSize, formatNumber, get, getDarkColor, getLightColor, groupBy, hexToRgb, hexToRgbString, imgToBase64, isArray, isBoolean, isEmpty, isEqual, isFunction, isNumber, isObject, isString, isValidEmail, isValidPhone, isValidUrl, max, min, omit, pick, randomInt, readFromClipboard, retry, rgbArrayToHex, rgbToHex, set, snakeToCamel, sortBy, sum, truncate, uniq, uniqueId };
|
|
370
|
+
//# sourceMappingURL=utils.js.map
|
|
371
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/modules/utils/index.ts"],"names":["min","max"],"mappings":";;;AAmCO,IAAM,KAAA,GAAQ,CAAI,GAAA,KAAc;AACrC,EAAA,IAAI,GAAA,KAAQ,IAAA,IAAQ,OAAO,GAAA,KAAQ,QAAA,EAAU;AAC3C,IAAA,OAAO,GAAA;AAAA,EACT;AACA,EAAA,IAAI,eAAe,IAAA,EAAM;AACvB,IAAA,OAAO,IAAI,IAAA,CAAK,GAAA,CAAI,OAAA,EAAS,CAAA;AAAA,EAC/B;AACA,EAAA,IAAI,eAAe,KAAA,EAAO;AACxB,IAAA,OAAO,IAAI,GAAA,CAAI,CAAC,IAAA,KAAS,KAAA,CAAM,IAAI,CAAC,CAAA;AAAA,EACtC;AACA,EAAA,IAAI,eAAe,MAAA,EAAQ;AACzB,IAAA,MAAM,OAAO,EAAC;AACd,IAAA,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA,CAAE,OAAA,CAAQ,CAAC,GAAA,KAAQ;AAC/B,MAAC,KAAa,GAAG,CAAA,GAAI,KAAA,CAAO,GAAA,CAAY,GAAG,CAAC,CAAA;AAAA,IAC/C,CAAC,CAAA;AACD,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,OAAO,GAAA;AACT;AAQO,IAAM,OAAA,GAAU,CAAC,CAAA,EAAQ,CAAA,KAAoB;AAClD,EAAA,IAAI,CAAA,KAAM,GAAG,OAAO,IAAA;AACpB,EAAA,IAAI,CAAA,KAAM,IAAA,IAAQ,CAAA,KAAM,IAAA,EAAM,OAAO,KAAA;AACrC,EAAA,IAAI,OAAO,CAAA,KAAM,OAAO,CAAA,EAAG,OAAO,KAAA;AAElC,EAAA,IAAI,OAAO,CAAA,KAAM,QAAA,EAAU,OAAO,CAAA,KAAM,CAAA;AACxC,EAAA,IAAI,KAAA,CAAM,QAAQ,CAAC,CAAA,KAAM,MAAM,OAAA,CAAQ,CAAC,GAAG,OAAO,KAAA;AAElD,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,EAAG;AACpB,IAAA,IAAI,CAAA,CAAE,MAAA,KAAW,CAAA,CAAE,MAAA,EAAQ,OAAO,KAAA;AAClC,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,CAAE,QAAQ,CAAA,EAAA,EAAK;AACjC,MAAA,IAAI,CAAC,QAAQ,CAAA,CAAE,CAAC,GAAG,CAAA,CAAE,CAAC,CAAC,CAAA,EAAG,OAAO,KAAA;AAAA,IACnC;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA;AAC3B,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA;AAC3B,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,KAAA,CAAM,MAAA,EAAQ,OAAO,KAAA;AAE1C,EAAA,KAAA,MAAW,OAAO,KAAA,EAAO;AACvB,IAAA,IAAI,CAAC,KAAA,CAAM,QAAA,CAAS,GAAG,GAAG,OAAO,KAAA;AACjC,IAAA,IAAI,CAAC,QAAQ,CAAA,CAAE,GAAG,GAAG,CAAA,CAAE,GAAG,CAAC,CAAA,EAAG,OAAO,KAAA;AAAA,EACvC;AACA,EAAA,OAAO,IAAA;AACT;AAOO,IAAM,SAAA,GAAY,IAAmC,OAAA,KAA6B;AACvF,EAAA,MAAM,SAAS,EAAC;AAChB,EAAA,OAAA,CAAQ,OAAA,CAAQ,CAAC,GAAA,KAAQ;AACvB,IAAA,IAAI,QAAA,CAAS,GAAG,CAAA,EAAG;AACjB,MAAA,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA,CAAE,OAAA,CAAQ,CAAC,GAAA,KAAQ;AAChC,QAAA,MAAM,KAAA,GAAQ,IAAI,GAAG,CAAA;AACrB,QAAA,IAAI,SAAS,KAAK,CAAA,IAAK,SAAS,MAAA,CAAO,GAAG,CAAC,CAAA,EAAG;AAC3C,UAAC,OAAe,GAAG,CAAA,GAAI,UAAU,MAAA,CAAO,GAAG,GAAG,KAAK,CAAA;AAAA,QACtD,CAAA,MAAO;AACJ,UAAC,MAAA,CAAe,GAAG,CAAA,GAAI,KAAA,CAAM,KAAK,CAAA;AAAA,QACrC;AAAA,MACF,CAAC,CAAA;AAAA,IACH;AAAA,EACF,CAAC,CAAA;AACD,EAAA,OAAO,MAAA;AACT;AAQO,IAAM,GAAA,GAAM,CAAC,GAAA,EAAU,IAAA,KAAsB;AAClD,EAAA,OAAO,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA,CAAE,MAAA,CAAO,CAAC,GAAA,EAAK,GAAA,KAAQ,GAAA,GAAM,GAAG,CAAA,EAAG,GAAG,CAAA;AAC7D;AAQO,IAAM,GAAA,GAAM,CAAC,GAAA,EAAU,IAAA,EAAc,KAAA,KAAqB;AAC/D,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC3B,EAAA,MAAM,OAAA,GAAU,KAAK,GAAA,EAAI;AACzB,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,CAAC,KAAK,GAAA,KAAQ;AACvC,IAAA,IAAI,CAAC,GAAA,CAAI,GAAG,GAAG,GAAA,CAAI,GAAG,IAAI,EAAC;AAC3B,IAAA,OAAO,IAAI,GAAG,CAAA;AAAA,EAChB,GAAG,GAAG,CAAA;AACN,EAAA,MAAA,CAAO,OAAO,CAAA,GAAI,KAAA;AACpB;AAQO,IAAM,IAAA,GAAO,CAClB,GAAA,EACA,IAAA,KACe;AACf,EAAA,MAAM,MAAA,GAAS,EAAE,GAAG,GAAA,EAAI;AACxB,EAAA,IAAA,CAAK,QAAQ,CAAC,GAAA,KAAQ,OAAO,MAAA,CAAO,GAAG,CAAC,CAAA;AACxC,EAAA,OAAO,MAAA;AACT;AAQO,IAAM,IAAA,GAAO,CAClB,GAAA,EACA,IAAA,KACe;AACf,EAAA,MAAM,SAAS,EAAC;AAChB,EAAA,IAAA,CAAK,OAAA,CAAQ,CAAC,GAAA,KAAQ;AACpB,IAAA,IAAI,OAAO,GAAA,EAAK;AACd,MAAA,MAAA,CAAO,GAAG,CAAA,GAAI,GAAA,CAAI,GAAG,CAAA;AAAA,IACvB;AAAA,EACF,CAAC,CAAA;AACD,EAAA,OAAO,MAAA;AACT;AASO,IAAM,QAAA,GAAW,CAAC,KAAA,KAA6C;AACpE,EAAA,OAAO,KAAA,KAAU,QAAQ,OAAO,KAAA,KAAU,YAAY,CAAC,KAAA,CAAM,QAAQ,KAAK,CAAA;AAC5E;AAOO,IAAM,OAAA,GAAU,CAAC,KAAA,KAA+B;AACrD,EAAA,OAAO,KAAA,CAAM,QAAQ,KAAK,CAAA;AAC5B;AAOO,IAAM,QAAA,GAAW,CAAC,KAAA,KAAgC;AACvD,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA;AAC1B;AAOO,IAAM,QAAA,GAAW,CAAC,KAAA,KAAgC;AACvD,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,IAAY,CAAC,MAAM,KAAK,CAAA;AAClD;AAOO,IAAM,SAAA,GAAY,CAAC,KAAA,KAAiC;AACzD,EAAA,OAAO,OAAO,KAAA,KAAU,SAAA;AAC1B;AAOO,IAAM,UAAA,GAAa,CAAC,KAAA,KAAkC;AAC3D,EAAA,OAAO,OAAO,KAAA,KAAU,UAAA;AAC1B;AAOO,IAAM,OAAA,GAAU,CAAC,KAAA,KAAwB;AAC9C,EAAA,IAAI,KAAA,KAAU,IAAA,IAAQ,KAAA,KAAU,MAAA,EAAW,OAAO,IAAA;AAClD,EAAA,IAAI,QAAA,CAAS,KAAK,CAAA,IAAK,KAAA,CAAM,QAAQ,KAAK,CAAA,EAAG,OAAO,KAAA,CAAM,MAAA,KAAW,CAAA;AACrE,EAAA,IAAI,QAAA,CAAS,KAAK,CAAA,EAAG,OAAO,OAAO,IAAA,CAAK,KAAK,EAAE,MAAA,KAAW,CAAA;AAC1D,EAAA,OAAO,KAAA;AACT;AASO,IAAM,IAAA,GAAO,CAAI,KAAA,KAAoB;AAC1C,EAAA,OAAO,CAAC,GAAG,IAAI,GAAA,CAAI,KAAK,CAAC,CAAA;AAC3B;AAQO,IAAM,MAAA,GAAS,CAAI,KAAA,EAAY,GAAA,KAA2C;AAC/E,EAAA,MAAM,MAAA,GAAS,OAAO,GAAA,KAAQ,UAAA,GAAa,MAAM,CAAC,IAAA,KAAY,KAAK,GAAG,CAAA;AACtE,EAAA,OAAO,CAAC,GAAG,KAAK,EAAE,IAAA,CAAK,CAAC,GAAG,CAAA,KAAM;AAC/B,IAAA,MAAM,MAAA,GAAS,OAAO,CAAC,CAAA;AACvB,IAAA,MAAM,MAAA,GAAS,OAAO,CAAC,CAAA;AACvB,IAAA,IAAI,MAAA,GAAS,QAAQ,OAAO,EAAA;AAC5B,IAAA,IAAI,MAAA,GAAS,QAAQ,OAAO,CAAA;AAC5B,IAAA,OAAO,CAAA;AAAA,EACT,CAAC,CAAA;AACH;AAQO,IAAM,KAAA,GAAQ,CAAI,KAAA,EAAY,IAAA,KAAwB;AAC3D,EAAA,MAAM,SAAgB,EAAC;AACvB,EAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,MAAA,EAAQ,KAAK,IAAA,EAAM;AAC3C,IAAA,MAAA,CAAO,KAAK,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,CAAA,GAAI,IAAI,CAAC,CAAA;AAAA,EACtC;AACA,EAAA,OAAO,MAAA;AACT;AAQO,IAAM,OAAA,GAAU,CACrB,KAAA,EACA,GAAA,KACwB;AACxB,EAAA,MAAM,OAAA,GAAU,OAAO,GAAA,KAAQ,UAAA,GAAa,GAAA,GAAM,CAAC,IAAA,KAAY,MAAA,CAAO,IAAA,CAAK,GAAG,CAAC,CAAA;AAC/E,EAAA,OAAO,KAAA,CAAM,MAAA;AAAA,IACX,CAAC,QAAQ,IAAA,KAAS;AAChB,MAAA,MAAM,QAAA,GAAW,QAAQ,IAAI,CAAA;AAC7B,MAAA,IAAI,CAAC,MAAA,CAAO,QAAQ,CAAA,EAAG;AACrB,QAAA,MAAA,CAAO,QAAQ,IAAI,EAAC;AAAA,MACtB;AACA,MAAA,MAAA,CAAO,QAAQ,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA;AAC1B,MAAA,OAAO,MAAA;AAAA,IACT,CAAA;AAAA,IACA;AAAC,GACH;AACF;AAOO,IAAM,GAAA,GAAM,CAAC,KAAA,KAA4B;AAC9C,EAAA,OAAO,MAAM,MAAA,CAAO,CAAC,KAAK,GAAA,KAAQ,GAAA,GAAM,KAAK,CAAC,CAAA;AAChD;AAOO,IAAM,GAAA,GAAM,CAAC,KAAA,KAA4B;AAC9C,EAAA,OAAO,MAAM,MAAA,GAAS,CAAA,GAAI,IAAI,KAAK,CAAA,GAAI,MAAM,MAAA,GAAS,CAAA;AACxD;AAOO,IAAM,GAAA,GAAM,CAAC,KAAA,KAA4B;AAC9C,EAAA,OAAO,IAAA,CAAK,GAAA,CAAI,GAAG,KAAK,CAAA;AAC1B;AAOO,IAAM,GAAA,GAAM,CAAC,KAAA,KAA4B;AAC9C,EAAA,OAAO,IAAA,CAAK,GAAA,CAAI,GAAG,KAAK,CAAA;AAC1B;AASO,IAAM,YAAA,GAAe,CAAC,GAAA,KAAwB;AACnD,EAAA,OAAO,GAAA,CAAI,QAAQ,QAAA,EAAU,CAAC,UAAU,CAAA,CAAA,EAAI,KAAA,CAAM,WAAA,EAAa,CAAA,CAAE,CAAA;AACnE;AAOO,IAAM,YAAA,GAAe,CAAC,GAAA,KAAwB;AACnD,EAAA,OAAO,GAAA,CAAI,QAAQ,WAAA,EAAa,CAAC,GAAG,KAAA,KAAU,KAAA,CAAM,aAAa,CAAA;AACnE;AAOO,IAAM,UAAA,GAAa,CAAC,GAAA,KAAwB;AACjD,EAAA,OAAO,GAAA,CAAI,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,KAAgB,GAAA,CAAI,KAAA,CAAM,CAAC,CAAA,CAAE,WAAA,EAAY;AAChE;AASO,IAAM,WAAW,CAAC,GAAA,EAAa,MAAA,GAAiB,GAAA,EAAK,SAAiB,KAAA,KAAkB;AAC7F,EAAA,IAAI,GAAA,CAAI,MAAA,IAAU,MAAA,EAAQ,OAAO,GAAA;AACjC,EAAA,OAAO,GAAG,GAAA,CAAI,KAAA,CAAM,GAAG,MAAM,CAAC,GAAG,MAAM,CAAA,CAAA;AACzC;AASO,IAAM,cAAA,GAAiB,CAAC,KAAA,KAA0B;AACvD,EAAA,IAAI,KAAA,KAAU,GAAG,OAAO,KAAA;AACxB,EAAA,MAAM,CAAA,GAAI,IAAA;AACV,EAAA,MAAM,QAAQ,CAAC,GAAA,EAAK,IAAA,EAAM,IAAA,EAAM,MAAM,IAAI,CAAA;AAC1C,EAAA,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAC,CAAC,CAAA;AAClD,EAAA,OAAO,CAAA,EAAA,CAAI,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,CAAC,CAAA,EAAG,OAAA,CAAQ,CAAC,CAAC,CAAA,CAAA,EAAI,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AAC3D;AAOO,IAAM,YAAA,GAAe,CAAC,GAAA,KAAwB;AACnD,EAAA,OAAO,GAAA,CAAI,QAAA,EAAS,CAAE,OAAA,CAAQ,yBAAyB,GAAG,CAAA;AAC5D;AASO,IAAM,UAAA,GAAa,CAAC,GAAA,KAAyB;AAClD,EAAA,IAAI;AACF,IAAA,IAAI,IAAI,GAAG,CAAA;AACX,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAOO,IAAM,YAAA,GAAe,CAAC,KAAA,KAA2B;AACtD,EAAA,MAAM,KAAA,GAAQ,4BAAA;AACd,EAAA,OAAO,KAAA,CAAM,KAAK,KAAK,CAAA;AACzB;AAOO,IAAM,YAAA,GAAe,CAAC,KAAA,KAA2B;AACtD,EAAA,MAAM,KAAA,GAAQ,eAAA;AACd,EAAA,OAAO,KAAA,CAAM,KAAK,KAAK,CAAA;AACzB;AAUO,IAAM,SAAA,GAAY,CAACA,IAAAA,EAAaC,IAAAA,KAAwB;AAC7D,EAAA,OAAO,IAAA,CAAK,MAAM,IAAA,CAAK,MAAA,MAAYA,IAAAA,GAAMD,IAAAA,GAAM,EAAE,CAAA,GAAIA,IAAAA;AACvD;AAOO,IAAM,QAAA,GAAW,CAAC,MAAA,GAAiB,EAAA,KAAe;AACvD,EAAA,OAAO,GAAG,MAAM,CAAA,EAAG,IAAA,CAAK,GAAA,EAAK,CAAA,CAAA,EAAI,IAAA,CAAK,MAAA,EAAO,CAAE,SAAS,EAAE,CAAA,CAAE,MAAA,CAAO,CAAA,EAAG,CAAC,CAAC,CAAA,CAAA;AAC1E;AAOO,IAAM,KAAA,GAAQ,CAAC,EAAA,KAA8B;AAClD,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,YAAY,UAAA,CAAW,OAAA,EAAS,EAAE,CAAC,CAAA;AACzD;AASO,IAAM,QAAQ,OACnB,EAAA,EACA,OAAA,GAAkB,CAAA,EAClB,UAAkB,GAAA,KACH;AACf,EAAA,IAAI;AACF,IAAA,OAAO,MAAM,EAAA,EAAG;AAAA,EAClB,SAAS,KAAA,EAAO;AACd,IAAA,IAAI,WAAW,CAAA,EAAG;AAChB,MAAA,MAAM,KAAA;AAAA,IACR;AACA,IAAA,MAAM,MAAM,OAAO,CAAA;AACnB,IAAA,OAAO,KAAA,CAAM,EAAA,EAAI,OAAA,GAAU,CAAA,EAAG,OAAO,CAAA;AAAA,EACvC;AACF;AASO,IAAM,QAAA,GAAW,CAAC,GAAA,KAAiC;AACxD,EAAA,MAAM,QAAA,GAAW,sBAAA;AACjB,EAAA,IAAI,CAAC,QAAA,CAAS,IAAA,CAAK,GAAG,CAAA,EAAG;AACvB,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,GAAA,GAAM,GAAA,CAAI,OAAA,CAAQ,GAAA,EAAK,EAAE,CAAA;AAC/B,EAAA,MAAM,IAAI,QAAA,CAAS,GAAA,CAAI,UAAU,CAAA,EAAG,CAAC,GAAG,EAAE,CAAA;AAC1C,EAAA,MAAM,IAAI,QAAA,CAAS,GAAA,CAAI,UAAU,CAAA,EAAG,CAAC,GAAG,EAAE,CAAA;AAC1C,EAAA,MAAM,IAAI,QAAA,CAAS,GAAA,CAAI,UAAU,CAAA,EAAG,CAAC,GAAG,EAAE,CAAA;AAE1C,EAAA,OAAO,CAAC,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AACjB;AAOO,IAAM,cAAA,GAAiB,CAAC,GAAA,KAA+B;AAC5D,EAAA,MAAM,GAAA,GAAM,SAAS,GAAG,CAAA;AACxB,EAAA,IAAI,CAAC,GAAA,EAAK;AACR,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,OAAO,CAAA,IAAA,EAAO,GAAA,CAAI,CAAC,CAAC,CAAA,EAAA,EAAK,GAAA,CAAI,CAAC,CAAC,CAAA,EAAA,EAAK,GAAA,CAAI,CAAC,CAAC,CAAA,CAAA,CAAA;AAC5C;AASO,IAAM,QAAA,GAAW,CAAC,CAAA,EAAW,CAAA,EAAW,CAAA,KAA6B;AAC1E,EAAA,MAAM,QAAA,GAAW,WAAA;AACjB,EAAA,IAAI,CAAC,SAAS,IAAA,CAAK,CAAA,CAAE,UAAU,CAAA,IAAK,CAAC,QAAA,CAAS,IAAA,CAAK,EAAE,QAAA,EAAU,KAAK,CAAC,QAAA,CAAS,KAAK,CAAA,CAAE,QAAA,EAAU,CAAA,EAAG;AAChG,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,IAAI,CAAA,GAAI,CAAA,IAAK,CAAA,GAAI,GAAA,IAAO,CAAA,GAAI,CAAA,IAAK,CAAA,GAAI,GAAA,IAAO,CAAA,GAAI,CAAA,IAAK,CAAA,GAAI,GAAA,EAAK;AAC5D,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,KAAA,GAAQ,CAAC,GAAA,KAAwB;AACrC,IAAA,MAAM,GAAA,GAAM,GAAA,CAAI,QAAA,CAAS,EAAE,CAAA;AAC3B,IAAA,OAAO,GAAA,CAAI,MAAA,KAAW,CAAA,GAAI,CAAA,CAAA,EAAI,GAAG,CAAA,CAAA,GAAK,GAAA;AAAA,EACxC,CAAA;AAEA,EAAA,OAAO,CAAA,CAAA,EAAI,KAAA,CAAM,CAAC,CAAC,CAAA,EAAG,KAAA,CAAM,CAAC,CAAC,CAAA,EAAG,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AAC3C;AAOO,IAAM,aAAA,GAAgB,CAAC,GAAA,KAAiC;AAC7D,EAAA,IAAI,GAAA,CAAI,WAAW,CAAA,EAAG;AACpB,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,OAAO,QAAA,CAAS,IAAI,CAAC,CAAA,EAAG,IAAI,CAAC,CAAA,EAAG,GAAA,CAAI,CAAC,CAAC,CAAA;AACxC;AAQO,IAAM,aAAA,GAAgB,CAAC,KAAA,EAAe,KAAA,KAAiC;AAC5E,EAAA,MAAM,GAAA,GAAM,SAAS,KAAK,CAAA;AAC1B,EAAA,IAAI,CAAC,GAAA,EAAK;AACR,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,CAAC,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,GAAI,GAAA;AAClB,EAAA,MAAM,OAAO,IAAA,CAAK,KAAA,CAAA,CAAO,GAAA,GAAM,CAAA,IAAK,QAAQ,CAAC,CAAA;AAC7C,EAAA,MAAM,OAAO,IAAA,CAAK,KAAA,CAAA,CAAO,GAAA,GAAM,CAAA,IAAK,QAAQ,CAAC,CAAA;AAC7C,EAAA,MAAM,OAAO,IAAA,CAAK,KAAA,CAAA,CAAO,GAAA,GAAM,CAAA,IAAK,QAAQ,CAAC,CAAA;AAE7C,EAAA,OAAO,QAAA,CAAS,IAAA,EAAM,IAAA,EAAM,IAAI,CAAA;AAClC;AAQO,IAAM,YAAA,GAAe,CAAC,KAAA,EAAe,KAAA,KAAiC;AAC3E,EAAA,MAAM,GAAA,GAAM,SAAS,KAAK,CAAA;AAC1B,EAAA,IAAI,CAAC,GAAA,EAAK;AACR,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,CAAC,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,GAAI,GAAA;AAClB,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,CAAA,IAAK,IAAI,KAAA,CAAM,CAAA;AACvC,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,CAAA,IAAK,IAAI,KAAA,CAAM,CAAA;AACvC,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,CAAA,IAAK,IAAI,KAAA,CAAM,CAAA;AAEvC,EAAA,OAAO,QAAA,CAAS,IAAA,EAAM,IAAA,EAAM,IAAI,CAAA;AAClC;AAUO,IAAM,WAAA,GAAc,CAAC,GAAA,EAAa,IAAA,GAAmC,WAAA,KAAiC;AAC3G,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,IAAA,MAAM,KAAA,GAAQ,IAAI,KAAA,EAAM;AACxB,IAAA,KAAA,CAAM,WAAA,GAAc,WAAA;AAEpB,IAAA,KAAA,CAAM,SAAS,MAAM;AACnB,MAAA,MAAM,MAAA,GAAS,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AAC9C,MAAA,MAAA,CAAO,QAAQ,KAAA,CAAM,YAAA;AACrB,MAAA,MAAA,CAAO,SAAS,KAAA,CAAM,aAAA;AAEtB,MAAA,MAAM,GAAA,GAAM,MAAA,CAAO,UAAA,CAAW,IAAI,CAAA;AAClC,MAAA,IAAI,CAAC,GAAA,EAAK;AACR,QAAA,MAAA,CAAO,IAAI,KAAA,CAAM,8BAA8B,CAAC,CAAA;AAChD,QAAA;AAAA,MACF;AAEA,MAAA,GAAA,CAAI,SAAA,CAAU,KAAA,EAAO,CAAA,EAAG,CAAC,CAAA;AACzB,MAAA,MAAM,MAAA,GAAS,MAAA,CAAO,SAAA,CAAU,IAAI,CAAA;AACpC,MAAA,OAAA,CAAQ,MAAM,CAAA;AAAA,IAChB,CAAA;AAEA,IAAA,KAAA,CAAM,OAAA,GAAU,CAAC,GAAA,KAAQ;AACvB,MAAA,MAAA,CAAO,IAAI,KAAA,CAAM,CAAA,sBAAA,EAAyB,OAAO,GAAG,CAAC,EAAE,CAAC,CAAA;AAAA,IAC1D,CAAA;AAEA,IAAA,KAAA,CAAM,GAAA,GAAM,GAAA;AAAA,EACd,CAAC,CAAA;AACH;AASO,IAAM,YAAA,GAAe,CAC1B,MAAA,EACA,QAAA,EACA,WAAmB,YAAA,KACV;AACT,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,KAAA,CAAM,GAAG,CAAA;AAChC,EAAA,MAAM,UAAA,GAAa,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAC,CAAA;AAClC,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,UAAA,CAAW,MAAM,CAAA;AAE9C,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,UAAA,CAAW,QAAQ,CAAA,EAAA,EAAK;AAC1C,IAAA,KAAA,CAAM,CAAC,CAAA,GAAI,UAAA,CAAW,UAAA,CAAW,CAAC,CAAA;AAAA,EACpC;AAEA,EAAA,OAAO,IAAI,KAAK,CAAC,KAAK,GAAG,QAAA,EAAU,EAAE,IAAA,EAAM,QAAA,EAAU,CAAA;AACvD;AAQO,IAAM,YAAA,GAAe,CAAC,MAAA,EAAgB,QAAA,GAAmB,YAAA,KAAuB;AACrF,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,KAAA,CAAM,GAAG,CAAA;AAChC,EAAA,MAAM,UAAA,GAAa,IAAA,CAAK,OAAA,CAAQ,CAAC,CAAC,CAAA;AAClC,EAAA,MAAM,KAAA,GAAQ,IAAI,UAAA,CAAW,UAAA,CAAW,MAAM,CAAA;AAE9C,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,UAAA,CAAW,QAAQ,CAAA,EAAA,EAAK;AAC1C,IAAA,KAAA,CAAM,CAAC,CAAA,GAAI,UAAA,CAAW,UAAA,CAAW,CAAC,CAAA;AAAA,EACpC;AAEA,EAAA,OAAO,IAAI,KAAK,CAAC,KAAK,GAAG,EAAE,IAAA,EAAM,UAAU,CAAA;AAC7C;AAUO,IAAM,eAAe,CAAC,GAAA,EAAa,QAAA,GAAmB,cAAA,EAAM,SAAS,KAAA,KAAgB;AAC1F,EAAA,MAAM,IAAA,GAAO,QAAA,CAAS,aAAA,CAAc,GAAG,CAAA;AACvC,EAAA,IAAA,CAAK,MAAM,OAAA,GAAU,MAAA;AACrB,EAAA,IAAA,CAAK,IAAA,GAAO,GAAA;AAEZ,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,IAAA,CAAK,MAAA,GAAS,QAAA;AAAA,EAChB,CAAA,MAAO;AACL,IAAA,IAAA,CAAK,YAAA,CAAa,YAAY,QAAQ,CAAA;AAAA,EACxC;AAEA,EAAA,QAAA,CAAS,IAAA,CAAK,YAAY,IAAI,CAAA;AAC9B,EAAA,IAAA,CAAK,KAAA,EAAM;AACX,EAAA,QAAA,CAAS,IAAA,CAAK,YAAY,IAAI,CAAA;AAChC;AAOO,IAAM,YAAA,GAAe,CAAC,IAAA,EAAY,QAAA,KAA2B;AAClE,EAAA,MAAM,GAAA,GAAM,GAAA,CAAI,eAAA,CAAgB,IAAI,CAAA;AACpC,EAAA,YAAA,CAAa,KAAK,QAAQ,CAAA;AAC1B,EAAA,GAAA,CAAI,gBAAgB,GAAG,CAAA;AACzB;AAQO,IAAM,cAAA,GAAiB,CAAC,MAAA,EAAgB,QAAA,EAAkB,WAAmB,YAAA,KAAuB;AACzG,EAAA,MAAM,IAAA,GAAO,YAAA,CAAa,MAAA,EAAQ,QAAQ,CAAA;AAC1C,EAAA,YAAA,CAAa,MAAM,QAAQ,CAAA;AAC7B;AASO,IAAM,eAAA,GAAkB,OAAO,IAAA,KAAmC;AACvE,EAAA,IAAI;AACF,IAAA,IAAI,SAAA,CAAU,SAAA,IAAa,SAAA,CAAU,SAAA,CAAU,SAAA,EAAW;AACxD,MAAA,MAAM,SAAA,CAAU,SAAA,CAAU,SAAA,CAAU,IAAI,CAAA;AACxC,MAAA,OAAO,IAAA;AAAA,IACT;AAGA,IAAA,MAAM,QAAA,GAAW,QAAA,CAAS,aAAA,CAAc,UAAU,CAAA;AAClD,IAAA,QAAA,CAAS,KAAA,GAAQ,IAAA;AACjB,IAAA,QAAA,CAAS,MAAM,QAAA,GAAW,OAAA;AAC1B,IAAA,QAAA,CAAS,MAAM,OAAA,GAAU,GAAA;AACzB,IAAA,QAAA,CAAS,IAAA,CAAK,YAAY,QAAQ,CAAA;AAClC,IAAA,QAAA,CAAS,MAAA,EAAO;AAChB,IAAA,MAAM,OAAA,GAAU,QAAA,CAAS,WAAA,CAAY,MAAM,CAAA;AAC3C,IAAA,QAAA,CAAS,IAAA,CAAK,YAAY,QAAQ,CAAA;AAClC,IAAA,OAAO,OAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAMO,IAAM,oBAAoB,YAA6B;AAC5D,EAAA,IAAI;AACF,IAAA,IAAI,SAAA,CAAU,SAAA,IAAa,SAAA,CAAU,SAAA,CAAU,QAAA,EAAU;AACvD,MAAA,OAAO,MAAM,SAAA,CAAU,SAAA,CAAU,QAAA,EAAS;AAAA,IAC5C;AAGA,IAAA,OAAO,EAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAA;AAAA,EACT;AACF","file":"utils.js","sourcesContent":["/**\n * 通用工具模块\n * 提供颜色转换、图片处理、文件下载、类型判断、数组/对象操作等通用功能\n */\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n// clone 函数的类型断言使用 any 是合理的\n\nimport { debounce, throttle, type DebouncedFunction, type ThrottledFunction } from 'es-toolkit'\n\n// ==================== 防抖与节流 ====================\n\n/**\n * 防抖函数(使用 es-toolkit)\n * @param fn 要防抖的函数\n * @param wait 等待时间(毫秒)\n * @returns 防抖后的函数\n */\nexport { debounce, type DebouncedFunction }\n\n/**\n * 节流函数(使用 es-toolkit)\n * @param fn 要节流的函数\n * @param wait 等待时间(毫秒)\n * @returns 节流后的函数\n */\nexport { throttle, type ThrottledFunction }\n\n// ==================== 对象深操作 ====================\n\n/**\n * 深度克隆对象\n * @param obj 要克隆的对象\n * @returns 克隆后的对象\n */\nexport const clone = <T>(obj: T): T => {\n if (obj === null || typeof obj !== 'object') {\n return obj\n }\n if (obj instanceof Date) {\n return new Date(obj.getTime()) as T\n }\n if (obj instanceof Array) {\n return obj.map((item) => clone(item)) as T\n }\n if (obj instanceof Object) {\n const copy = {} as T\n Object.keys(obj).forEach((key) => {\n ;(copy as any)[key] = clone((obj as any)[key])\n })\n return copy\n }\n return obj\n}\n\n/**\n * 深度比较两个对象是否相等\n * @param a 对象 a\n * @param b 对象 b\n * @returns 是否相等\n */\nexport const isEqual = (a: any, b: any): boolean => {\n if (a === b) return true\n if (a === null || b === null) return false\n if (typeof a !== typeof b) return false\n\n if (typeof a !== 'object') return a === b\n if (Array.isArray(a) !== Array.isArray(b)) return false\n\n if (Array.isArray(a)) {\n if (a.length !== b.length) return false\n for (let i = 0; i < a.length; i++) {\n if (!isEqual(a[i], b[i])) return false\n }\n return true\n }\n\n const keysA = Object.keys(a)\n const keysB = Object.keys(b)\n if (keysA.length !== keysB.length) return false\n\n for (const key of keysA) {\n if (!keysB.includes(key)) return false\n if (!isEqual(a[key], b[key])) return false\n }\n return true\n}\n\n/**\n * 深度合并对象\n * @param objects 要合并的对象\n * @returns 合并后的对象\n */\nexport const deepMerge = <T extends Record<string, any>>(...objects: Partial<T>[]): T => {\n const result = {} as T\n objects.forEach((obj) => {\n if (isObject(obj)) {\n Object.keys(obj).forEach((key) => {\n const value = obj[key]\n if (isObject(value) && isObject(result[key])) {\n ;(result as any)[key] = deepMerge(result[key], value)\n } else {\n ;(result as any)[key] = clone(value)\n }\n })\n }\n })\n return result\n}\n\n/**\n * 获取对象的路径值\n * @param obj 对象\n * @param path 路径(例如:'user.name')\n * @returns 路径对应的值\n */\nexport const get = (obj: any, path: string): any => {\n return path.split('.').reduce((acc, key) => acc?.[key], obj)\n}\n\n/**\n * 设置对象的路径值\n * @param obj 对象\n * @param path 路径(例如:'user.name')\n * @param value 要设置的值\n */\nexport const set = (obj: any, path: string, value: any): void => {\n const keys = path.split('.')\n const lastKey = keys.pop()!\n const target = keys.reduce((acc, key) => {\n if (!acc[key]) acc[key] = {}\n return acc[key]\n }, obj)\n target[lastKey] = value\n}\n\n/**\n * 省略对象中的某些属性\n * @param obj 对象\n * @param keys 要省略的键\n * @returns 省略后的对象\n */\nexport const omit = <T extends Record<string, any>, K extends keyof T>(\n obj: T,\n keys: K[]\n): Omit<T, K> => {\n const result = { ...obj }\n keys.forEach((key) => delete result[key])\n return result\n}\n\n/**\n * 选择对象中的某些属性\n * @param obj 对象\n * @param keys 要选择的键\n * @returns 选择后的对象\n */\nexport const pick = <T extends Record<string, any>, K extends keyof T>(\n obj: T,\n keys: K[]\n): Pick<T, K> => {\n const result = {} as Pick<T, K>\n keys.forEach((key) => {\n if (key in obj) {\n result[key] = obj[key]\n }\n })\n return result\n}\n\n// ==================== 类型判断 ====================\n\n/**\n * 判断是否为对象\n * @param value 要判断的值\n * @returns 是否为对象\n */\nexport const isObject = (value: any): value is Record<string, any> => {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n\n/**\n * 判断是否为数组\n * @param value 要判断的值\n * @returns 是否为数组\n */\nexport const isArray = (value: any): value is any[] => {\n return Array.isArray(value)\n}\n\n/**\n * 判断是否为字符串\n * @param value 要判断的值\n * @returns 是否为字符串\n */\nexport const isString = (value: any): value is string => {\n return typeof value === 'string'\n}\n\n/**\n * 判断是否为数字\n * @param value 要判断的值\n * @returns 是否为数字\n */\nexport const isNumber = (value: any): value is number => {\n return typeof value === 'number' && !isNaN(value)\n}\n\n/**\n * 判断是否为布尔值\n * @param value 要判断的值\n * @returns 是否为布尔值\n */\nexport const isBoolean = (value: any): value is boolean => {\n return typeof value === 'boolean'\n}\n\n/**\n * 判断是否为函数\n * @param value 要判断的值\n * @returns 是否为函数\n */\nexport const isFunction = (value: any): value is Function => {\n return typeof value === 'function'\n}\n\n/**\n * 判断是否为空值\n * @param value 要判断的值\n * @returns 是否为空\n */\nexport const isEmpty = (value: any): boolean => {\n if (value === null || value === undefined) return true\n if (isString(value) || Array.isArray(value)) return value.length === 0\n if (isObject(value)) return Object.keys(value).length === 0\n return false\n}\n\n// ==================== 数组操作 ====================\n\n/**\n * 数组去重\n * @param array 数组\n * @returns 去重后的数组\n */\nexport const uniq = <T>(array: T[]): T[] => {\n return [...new Set(array)]\n}\n\n/**\n * 数组排序\n * @param array 数组\n * @param key 排序键\n * @returns 排序后的数组\n */\nexport const sortBy = <T>(array: T[], key: keyof T | ((item: T) => any)): T[] => {\n const sortFn = typeof key === 'function' ? key : (item: T) => item[key]\n return [...array].sort((a, b) => {\n const valueA = sortFn(a)\n const valueB = sortFn(b)\n if (valueA < valueB) return -1\n if (valueA > valueB) return 1\n return 0\n })\n}\n\n/**\n * 数组分块\n * @param array 数组\n * @param size 分块大小\n * @returns 分块后的二维数组\n */\nexport const chunk = <T>(array: T[], size: number): T[][] => {\n const result: T[][] = []\n for (let i = 0; i < array.length; i += size) {\n result.push(array.slice(i, i + size))\n }\n return result\n}\n\n/**\n * 数组分组\n * @param array 数组\n * @param key 分组键\n * @returns 分组后的对象\n */\nexport const groupBy = <T>(\n array: T[],\n key: keyof T | ((item: T) => string)\n): Record<string, T[]> => {\n const groupFn = typeof key === 'function' ? key : (item: T) => String(item[key])\n return array.reduce(\n (result, item) => {\n const groupKey = groupFn(item)\n if (!result[groupKey]) {\n result[groupKey] = []\n }\n result[groupKey].push(item)\n return result\n },\n {} as Record<string, T[]>\n )\n}\n\n/**\n * 数组求和\n * @param array 数组\n * @returns 总和\n */\nexport const sum = (array: number[]): number => {\n return array.reduce((acc, num) => acc + num, 0)\n}\n\n/**\n * 数组平均值\n * @param array 数组\n * @returns 平均值\n */\nexport const avg = (array: number[]): number => {\n return array.length > 0 ? sum(array) / array.length : 0\n}\n\n/**\n * 数组最大值\n * @param array 数组\n * @returns 最大值\n */\nexport const max = (array: number[]): number => {\n return Math.max(...array)\n}\n\n/**\n * 数组最小值\n * @param array 数组\n * @returns 最小值\n */\nexport const min = (array: number[]): number => {\n return Math.min(...array)\n}\n\n// ==================== 字符串转换 ====================\n\n/**\n * 驼峰转下划线\n * @param str 字符串\n * @returns 转换后的字符串\n */\nexport const camelToSnake = (str: string): string => {\n return str.replace(/[A-Z]/g, (match) => `_${match.toLowerCase()}`)\n}\n\n/**\n * 下划线转驼峰\n * @param str 字符串\n * @returns 转换后的字符串\n */\nexport const snakeToCamel = (str: string): string => {\n return str.replace(/_([a-z])/g, (_, match) => match.toUpperCase())\n}\n\n/**\n * 首字母大写\n * @param str 字符串\n * @returns 转换后的字符串\n */\nexport const capitalize = (str: string): string => {\n return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase()\n}\n\n/**\n * 截断字符串\n * @param str 字符串\n * @param length 最大长度\n * @param suffix 后缀\n * @returns 截断后的字符串\n */\nexport const truncate = (str: string, length: number = 100, suffix: string = '...'): string => {\n if (str.length <= length) return str\n return `${str.slice(0, length)}${suffix}`\n}\n\n// ==================== 格式化函数 ====================\n\n/**\n * 格式化文件大小\n * @param bytes 字节数\n * @returns 格式化后的字符串\n */\nexport const formatFileSize = (bytes: number): string => {\n if (bytes === 0) return '0 B'\n const k = 1024\n const sizes = ['B', 'KB', 'MB', 'GB', 'TB']\n const i = Math.floor(Math.log(bytes) / Math.log(k))\n return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}`\n}\n\n/**\n * 格式化数字(千分位)\n * @param num 数字\n * @returns 格式化后的字符串\n */\nexport const formatNumber = (num: number): string => {\n return num.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',')\n}\n\n// ==================== 验证函数 ====================\n\n/**\n * 检查是否为有效的 URL\n * @param str 字符串\n * @returns 是否为有效 URL\n */\nexport const isValidUrl = (str: string): boolean => {\n try {\n new URL(str)\n return true\n } catch {\n return false\n }\n}\n\n/**\n * 检查是否为有效的邮箱\n * @param email 邮箱地址\n * @returns 是否为有效邮箱\n */\nexport const isValidEmail = (email: string): boolean => {\n const regex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/\n return regex.test(email)\n}\n\n/**\n * 检查是否为有效的手机号(中国)\n * @param phone 手机号\n * @returns 是否为有效手机号\n */\nexport const isValidPhone = (phone: string): boolean => {\n const regex = /^1[3-9]\\d{9}$/\n return regex.test(phone)\n}\n\n// ==================== 其他工具函数 ====================\n\n/**\n * 生成范围内的随机整数\n * @param min 最小值\n * @param max 最大值\n * @returns 随机整数\n */\nexport const randomInt = (min: number, max: number): number => {\n return Math.floor(Math.random() * (max - min + 1)) + min\n}\n\n/**\n * 生成唯一 ID\n * @param prefix 前缀\n * @returns 唯一 ID\n */\nexport const uniqueId = (prefix: string = ''): string => {\n return `${prefix}${Date.now()}-${Math.random().toString(36).substr(2, 9)}`\n}\n\n/**\n * 延迟执行\n * @param ms 延迟时间(毫秒)\n * @returns Promise\n */\nexport const delay = (ms: number): Promise<void> => {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\n/**\n * 重试函数\n * @param fn 要执行的函数\n * @param retries 重试次数\n * @param delayMs 重试延迟\n * @returns Promise\n */\nexport const retry = async <T>(\n fn: () => Promise<T>,\n retries: number = 3,\n delayMs: number = 1000\n): Promise<T> => {\n try {\n return await fn()\n } catch (error) {\n if (retries <= 0) {\n throw error\n }\n await delay(delayMs)\n return retry(fn, retries - 1, delayMs)\n }\n}\n\n// ==================== 颜色转换 ====================\n\n/**\n * Hex 颜色转 RGB 颜色\n * @param str Hex 颜色(如 #FFFFFF 或 FFFFFF)\n * @returns RGB 颜色数组 [r, g, b]\n */\nexport const hexToRgb = (str: string): number[] | null => {\n const hexRegex = /^#?([0-9A-Fa-f]{6})$/\n if (!hexRegex.test(str)) {\n return null\n }\n\n const hex = str.replace('#', '')\n const r = parseInt(hex.substring(0, 2), 16)\n const g = parseInt(hex.substring(2, 4), 16)\n const b = parseInt(hex.substring(4, 6), 16)\n\n return [r, g, b]\n}\n\n/**\n * Hex 颜色转 RGB 字符串\n * @param str Hex 颜色(如 #FFFFFF 或 FFFFFF)\n * @returns RGB 字符串(如 rgb(255, 255, 255))\n */\nexport const hexToRgbString = (str: string): string | null => {\n const rgb = hexToRgb(str)\n if (!rgb) {\n return null\n }\n return `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`\n}\n\n/**\n * RGB 颜色转 Hex 颜色\n * @param r 红色值 (0-255)\n * @param g 绿色值 (0-255)\n * @param b 蓝色值 (0-255)\n * @returns Hex 颜色字符串(如 #FFFFFF)\n */\nexport const rgbToHex = (r: number, g: number, b: number): string | null => {\n const numRegex = /^\\d{1,3}$/\n if (!numRegex.test(r.toString()) || !numRegex.test(g.toString()) || !numRegex.test(b.toString())) {\n return null\n }\n\n if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) {\n return null\n }\n\n const toHex = (num: number): string => {\n const hex = num.toString(16)\n return hex.length === 1 ? `0${hex}` : hex\n }\n\n return `#${toHex(r)}${toHex(g)}${toHex(b)}`\n}\n\n/**\n * RGB 颜色转 Hex 颜色(数组版本)\n * @param rgb RGB 数组 [r, g, b]\n * @returns Hex 颜色字符串(如 #FFFFFF)\n */\nexport const rgbArrayToHex = (rgb: number[]): string | null => {\n if (rgb.length !== 3) {\n return null\n }\n return rgbToHex(rgb[0], rgb[1], rgb[2])\n}\n\n/**\n * 变浅颜色值\n * @param color Hex 颜色(如 #FFFFFF 或 FFFFFF)\n * @param alpha 透明度因子 (0-1),值越大颜色越浅\n * @returns 变浅后的 Hex 颜色\n */\nexport const getLightColor = (color: string, alpha: number): string | null => {\n const rgb = hexToRgb(color)\n if (!rgb) {\n return null\n }\n\n const [r, g, b] = rgb\n const newR = Math.floor((255 - r) * alpha + r)\n const newG = Math.floor((255 - g) * alpha + g)\n const newB = Math.floor((255 - b) * alpha + b)\n\n return rgbToHex(newR, newG, newB)\n}\n\n/**\n * 变深颜色值\n * @param color Hex 颜色(如 #FFFFFF 或 FFFFFF)\n * @param alpha 暗化因子 (0-1),值越大颜色越深\n * @returns 变深后的 Hex 颜色\n */\nexport const getDarkColor = (color: string, alpha: number): string | null => {\n const rgb = hexToRgb(color)\n if (!rgb) {\n return null\n }\n\n const [r, g, b] = rgb\n const newR = Math.floor(r * (1 - alpha))\n const newG = Math.floor(g * (1 - alpha))\n const newB = Math.floor(b * (1 - alpha))\n\n return rgbToHex(newR, newG, newB)\n}\n\n// ==================== 图片处理 ====================\n\n/**\n * 图片转 Base64\n * @param url 图片 URL\n * @param type 图片类型(默认 image/png)\n * @returns Base64 字符串\n */\nexport const imgToBase64 = (url: string, type: 'image/jpeg' | 'image/png' = 'image/png'): Promise<string> => {\n return new Promise((resolve, reject) => {\n const image = new Image()\n image.crossOrigin = 'anonymous'\n\n image.onload = () => {\n const canvas = document.createElement('canvas')\n canvas.width = image.naturalWidth\n canvas.height = image.naturalHeight\n\n const ctx = canvas.getContext('2d')\n if (!ctx) {\n reject(new Error('Failed to get canvas context'))\n return\n }\n\n ctx.drawImage(image, 0, 0)\n const base64 = canvas.toDataURL(type)\n resolve(base64)\n }\n\n image.onerror = (err) => {\n reject(new Error(`Failed to load image: ${String(err)}`))\n }\n\n image.src = url\n })\n}\n\n/**\n * Base64 转 File 对象\n * @param base64 Base64 字符串\n * @param fileName 文件名\n * @param mimeType MIME 类型(默认 image/jpeg)\n * @returns File 对象\n */\nexport const base64toFile = (\n base64: string,\n fileName: string,\n mimeType: string = 'image/jpeg'\n): File => {\n const dataArr = base64.split(',')\n const byteString = atob(dataArr[1])\n const u8Arr = new Uint8Array(byteString.length)\n\n for (let i = 0; i < byteString.length; i++) {\n u8Arr[i] = byteString.charCodeAt(i)\n }\n\n return new File([u8Arr], fileName, { type: mimeType })\n}\n\n/**\n * Base64 转 Blob 对象\n * @param base64 Base64 字符串\n * @param mimeType MIME 类型\n * @returns Blob 对象\n */\nexport const base64toBlob = (base64: string, mimeType: string = 'image/jpeg'): Blob => {\n const dataArr = base64.split(',')\n const byteString = atob(dataArr[1])\n const u8Arr = new Uint8Array(byteString.length)\n\n for (let i = 0; i < byteString.length; i++) {\n u8Arr[i] = byteString.charCodeAt(i)\n }\n\n return new Blob([u8Arr], { type: mimeType })\n}\n\n// ==================== 文件下载 ====================\n\n/**\n * 下载文件\n * @param url 文件 URL 或 Data URL\n * @param fileName 文件名\n * @param target 是否在新标签页打开(默认 false)\n */\nexport const downloadFile = (url: string, fileName: string = '文件', target = false): void => {\n const link = document.createElement('a')\n link.style.display = 'none'\n link.href = url\n\n if (target) {\n link.target = '_blank'\n } else {\n link.setAttribute('download', fileName)\n }\n\n document.body.appendChild(link)\n link.click()\n document.body.removeChild(link)\n}\n\n/**\n * 下载 Blob 文件\n * @param blob Blob 对象\n * @param fileName 文件名\n */\nexport const downloadBlob = (blob: Blob, fileName: string): void => {\n const url = URL.createObjectURL(blob)\n downloadFile(url, fileName)\n URL.revokeObjectURL(url)\n}\n\n/**\n * 下载 Base64 文件\n * @param base64 Base64 字符串\n * @param fileName 文件名\n * @param mimeType MIME 类型\n */\nexport const downloadBase64 = (base64: string, fileName: string, mimeType: string = 'image/jpeg'): void => {\n const blob = base64toBlob(base64, mimeType)\n downloadBlob(blob, fileName)\n}\n\n// ==================== 剪贴板操作 ====================\n\n/**\n * 复制文本到剪贴板\n * @param text 要复制的文本\n * @returns 是否成功\n */\nexport const copyToClipboard = async (text: string): Promise<boolean> => {\n try {\n if (navigator.clipboard && navigator.clipboard.writeText) {\n await navigator.clipboard.writeText(text)\n return true\n }\n\n // 降级方案\n const textarea = document.createElement('textarea')\n textarea.value = text\n textarea.style.position = 'fixed'\n textarea.style.opacity = '0'\n document.body.appendChild(textarea)\n textarea.select()\n const success = document.execCommand('copy')\n document.body.removeChild(textarea)\n return success\n } catch {\n return false\n }\n}\n\n/**\n * 从剪贴板读取文本\n * @returns 剪贴板文本\n */\nexport const readFromClipboard = async (): Promise<string> => {\n try {\n if (navigator.clipboard && navigator.clipboard.readText) {\n return await navigator.clipboard.readText()\n }\n\n // 降级方案(需要用户权限)\n return ''\n } catch {\n return ''\n }\n}\n"]}
|