🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

@snack-kit/lib

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@snack-kit/lib - npm Package Compare versions

Comparing version
0.2.0
to
0.3.0
+264
dist/cjs/chunk-U6KYHCBL.cjs
'use strict';
// src/utils/detect.ts
var _toString = (val) => Object.prototype.toString.call(val);
var IsNumber = (val) => !isNaN(parseFloat(val)) && isFinite(val);
var IsRealNumber = (val) => typeof val === "number" && !isNaN(val);
var IsString = (val) => _toString(val) === "[object String]";
var IsBoolean = (val) => _toString(val) === "[object Boolean]";
var IsArray = (val) => Array.isArray(val);
var IsFunction = (val) => _toString(val) === "[object Function]";
var IsObject = (val) => _toString(val) === "[object Object]";
var IsNull = (val) => val === null || val === void 0 || val === "";
var IsEqual = (a, b) => {
if (a === b) return true;
if (typeof a !== typeof b) return false;
if (a === null || b === null) return false;
if (typeof a !== "object") return false;
if (Array.isArray(a) !== Array.isArray(b)) return false;
const keysA = Object.keys(a);
const keysB = Object.keys(b);
if (keysA.length !== keysB.length) return false;
for (const key of keysA) {
if (!IsEqual(a[key], b[key])) {
return false;
}
}
return true;
};
// src/utils/validate.ts
var REGEX = {
/** 手机号(宽松:13-19 开头) */
phone: /^(?:(?:\+|00)86)?1[3-9]\d{9}$/,
/** 手机号(严谨,基于工信部 2019 年最新公布号段) */
strictPhone: /^(?:(?:\+|00)86)?1(?:(?:3\d)|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8\d)|(?:9[189]))\d{8}$/,
/** 邮箱(符合 RFC 标准) */
email: /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-_0-9]+\.)+[a-zA-Z]{2,}))$/,
/** URL(支持 http / https / ftp) */
url: /^(https?|ftp):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:/~+#]*[\w\-@?^=%&/~+#])?/,
/** IPv4 地址 */
ipv4: /^((25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/,
/** 整数(含负数和零) */
integer: /^[+-]?\d+$/,
/** 正整数(不含零) */
positiveInteger: /^[1-9]\d*$/,
/** 二代身份证 */
idcard: /^[1-9]\d{5}(?:18|19|20)\d{2}(?:0[1-9]|10|11|12)(?:0[1-9]|[1-2]\d|30|31)\d{3}[\dXx]$/,
/** 日期(宽松,如 2022-9-1) */
date: /^\d{1,4}-(1[0-2]|0?[1-9])-(0?[1-9]|[1-2]\d|30|31)$/,
/** 16 进制颜色值 */
color: /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/
};
var IsEmail = (val) => REGEX.email.test(val);
var IsPhone = (val) => REGEX.phone.test(val);
var IsUrl = (val) => REGEX.url.test(val);
var IsIpv4 = (val) => REGEX.ipv4.test(val);
var IsInteger = (val) => REGEX.integer.test(val);
var IsPositiveInteger = (val) => REGEX.positiveInteger.test(val);
// src/utils/array.ts
var Unique = (arr) => [...new Set(arr)];
var UniqueByKey = (arr, key) => {
const seen = /* @__PURE__ */ new Set();
const result = [];
for (const item of arr) {
const k = item[key];
if (!seen.has(k)) {
seen.add(k);
result.push(item);
}
}
return result;
};
var Minus = (arr, other) => {
const otherSet = new Set(other);
return arr.filter((item) => !otherSet.has(item));
};
// src/utils/object.ts
var DeepClone = (obj) => {
if (typeof structuredClone === "function") {
return structuredClone(obj);
}
return JSON.parse(JSON.stringify(obj));
};
var CleanObject = (obj) => {
const result = {};
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
const val = obj[key];
if (val !== null && val !== void 0) {
result[key] = val;
}
}
}
return result;
};
var Pick = (obj, keys) => {
const result = {};
for (const key of keys) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
result[key] = obj[key];
}
}
return result;
};
var Omit = (obj, keys) => {
const excludeSet = new Set(keys);
const result = {};
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key) && !excludeSet.has(key)) {
result[key] = obj[key];
}
}
return result;
};
// src/utils/func.ts
var Debounce = (fn, delay = 300) => {
let timer = null;
return function(...args) {
if (timer !== null) clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, args);
timer = null;
}, delay);
};
};
var Throttle = (fn, delay = 50) => {
let lastTime = 0;
return function(...args) {
const now = Date.now();
if (now - lastTime >= delay) {
lastTime = now;
fn.apply(this, args);
}
};
};
var Delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
// src/utils/string.ts
var UUID = () => {
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
return crypto.randomUUID();
}
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
const arr = new Uint8Array(1);
crypto.getRandomValues(arr);
const r = arr[0] & 15;
const v = c === "x" ? r : r & 3 | 8;
return v.toString(16);
});
};
var GetURLParam = (name, url = typeof window !== "undefined" ? window.location.href : "") => {
try {
return new URL(url).searchParams.get(name) ?? "";
} catch {
return "";
}
};
var GetURLParams = (url = typeof window !== "undefined" ? window.location.href : "") => {
try {
const result = {};
new URL(url).searchParams.forEach((val, key) => {
result[key] = val;
});
return result;
} catch {
return {};
}
};
var ObjectToQuery = (obj) => {
const params = new URLSearchParams();
for (const [key, val] of Object.entries(obj)) {
if (val !== null && val !== void 0) {
params.append(key, String(val));
}
}
const str = params.toString();
return str ? `?${str}` : "";
};
var QueryToObject = (query) => {
const str = query.startsWith("?") ? query.slice(1) : query;
const result = {};
new URLSearchParams(str).forEach((val, key) => {
result[key] = val;
});
return result;
};
// src/utils/time.ts
var FormatDate = (date = /* @__PURE__ */ new Date(), format = "yyyy-MM-dd HH:mm:ss") => {
const d = date instanceof Date ? date : new Date(date);
if (isNaN(d.getTime())) return "";
const map = {
"M+": d.getMonth() + 1,
"d+": d.getDate(),
"H+": d.getHours(),
"m+": d.getMinutes(),
"s+": d.getSeconds()
};
let result = format.replace(
/(y+)/,
(_, p) => String(d.getFullYear()).slice(4 - p.length)
);
for (const [pattern, value] of Object.entries(map)) {
result = result.replace(
new RegExp(`(${pattern})`),
(_, p) => String(value).padStart(p.length, "0")
);
}
return result;
};
var GetDateOffset = (date = /* @__PURE__ */ new Date(), days = 0, format = "yyyy-MM-dd HH:mm:ss") => {
const d = new Date(date.getTime());
d.setDate(d.getDate() + days);
return FormatDate(d, format);
};
var GetDayRange = (date = /* @__PURE__ */ new Date()) => {
const y = date.getFullYear();
const m = date.getMonth();
const d = date.getDate();
return {
start: new Date(y, m, d, 0, 0, 0, 0).getTime(),
end: new Date(y, m, d, 23, 59, 59, 999).getTime()
};
};
exports.CleanObject = CleanObject;
exports.Debounce = Debounce;
exports.DeepClone = DeepClone;
exports.Delay = Delay;
exports.FormatDate = FormatDate;
exports.GetDateOffset = GetDateOffset;
exports.GetDayRange = GetDayRange;
exports.GetURLParam = GetURLParam;
exports.GetURLParams = GetURLParams;
exports.IsArray = IsArray;
exports.IsBoolean = IsBoolean;
exports.IsEmail = IsEmail;
exports.IsEqual = IsEqual;
exports.IsFunction = IsFunction;
exports.IsInteger = IsInteger;
exports.IsIpv4 = IsIpv4;
exports.IsNull = IsNull;
exports.IsNumber = IsNumber;
exports.IsObject = IsObject;
exports.IsPhone = IsPhone;
exports.IsPositiveInteger = IsPositiveInteger;
exports.IsRealNumber = IsRealNumber;
exports.IsString = IsString;
exports.IsUrl = IsUrl;
exports.Minus = Minus;
exports.ObjectToQuery = ObjectToQuery;
exports.Omit = Omit;
exports.Pick = Pick;
exports.QueryToObject = QueryToObject;
exports.REGEX = REGEX;
exports.Throttle = Throttle;
exports.UUID = UUID;
exports.Unique = Unique;
exports.UniqueByKey = UniqueByKey;
//# sourceMappingURL=chunk-U6KYHCBL.cjs.map
//# sourceMappingURL=chunk-U6KYHCBL.cjs.map
{"version":3,"sources":["../../src/utils/detect.ts","../../src/utils/validate.ts","../../src/utils/array.ts","../../src/utils/object.ts","../../src/utils/func.ts","../../src/utils/string.ts","../../src/utils/time.ts"],"names":[],"mappings":"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","file":"chunk-U6KYHCBL.cjs","sourcesContent":["/**\n * 类型检测工具\n *\n * 统一使用 Object.prototype.toString 确保跨环境准确性,\n * 规避 typeof null === 'object' 等已知陷阱。\n */\n\nconst _toString = (val: unknown): string => Object.prototype.toString.call(val)\n\n/**\n * 是否为数字(含可转换的字符串数字,如 '42'、'3.14')\n * @example IsNumber(42) // true\n * @example IsNumber('42') // true\n * @example IsNumber('abc') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsNumber = (val: unknown): boolean =>\n !isNaN(parseFloat(val as string)) && isFinite(val as number)\n\n/**\n * 是否为严格数字类型(不含字符串数字)\n * @example IsRealNumber(42) // true\n * @example IsRealNumber('42') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsRealNumber = (val: unknown): val is number =>\n typeof val === 'number' && !isNaN(val)\n\n/**\n * 是否为字符串\n * @example IsString('hello') // true\n * @example IsString(new String('hello')) // true\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsString = (val: unknown): val is string =>\n _toString(val) === '[object String]'\n\n/**\n * 是否为布尔值\n * @example IsBoolean(true) // true\n * @example IsBoolean(1) // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsBoolean = (val: unknown): val is boolean =>\n _toString(val) === '[object Boolean]'\n\n/**\n * 是否为数组\n * @example IsArray([1, 2]) // true\n * @example IsArray({}) // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3.5+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsArray = (val: unknown): val is unknown[] => Array.isArray(val)\n\n/**\n * 是否为函数\n * @example IsFunction(() => {}) // true\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsFunction = (val: unknown): val is (...args: unknown[]) => unknown =>\n _toString(val) === '[object Function]'\n\n/**\n * 是否为普通对象(排除 null 和数组)\n * @example IsObject({}) // true\n * @example IsObject([]) // false\n * @example IsObject(null) // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsObject = (val: unknown): val is Record<string, unknown> =>\n _toString(val) === '[object Object]'\n\n/**\n * 是否为空值(null / undefined / 空字符串)\n * @example IsNull(null) // true\n * @example IsNull(undefined) // true\n * @example IsNull('') // true\n * @example IsNull(0) // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsNull = (val: unknown): boolean =>\n val === null || val === undefined || val === ''\n\n/**\n * 深度相等比较,支持对象和数组的递归比较。\n *\n * 注意:仅比较自身可枚举属性,不比较原型链上的属性。\n * 不支持 Map、Set、Date、RegExp 等特殊对象的深度比较。\n * @example IsEqual({ a: 1 }, { a: 1 }) // true\n * @example IsEqual([1, 2], [1, 2]) // true\n * @example IsEqual({ a: 1 }, { a: 2 }) // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsEqual = (a: unknown, b: unknown): boolean => {\n if (a === b) return true\n if (typeof a !== typeof b) return false\n if (a === null || b === null) return false\n if (typeof a !== 'object') return false\n // 数组与普通对象不相等\n if (Array.isArray(a) !== Array.isArray(b)) return false\n\n const keysA = Object.keys(a as object)\n const keysB = Object.keys(b as object)\n if (keysA.length !== keysB.length) return false\n\n for (const key of keysA) {\n if (!IsEqual((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key])) {\n return false\n }\n }\n return true\n}\n","/**\n * 输入校验工具 + 常用正则常量\n */\n\n/**\n * 常用正则规则常量,来源参考 any-rule(https://github.com/any86/any-rule)\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const REGEX = {\n /** 手机号(宽松:13-19 开头) */\n phone: /^(?:(?:\\+|00)86)?1[3-9]\\d{9}$/,\n /** 手机号(严谨,基于工信部 2019 年最新公布号段) */\n strictPhone: /^(?:(?:\\+|00)86)?1(?:(?:3\\d)|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8\\d)|(?:9[189]))\\d{8}$/,\n /** 邮箱(符合 RFC 标准) */\n email: /^(([^<>()[\\]\\\\.,;:\\s@\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-_0-9]+\\.)+[a-zA-Z]{2,}))$/,\n /** URL(支持 http / https / ftp) */\n url: /^(https?|ftp):\\/\\/[\\w\\-]+(\\.[\\w\\-]+)+([\\w\\-.,@?^=%&:/~+#]*[\\w\\-@?^=%&/~+#])?/,\n /** IPv4 地址 */\n ipv4: /^((25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)\\.){3}(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)$/,\n /** 整数(含负数和零) */\n integer: /^[+-]?\\d+$/,\n /** 正整数(不含零) */\n positiveInteger: /^[1-9]\\d*$/,\n /** 二代身份证 */\n idcard: /^[1-9]\\d{5}(?:18|19|20)\\d{2}(?:0[1-9]|10|11|12)(?:0[1-9]|[1-2]\\d|30|31)\\d{3}[\\dXx]$/,\n /** 日期(宽松,如 2022-9-1) */\n date: /^\\d{1,4}-(1[0-2]|0?[1-9])-(0?[1-9]|[1-2]\\d|30|31)$/,\n /** 16 进制颜色值 */\n color: /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/,\n} as const\n\n/**\n * 是否为合法邮箱地址\n * @example IsEmail('user@example.com') // true\n * @example IsEmail('invalid') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsEmail = (val: string): boolean => REGEX.email.test(val)\n\n/**\n * 是否为中国大陆手机号(宽松校验)\n * @example IsPhone('13812345678') // true\n * @example IsPhone('12345678901') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsPhone = (val: string): boolean => REGEX.phone.test(val)\n\n/**\n * 是否为合法 URL\n * @example IsUrl('https://example.com') // true\n * @example IsUrl('not-a-url') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsUrl = (val: string): boolean => REGEX.url.test(val)\n\n/**\n * 是否为合法 IPv4 地址\n * @example IsIpv4('192.168.1.1') // true\n * @example IsIpv4('999.0.0.1') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsIpv4 = (val: string): boolean => REGEX.ipv4.test(val)\n\n/**\n * 是否为整数(含负数和零)\n * @example IsInteger('42') // true\n * @example IsInteger('-10') // true\n * @example IsInteger('3.14') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsInteger = (val: string): boolean => REGEX.integer.test(val)\n\n/**\n * 是否为正整数(不含零)\n * @example IsPositiveInteger('1') // true\n * @example IsPositiveInteger('0') // false\n * @example IsPositiveInteger('-1') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsPositiveInteger = (val: string): boolean => REGEX.positiveInteger.test(val)\n","/**\n * 数组工具\n */\n\n/**\n * 数组去重(基于 Set,时间复杂度 O(n))\n * @example Unique([1, 2, 1, 3]) // [1, 2, 3]\n * @remarks\n * 浏览器兼容性:Chrome 38+ · Firefox 13+ · Safari 7.1+ · Node.js 0.12+\n *\n * 依赖 `Set`(ES2015)。\n */\nexport const Unique = <T>(arr: T[]): T[] => [...new Set(arr)]\n\n/**\n * 按对象指定 key 的值去重,保留首次出现的元素\n * @param arr 待去重数组\n * @param key 用于去重的对象属性名\n * @example\n * UniqueByKey([{ id: 1, name: 'a' }, { id: 1, name: 'b' }], 'id')\n * // [{ id: 1, name: 'a' }]\n * @remarks\n * 浏览器兼容性:Chrome 38+ · Firefox 13+ · Safari 7.1+ · Node.js 0.12+\n *\n * 依赖 `Set`(ES2015)。\n */\nexport const UniqueByKey = <T extends object>(arr: T[], key: keyof T): T[] => {\n const seen = new Set<unknown>()\n const result: T[] = []\n for (const item of arr) {\n const k = item[key]\n if (!seen.has(k)) {\n seen.add(k)\n result.push(item)\n }\n }\n return result\n}\n\n/**\n * 差集:返回只在 arr 中存在、不在 other 中存在的元素(基于 Set,时间复杂度 O(n))\n * @param arr 基础数组\n * @param other 比较数组\n * @example Minus([1, 2, 3], [2, 3, 4]) // [1]\n * @remarks\n * 浏览器兼容性:Chrome 38+ · Firefox 13+ · Safari 7.1+ · Node.js 0.12+\n *\n * 依赖 `Set`(ES2015)。\n */\nexport const Minus = <T>(arr: T[], other: T[]): T[] => {\n const otherSet = new Set(other)\n return arr.filter(item => !otherSet.has(item))\n}\n","/**\n * 对象工具\n */\n\n/**\n * 深拷贝对象或数组。\n *\n * 优先使用原生 `structuredClone`(支持 Date、RegExp、Map、Set、循环引用等),\n * 降级为 JSON 序列化(不支持 undefined、函数、循环引用)。\n * @example DeepClone({ a: { b: 1 } }) // { a: { b: 1 } }(新对象)\n * @remarks\n * 浏览器兼容性:\n * - `structuredClone`(优先):Chrome 98+ · Firefox 94+ · Safari 15.4+ · Node.js 17.0+\n * - JSON 降级(自动回退):Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n *\n * 在不支持 `structuredClone` 的环境中自动降级为 `JSON.parse(JSON.stringify(obj))`,\n * 降级时不支持 `undefined`、函数、`Date`、`RegExp`、循环引用。\n */\nexport const DeepClone = <T>(obj: T): T => {\n if (typeof structuredClone === 'function') {\n return structuredClone(obj)\n }\n // 降级:仅适用于纯 JSON 可序列化的数据\n return JSON.parse(JSON.stringify(obj)) as T\n}\n\n/**\n * 删除对象中值为 null 或 undefined 的属性,返回新对象(不修改原对象)。\n *\n * 注意:空字符串、false、0 等假值不会被删除。\n * @example CleanObject({ a: 1, b: null, c: undefined }) // { a: 1 }\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const CleanObject = <T extends object>(obj: T): Partial<T> => {\n const result = {} as Partial<T>\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n const val = obj[key]\n if (val !== null && val !== undefined) {\n result[key] = val\n }\n }\n }\n return result\n}\n\n/**\n * 按 key 列表提取对象子集,返回新对象(类型安全)。\n * @example Pick({ a: 1, b: 2, c: 3 }, ['a', 'c']) // { a: 1, c: 3 }\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const Pick = <T extends object, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> => {\n const result = {} as Pick<T, K>\n for (const key of keys) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n result[key] = obj[key]\n }\n }\n return result\n}\n\n/**\n * 排除指定 key 后返回新对象(类型安全)。\n * @example Omit({ a: 1, b: 2, c: 3 }, ['b']) // { a: 1, c: 3 }\n * @remarks\n * 浏览器兼容性:Chrome 38+ · Firefox 13+ · Safari 7.1+ · Node.js 0.12+\n *\n * 依赖 `Set`(ES2015)。\n */\nexport const Omit = <T extends object, K extends keyof T>(obj: T, keys: K[]): Omit<T, K> => {\n const excludeSet = new Set<keyof T>(keys)\n const result = {} as Omit<T, K>\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key) && !excludeSet.has(key as keyof T)) {\n (result as Record<string, unknown>)[key] = obj[key]\n }\n }\n return result\n}\n","/**\n * 函数工具\n */\n\n/**\n * 防抖:在最后一次调用后等待 delay 毫秒再执行(trailing edge)。\n *\n * 适合搜索输入、窗口 resize、表单提交等场景。\n * @param fn 要防抖的函数\n * @param delay 延迟毫秒数,默认 300ms\n * @example\n * const handleInput = Debounce((val: string) => search(val), 500)\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n *\n * 依赖 `setTimeout` / `clearTimeout`,全平台支持。\n */\nexport const Debounce = <T extends (...args: Parameters<T>) => ReturnType<T>>(\n fn: T,\n delay = 300\n): ((...args: Parameters<T>) => void) => {\n let timer: ReturnType<typeof setTimeout> | null = null\n return function (this: ThisParameterType<T>, ...args: Parameters<T>) {\n if (timer !== null) clearTimeout(timer)\n timer = setTimeout(() => {\n fn.apply(this, args)\n timer = null\n }, delay)\n }\n}\n\n/**\n * 节流:在 delay 毫秒内最多执行一次(leading edge,时间戳实现)。\n *\n * 适合滚动监听、mousemove、高频点击等场景。\n * @param fn 要节流的函数\n * @param delay 节流间隔毫秒数,默认 50ms\n * @example\n * const handleScroll = Throttle(() => updatePosition(), 100)\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n *\n * 依赖 `Date.now()`,无 `setTimeout` 悬空回调风险。\n */\nexport const Throttle = <T extends (...args: Parameters<T>) => ReturnType<T>>(\n fn: T,\n delay = 50\n): ((...args: Parameters<T>) => void) => {\n let lastTime = 0\n return function (this: ThisParameterType<T>, ...args: Parameters<T>) {\n const now = Date.now()\n if (now - lastTime >= delay) {\n lastTime = now\n fn.apply(this, args)\n }\n }\n}\n\n/**\n * Promise 延迟:等待指定毫秒数后 resolve。\n * @param ms 延迟毫秒数\n * @example await Delay(1000) // 等待 1 秒\n * @remarks\n * 浏览器兼容性:Chrome 32+ · Firefox 29+ · Safari 8+ · Node.js 0.12+\n *\n * 依赖 `Promise`(ES2015)和 `setTimeout`。\n */\nexport const Delay = (ms: number): Promise<void> =>\n new Promise(resolve => setTimeout(resolve, ms))\n","/**\n * 字符串 / UUID / URL 工具\n */\n\n/**\n * 生成标准 RFC 4122 v4 UUID。\n *\n * 优先使用 `crypto.randomUUID()`(现代浏览器 / Node.js 19+),\n * 降级为基于 `crypto.getRandomValues` 的手动实现。\n * @example UUID() // 'f47ac10b-58cc-4372-a567-0e02b2c3d479'\n * @remarks\n * 浏览器兼容性:\n * - `crypto.randomUUID()`(优先):Chrome 92+ · Firefox 95+ · Safari 15.4+ · Node.js 19.0+\n * - `crypto.getRandomValues` 降级:Chrome 11+ · Firefox 21+ · Safari 6.1+ · Node.js 15.0+\n *\n * Node.js 14.17+ 可通过 `import { randomUUID } from 'crypto'` 单独使用,\n * 但全局 `crypto` 对象需 Node.js 15.0+ 才可用。\n */\nexport const UUID = (): string => {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID()\n }\n // 降级:RFC 4122 v4,使用 crypto.getRandomValues 保证随机性\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const arr = new Uint8Array(1)\n crypto.getRandomValues(arr)\n const r = arr[0] & 0xf\n const v = c === 'x' ? r : (r & 0x3) | 0x8\n return v.toString(16)\n })\n}\n\n/**\n * 从 URL 中获取指定查询参数的值,不存在则返回空字符串。\n * @param name 参数名\n * @param url 目标 URL,默认取 `window.location.href`\n * @example GetURLParam('page', 'https://example.com?page=2&size=10') // '2'\n * @remarks\n * 浏览器兼容性:Chrome 49+ · Firefox 44+ · Safari 10.1+ · Node.js 10.0+\n *\n * 依赖 `URL` API 和 `URLSearchParams`(WHATWG URL Standard)。\n * 若 URL 格式非法会静默返回空字符串。\n */\nexport const GetURLParam = (\n name: string,\n url: string = typeof window !== 'undefined' ? window.location.href : ''\n): string => {\n try {\n return new URL(url).searchParams.get(name) ?? ''\n } catch {\n return ''\n }\n}\n\n/**\n * 获取 URL 中所有查询参数,以键值对对象返回。\n *\n * 若同名参数出现多次,取最后一个值。\n * @param url 目标 URL,默认取 `window.location.href`\n * @example GetURLParams('https://example.com?a=1&b=2') // { a: '1', b: '2' }\n * @remarks\n * 浏览器兼容性:Chrome 49+ · Firefox 44+ · Safari 10.1+ · Node.js 10.0+\n *\n * 依赖 `URL` API 和 `URLSearchParams`(WHATWG URL Standard)。\n * 若 URL 格式非法会静默返回空对象。\n */\nexport const GetURLParams = (\n url: string = typeof window !== 'undefined' ? window.location.href : ''\n): Record<string, string> => {\n try {\n const result: Record<string, string> = {}\n new URL(url).searchParams.forEach((val, key) => {\n result[key] = val\n })\n return result\n } catch {\n return {}\n }\n}\n\n/**\n * 将对象转换为 URL 查询字符串(以 `?` 开头)。\n *\n * 值为 null / undefined 的属性会被跳过,特殊字符自动编码。\n * @example ObjectToQuery({ page: 1, size: 10 }) // '?page=1&size=10'\n * @example ObjectToQuery({}) // ''\n * @remarks\n * 浏览器兼容性:Chrome 49+ · Firefox 44+ · Safari 10.1+ · Node.js 10.0+\n *\n * 依赖 `URLSearchParams`(WHATWG URL Standard)。\n * 空格编码为 `+`(application/x-www-form-urlencoded 规范),\n * 与 `encodeURIComponent` 的 `%20` 编码略有差异。\n */\nexport const ObjectToQuery = (obj: Record<string, unknown>): string => {\n const params = new URLSearchParams()\n for (const [key, val] of Object.entries(obj)) {\n if (val !== null && val !== undefined) {\n params.append(key, String(val))\n }\n }\n const str = params.toString()\n return str ? `?${str}` : ''\n}\n\n/**\n * 将查询字符串解析为键值对对象。\n *\n * 支持以 `?` 开头或不以 `?` 开头的格式,自动解码编码字符。\n * @example QueryToObject('?a=1&b=hello%20world') // { a: '1', b: 'hello world' }\n * @remarks\n * 浏览器兼容性:Chrome 49+ · Firefox 44+ · Safari 10.1+ · Node.js 10.0+\n *\n * 依赖 `URLSearchParams`(WHATWG URL Standard)。\n */\nexport const QueryToObject = (query: string): Record<string, string> => {\n const str = query.startsWith('?') ? query.slice(1) : query\n const result: Record<string, string> = {}\n new URLSearchParams(str).forEach((val, key) => {\n result[key] = val\n })\n return result\n}\n","/**\n * 时间日期工具\n */\n\n/**\n * 格式化日期时间。\n *\n * 支持占位符:`yyyy`(年)、`MM`(月)、`dd`(日)、`HH`(24 小时制小时)、`mm`(分钟)、`ss`(秒)。\n * @param date 日期,默认当前时间,支持 Date 对象、日期字符串、时间戳\n * @param format 格式字符串,默认 `'yyyy-MM-dd HH:mm:ss'`\n * @example FormatDate(new Date('2024-01-05 09:05:03')) // '2024-01-05 09:05:03'\n * @example FormatDate(new Date('2024-01-05'), 'yyyy/MM/dd') // '2024/01/05'\n * @example FormatDate(new Date('2024-01-05'), 'yy-MM-dd') // '24-01-05'\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n *\n * 依赖原生 `Date` API,全平台支持。\n * 传入非法日期字符串时返回空字符串。\n */\nexport const FormatDate = (\n date: Date | string | number = new Date(),\n format = 'yyyy-MM-dd HH:mm:ss'\n): string => {\n const d = date instanceof Date ? date : new Date(date)\n if (isNaN(d.getTime())) return ''\n\n const map: Record<string, number> = {\n 'M+': d.getMonth() + 1,\n 'd+': d.getDate(),\n 'H+': d.getHours(),\n 'm+': d.getMinutes(),\n 's+': d.getSeconds(),\n }\n\n // 年份单独处理(支持 yy / yyyy)\n let result = format.replace(/(y+)/, (_, p: string) =>\n String(d.getFullYear()).slice(4 - p.length)\n )\n\n for (const [pattern, value] of Object.entries(map)) {\n result = result.replace(new RegExp(`(${pattern})`), (_, p: string) =>\n String(value).padStart(p.length, '0')\n )\n }\n\n return result\n}\n\n/**\n * 获取指定日期偏移 N 天后的日期字符串。\n *\n * 正数表示往后,负数表示往前。不修改传入的 Date 对象。\n * @param date 基准日期,默认当前时间\n * @param days 偏移天数(正数往后,负数往前)\n * @param format 格式字符串,默认 `'yyyy-MM-dd HH:mm:ss'`\n * @example GetDateOffset(new Date('2024-01-10'), 3, 'yyyy-MM-dd') // '2024-01-13'\n * @example GetDateOffset(new Date('2024-01-10'), -3, 'yyyy-MM-dd') // '2024-01-07'\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n *\n * 依赖原生 `Date` API,全平台支持。\n */\nexport const GetDateOffset = (\n date: Date = new Date(),\n days = 0,\n format = 'yyyy-MM-dd HH:mm:ss'\n): string => {\n const d = new Date(date.getTime())\n d.setDate(d.getDate() + days)\n return FormatDate(d, format)\n}\n\n/**\n * 获取指定日期当天的开始时间戳(00:00:00.000)和结束时间戳(23:59:59.999)。\n * @param date 指定日期,默认当前时间\n * @example GetDayRange(new Date('2024-01-05'))\n * // { start: 1704384000000, end: 1704470399999 }\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n *\n * 依赖原生 `Date` API,全平台支持。\n * 时间戳基于本地时区计算。\n */\nexport const GetDayRange = (\n date: Date = new Date()\n): { start: number; end: number } => {\n const y = date.getFullYear()\n const m = date.getMonth()\n const d = date.getDate()\n return {\n start: new Date(y, m, d, 0, 0, 0, 0).getTime(),\n end: new Date(y, m, d, 23, 59, 59, 999).getTime(),\n }\n}\n"]}
'use strict';
var chunkU6KYHCBL_cjs = require('./chunk-U6KYHCBL.cjs');
Object.defineProperty(exports, "CleanObject", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.CleanObject; }
});
Object.defineProperty(exports, "Debounce", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.Debounce; }
});
Object.defineProperty(exports, "DeepClone", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.DeepClone; }
});
Object.defineProperty(exports, "Delay", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.Delay; }
});
Object.defineProperty(exports, "FormatDate", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.FormatDate; }
});
Object.defineProperty(exports, "GetDateOffset", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.GetDateOffset; }
});
Object.defineProperty(exports, "GetDayRange", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.GetDayRange; }
});
Object.defineProperty(exports, "GetURLParam", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.GetURLParam; }
});
Object.defineProperty(exports, "GetURLParams", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.GetURLParams; }
});
Object.defineProperty(exports, "IsArray", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.IsArray; }
});
Object.defineProperty(exports, "IsBoolean", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.IsBoolean; }
});
Object.defineProperty(exports, "IsEmail", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.IsEmail; }
});
Object.defineProperty(exports, "IsEqual", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.IsEqual; }
});
Object.defineProperty(exports, "IsFunction", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.IsFunction; }
});
Object.defineProperty(exports, "IsInteger", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.IsInteger; }
});
Object.defineProperty(exports, "IsIpv4", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.IsIpv4; }
});
Object.defineProperty(exports, "IsNull", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.IsNull; }
});
Object.defineProperty(exports, "IsNumber", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.IsNumber; }
});
Object.defineProperty(exports, "IsObject", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.IsObject; }
});
Object.defineProperty(exports, "IsPhone", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.IsPhone; }
});
Object.defineProperty(exports, "IsPositiveInteger", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.IsPositiveInteger; }
});
Object.defineProperty(exports, "IsRealNumber", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.IsRealNumber; }
});
Object.defineProperty(exports, "IsString", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.IsString; }
});
Object.defineProperty(exports, "IsUrl", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.IsUrl; }
});
Object.defineProperty(exports, "Minus", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.Minus; }
});
Object.defineProperty(exports, "ObjectToQuery", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.ObjectToQuery; }
});
Object.defineProperty(exports, "Omit", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.Omit; }
});
Object.defineProperty(exports, "Pick", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.Pick; }
});
Object.defineProperty(exports, "QueryToObject", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.QueryToObject; }
});
Object.defineProperty(exports, "REGEX", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.REGEX; }
});
Object.defineProperty(exports, "Throttle", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.Throttle; }
});
Object.defineProperty(exports, "UUID", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.UUID; }
});
Object.defineProperty(exports, "Unique", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.Unique; }
});
Object.defineProperty(exports, "UniqueByKey", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.UniqueByKey; }
});
//# sourceMappingURL=utils.cjs.map
//# sourceMappingURL=utils.cjs.map
{"version":3,"sources":[],"names":[],"mappings":"","file":"utils.cjs"}
// src/utils/detect.ts
var _toString = (val) => Object.prototype.toString.call(val);
var IsNumber = (val) => !isNaN(parseFloat(val)) && isFinite(val);
var IsRealNumber = (val) => typeof val === "number" && !isNaN(val);
var IsString = (val) => _toString(val) === "[object String]";
var IsBoolean = (val) => _toString(val) === "[object Boolean]";
var IsArray = (val) => Array.isArray(val);
var IsFunction = (val) => _toString(val) === "[object Function]";
var IsObject = (val) => _toString(val) === "[object Object]";
var IsNull = (val) => val === null || val === void 0 || val === "";
var IsEqual = (a, b) => {
if (a === b) return true;
if (typeof a !== typeof b) return false;
if (a === null || b === null) return false;
if (typeof a !== "object") return false;
if (Array.isArray(a) !== Array.isArray(b)) return false;
const keysA = Object.keys(a);
const keysB = Object.keys(b);
if (keysA.length !== keysB.length) return false;
for (const key of keysA) {
if (!IsEqual(a[key], b[key])) {
return false;
}
}
return true;
};
// src/utils/validate.ts
var REGEX = {
/** 手机号(宽松:13-19 开头) */
phone: /^(?:(?:\+|00)86)?1[3-9]\d{9}$/,
/** 手机号(严谨,基于工信部 2019 年最新公布号段) */
strictPhone: /^(?:(?:\+|00)86)?1(?:(?:3\d)|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8\d)|(?:9[189]))\d{8}$/,
/** 邮箱(符合 RFC 标准) */
email: /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-_0-9]+\.)+[a-zA-Z]{2,}))$/,
/** URL(支持 http / https / ftp) */
url: /^(https?|ftp):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:/~+#]*[\w\-@?^=%&/~+#])?/,
/** IPv4 地址 */
ipv4: /^((25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/,
/** 整数(含负数和零) */
integer: /^[+-]?\d+$/,
/** 正整数(不含零) */
positiveInteger: /^[1-9]\d*$/,
/** 二代身份证 */
idcard: /^[1-9]\d{5}(?:18|19|20)\d{2}(?:0[1-9]|10|11|12)(?:0[1-9]|[1-2]\d|30|31)\d{3}[\dXx]$/,
/** 日期(宽松,如 2022-9-1) */
date: /^\d{1,4}-(1[0-2]|0?[1-9])-(0?[1-9]|[1-2]\d|30|31)$/,
/** 16 进制颜色值 */
color: /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/
};
var IsEmail = (val) => REGEX.email.test(val);
var IsPhone = (val) => REGEX.phone.test(val);
var IsUrl = (val) => REGEX.url.test(val);
var IsIpv4 = (val) => REGEX.ipv4.test(val);
var IsInteger = (val) => REGEX.integer.test(val);
var IsPositiveInteger = (val) => REGEX.positiveInteger.test(val);
// src/utils/array.ts
var Unique = (arr) => [...new Set(arr)];
var UniqueByKey = (arr, key) => {
const seen = /* @__PURE__ */ new Set();
const result = [];
for (const item of arr) {
const k = item[key];
if (!seen.has(k)) {
seen.add(k);
result.push(item);
}
}
return result;
};
var Minus = (arr, other) => {
const otherSet = new Set(other);
return arr.filter((item) => !otherSet.has(item));
};
// src/utils/object.ts
var DeepClone = (obj) => {
if (typeof structuredClone === "function") {
return structuredClone(obj);
}
return JSON.parse(JSON.stringify(obj));
};
var CleanObject = (obj) => {
const result = {};
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
const val = obj[key];
if (val !== null && val !== void 0) {
result[key] = val;
}
}
}
return result;
};
var Pick = (obj, keys) => {
const result = {};
for (const key of keys) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
result[key] = obj[key];
}
}
return result;
};
var Omit = (obj, keys) => {
const excludeSet = new Set(keys);
const result = {};
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key) && !excludeSet.has(key)) {
result[key] = obj[key];
}
}
return result;
};
// src/utils/func.ts
var Debounce = (fn, delay = 300) => {
let timer = null;
return function(...args) {
if (timer !== null) clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, args);
timer = null;
}, delay);
};
};
var Throttle = (fn, delay = 50) => {
let lastTime = 0;
return function(...args) {
const now = Date.now();
if (now - lastTime >= delay) {
lastTime = now;
fn.apply(this, args);
}
};
};
var Delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
// src/utils/string.ts
var UUID = () => {
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
return crypto.randomUUID();
}
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
const arr = new Uint8Array(1);
crypto.getRandomValues(arr);
const r = arr[0] & 15;
const v = c === "x" ? r : r & 3 | 8;
return v.toString(16);
});
};
var GetURLParam = (name, url = typeof window !== "undefined" ? window.location.href : "") => {
try {
return new URL(url).searchParams.get(name) ?? "";
} catch {
return "";
}
};
var GetURLParams = (url = typeof window !== "undefined" ? window.location.href : "") => {
try {
const result = {};
new URL(url).searchParams.forEach((val, key) => {
result[key] = val;
});
return result;
} catch {
return {};
}
};
var ObjectToQuery = (obj) => {
const params = new URLSearchParams();
for (const [key, val] of Object.entries(obj)) {
if (val !== null && val !== void 0) {
params.append(key, String(val));
}
}
const str = params.toString();
return str ? `?${str}` : "";
};
var QueryToObject = (query) => {
const str = query.startsWith("?") ? query.slice(1) : query;
const result = {};
new URLSearchParams(str).forEach((val, key) => {
result[key] = val;
});
return result;
};
// src/utils/time.ts
var FormatDate = (date = /* @__PURE__ */ new Date(), format = "yyyy-MM-dd HH:mm:ss") => {
const d = date instanceof Date ? date : new Date(date);
if (isNaN(d.getTime())) return "";
const map = {
"M+": d.getMonth() + 1,
"d+": d.getDate(),
"H+": d.getHours(),
"m+": d.getMinutes(),
"s+": d.getSeconds()
};
let result = format.replace(
/(y+)/,
(_, p) => String(d.getFullYear()).slice(4 - p.length)
);
for (const [pattern, value] of Object.entries(map)) {
result = result.replace(
new RegExp(`(${pattern})`),
(_, p) => String(value).padStart(p.length, "0")
);
}
return result;
};
var GetDateOffset = (date = /* @__PURE__ */ new Date(), days = 0, format = "yyyy-MM-dd HH:mm:ss") => {
const d = new Date(date.getTime());
d.setDate(d.getDate() + days);
return FormatDate(d, format);
};
var GetDayRange = (date = /* @__PURE__ */ new Date()) => {
const y = date.getFullYear();
const m = date.getMonth();
const d = date.getDate();
return {
start: new Date(y, m, d, 0, 0, 0, 0).getTime(),
end: new Date(y, m, d, 23, 59, 59, 999).getTime()
};
};
export { CleanObject, Debounce, DeepClone, Delay, FormatDate, GetDateOffset, GetDayRange, GetURLParam, GetURLParams, IsArray, IsBoolean, IsEmail, IsEqual, IsFunction, IsInteger, IsIpv4, IsNull, IsNumber, IsObject, IsPhone, IsPositiveInteger, IsRealNumber, IsString, IsUrl, Minus, ObjectToQuery, Omit, Pick, QueryToObject, REGEX, Throttle, UUID, Unique, UniqueByKey };
//# sourceMappingURL=chunk-WJX5Q3WL.js.map
//# sourceMappingURL=chunk-WJX5Q3WL.js.map
{"version":3,"sources":["../../src/utils/detect.ts","../../src/utils/validate.ts","../../src/utils/array.ts","../../src/utils/object.ts","../../src/utils/func.ts","../../src/utils/string.ts","../../src/utils/time.ts"],"names":[],"mappings":"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","file":"chunk-WJX5Q3WL.js","sourcesContent":["/**\n * 类型检测工具\n *\n * 统一使用 Object.prototype.toString 确保跨环境准确性,\n * 规避 typeof null === 'object' 等已知陷阱。\n */\n\nconst _toString = (val: unknown): string => Object.prototype.toString.call(val)\n\n/**\n * 是否为数字(含可转换的字符串数字,如 '42'、'3.14')\n * @example IsNumber(42) // true\n * @example IsNumber('42') // true\n * @example IsNumber('abc') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsNumber = (val: unknown): boolean =>\n !isNaN(parseFloat(val as string)) && isFinite(val as number)\n\n/**\n * 是否为严格数字类型(不含字符串数字)\n * @example IsRealNumber(42) // true\n * @example IsRealNumber('42') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsRealNumber = (val: unknown): val is number =>\n typeof val === 'number' && !isNaN(val)\n\n/**\n * 是否为字符串\n * @example IsString('hello') // true\n * @example IsString(new String('hello')) // true\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsString = (val: unknown): val is string =>\n _toString(val) === '[object String]'\n\n/**\n * 是否为布尔值\n * @example IsBoolean(true) // true\n * @example IsBoolean(1) // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsBoolean = (val: unknown): val is boolean =>\n _toString(val) === '[object Boolean]'\n\n/**\n * 是否为数组\n * @example IsArray([1, 2]) // true\n * @example IsArray({}) // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3.5+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsArray = (val: unknown): val is unknown[] => Array.isArray(val)\n\n/**\n * 是否为函数\n * @example IsFunction(() => {}) // true\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsFunction = (val: unknown): val is (...args: unknown[]) => unknown =>\n _toString(val) === '[object Function]'\n\n/**\n * 是否为普通对象(排除 null 和数组)\n * @example IsObject({}) // true\n * @example IsObject([]) // false\n * @example IsObject(null) // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsObject = (val: unknown): val is Record<string, unknown> =>\n _toString(val) === '[object Object]'\n\n/**\n * 是否为空值(null / undefined / 空字符串)\n * @example IsNull(null) // true\n * @example IsNull(undefined) // true\n * @example IsNull('') // true\n * @example IsNull(0) // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsNull = (val: unknown): boolean =>\n val === null || val === undefined || val === ''\n\n/**\n * 深度相等比较,支持对象和数组的递归比较。\n *\n * 注意:仅比较自身可枚举属性,不比较原型链上的属性。\n * 不支持 Map、Set、Date、RegExp 等特殊对象的深度比较。\n * @example IsEqual({ a: 1 }, { a: 1 }) // true\n * @example IsEqual([1, 2], [1, 2]) // true\n * @example IsEqual({ a: 1 }, { a: 2 }) // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsEqual = (a: unknown, b: unknown): boolean => {\n if (a === b) return true\n if (typeof a !== typeof b) return false\n if (a === null || b === null) return false\n if (typeof a !== 'object') return false\n // 数组与普通对象不相等\n if (Array.isArray(a) !== Array.isArray(b)) return false\n\n const keysA = Object.keys(a as object)\n const keysB = Object.keys(b as object)\n if (keysA.length !== keysB.length) return false\n\n for (const key of keysA) {\n if (!IsEqual((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key])) {\n return false\n }\n }\n return true\n}\n","/**\n * 输入校验工具 + 常用正则常量\n */\n\n/**\n * 常用正则规则常量,来源参考 any-rule(https://github.com/any86/any-rule)\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const REGEX = {\n /** 手机号(宽松:13-19 开头) */\n phone: /^(?:(?:\\+|00)86)?1[3-9]\\d{9}$/,\n /** 手机号(严谨,基于工信部 2019 年最新公布号段) */\n strictPhone: /^(?:(?:\\+|00)86)?1(?:(?:3\\d)|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8\\d)|(?:9[189]))\\d{8}$/,\n /** 邮箱(符合 RFC 标准) */\n email: /^(([^<>()[\\]\\\\.,;:\\s@\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-_0-9]+\\.)+[a-zA-Z]{2,}))$/,\n /** URL(支持 http / https / ftp) */\n url: /^(https?|ftp):\\/\\/[\\w\\-]+(\\.[\\w\\-]+)+([\\w\\-.,@?^=%&:/~+#]*[\\w\\-@?^=%&/~+#])?/,\n /** IPv4 地址 */\n ipv4: /^((25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)\\.){3}(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)$/,\n /** 整数(含负数和零) */\n integer: /^[+-]?\\d+$/,\n /** 正整数(不含零) */\n positiveInteger: /^[1-9]\\d*$/,\n /** 二代身份证 */\n idcard: /^[1-9]\\d{5}(?:18|19|20)\\d{2}(?:0[1-9]|10|11|12)(?:0[1-9]|[1-2]\\d|30|31)\\d{3}[\\dXx]$/,\n /** 日期(宽松,如 2022-9-1) */\n date: /^\\d{1,4}-(1[0-2]|0?[1-9])-(0?[1-9]|[1-2]\\d|30|31)$/,\n /** 16 进制颜色值 */\n color: /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/,\n} as const\n\n/**\n * 是否为合法邮箱地址\n * @example IsEmail('user@example.com') // true\n * @example IsEmail('invalid') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsEmail = (val: string): boolean => REGEX.email.test(val)\n\n/**\n * 是否为中国大陆手机号(宽松校验)\n * @example IsPhone('13812345678') // true\n * @example IsPhone('12345678901') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsPhone = (val: string): boolean => REGEX.phone.test(val)\n\n/**\n * 是否为合法 URL\n * @example IsUrl('https://example.com') // true\n * @example IsUrl('not-a-url') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsUrl = (val: string): boolean => REGEX.url.test(val)\n\n/**\n * 是否为合法 IPv4 地址\n * @example IsIpv4('192.168.1.1') // true\n * @example IsIpv4('999.0.0.1') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsIpv4 = (val: string): boolean => REGEX.ipv4.test(val)\n\n/**\n * 是否为整数(含负数和零)\n * @example IsInteger('42') // true\n * @example IsInteger('-10') // true\n * @example IsInteger('3.14') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsInteger = (val: string): boolean => REGEX.integer.test(val)\n\n/**\n * 是否为正整数(不含零)\n * @example IsPositiveInteger('1') // true\n * @example IsPositiveInteger('0') // false\n * @example IsPositiveInteger('-1') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsPositiveInteger = (val: string): boolean => REGEX.positiveInteger.test(val)\n","/**\n * 数组工具\n */\n\n/**\n * 数组去重(基于 Set,时间复杂度 O(n))\n * @example Unique([1, 2, 1, 3]) // [1, 2, 3]\n * @remarks\n * 浏览器兼容性:Chrome 38+ · Firefox 13+ · Safari 7.1+ · Node.js 0.12+\n *\n * 依赖 `Set`(ES2015)。\n */\nexport const Unique = <T>(arr: T[]): T[] => [...new Set(arr)]\n\n/**\n * 按对象指定 key 的值去重,保留首次出现的元素\n * @param arr 待去重数组\n * @param key 用于去重的对象属性名\n * @example\n * UniqueByKey([{ id: 1, name: 'a' }, { id: 1, name: 'b' }], 'id')\n * // [{ id: 1, name: 'a' }]\n * @remarks\n * 浏览器兼容性:Chrome 38+ · Firefox 13+ · Safari 7.1+ · Node.js 0.12+\n *\n * 依赖 `Set`(ES2015)。\n */\nexport const UniqueByKey = <T extends object>(arr: T[], key: keyof T): T[] => {\n const seen = new Set<unknown>()\n const result: T[] = []\n for (const item of arr) {\n const k = item[key]\n if (!seen.has(k)) {\n seen.add(k)\n result.push(item)\n }\n }\n return result\n}\n\n/**\n * 差集:返回只在 arr 中存在、不在 other 中存在的元素(基于 Set,时间复杂度 O(n))\n * @param arr 基础数组\n * @param other 比较数组\n * @example Minus([1, 2, 3], [2, 3, 4]) // [1]\n * @remarks\n * 浏览器兼容性:Chrome 38+ · Firefox 13+ · Safari 7.1+ · Node.js 0.12+\n *\n * 依赖 `Set`(ES2015)。\n */\nexport const Minus = <T>(arr: T[], other: T[]): T[] => {\n const otherSet = new Set(other)\n return arr.filter(item => !otherSet.has(item))\n}\n","/**\n * 对象工具\n */\n\n/**\n * 深拷贝对象或数组。\n *\n * 优先使用原生 `structuredClone`(支持 Date、RegExp、Map、Set、循环引用等),\n * 降级为 JSON 序列化(不支持 undefined、函数、循环引用)。\n * @example DeepClone({ a: { b: 1 } }) // { a: { b: 1 } }(新对象)\n * @remarks\n * 浏览器兼容性:\n * - `structuredClone`(优先):Chrome 98+ · Firefox 94+ · Safari 15.4+ · Node.js 17.0+\n * - JSON 降级(自动回退):Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n *\n * 在不支持 `structuredClone` 的环境中自动降级为 `JSON.parse(JSON.stringify(obj))`,\n * 降级时不支持 `undefined`、函数、`Date`、`RegExp`、循环引用。\n */\nexport const DeepClone = <T>(obj: T): T => {\n if (typeof structuredClone === 'function') {\n return structuredClone(obj)\n }\n // 降级:仅适用于纯 JSON 可序列化的数据\n return JSON.parse(JSON.stringify(obj)) as T\n}\n\n/**\n * 删除对象中值为 null 或 undefined 的属性,返回新对象(不修改原对象)。\n *\n * 注意:空字符串、false、0 等假值不会被删除。\n * @example CleanObject({ a: 1, b: null, c: undefined }) // { a: 1 }\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const CleanObject = <T extends object>(obj: T): Partial<T> => {\n const result = {} as Partial<T>\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n const val = obj[key]\n if (val !== null && val !== undefined) {\n result[key] = val\n }\n }\n }\n return result\n}\n\n/**\n * 按 key 列表提取对象子集,返回新对象(类型安全)。\n * @example Pick({ a: 1, b: 2, c: 3 }, ['a', 'c']) // { a: 1, c: 3 }\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const Pick = <T extends object, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> => {\n const result = {} as Pick<T, K>\n for (const key of keys) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n result[key] = obj[key]\n }\n }\n return result\n}\n\n/**\n * 排除指定 key 后返回新对象(类型安全)。\n * @example Omit({ a: 1, b: 2, c: 3 }, ['b']) // { a: 1, c: 3 }\n * @remarks\n * 浏览器兼容性:Chrome 38+ · Firefox 13+ · Safari 7.1+ · Node.js 0.12+\n *\n * 依赖 `Set`(ES2015)。\n */\nexport const Omit = <T extends object, K extends keyof T>(obj: T, keys: K[]): Omit<T, K> => {\n const excludeSet = new Set<keyof T>(keys)\n const result = {} as Omit<T, K>\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key) && !excludeSet.has(key as keyof T)) {\n (result as Record<string, unknown>)[key] = obj[key]\n }\n }\n return result\n}\n","/**\n * 函数工具\n */\n\n/**\n * 防抖:在最后一次调用后等待 delay 毫秒再执行(trailing edge)。\n *\n * 适合搜索输入、窗口 resize、表单提交等场景。\n * @param fn 要防抖的函数\n * @param delay 延迟毫秒数,默认 300ms\n * @example\n * const handleInput = Debounce((val: string) => search(val), 500)\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n *\n * 依赖 `setTimeout` / `clearTimeout`,全平台支持。\n */\nexport const Debounce = <T extends (...args: Parameters<T>) => ReturnType<T>>(\n fn: T,\n delay = 300\n): ((...args: Parameters<T>) => void) => {\n let timer: ReturnType<typeof setTimeout> | null = null\n return function (this: ThisParameterType<T>, ...args: Parameters<T>) {\n if (timer !== null) clearTimeout(timer)\n timer = setTimeout(() => {\n fn.apply(this, args)\n timer = null\n }, delay)\n }\n}\n\n/**\n * 节流:在 delay 毫秒内最多执行一次(leading edge,时间戳实现)。\n *\n * 适合滚动监听、mousemove、高频点击等场景。\n * @param fn 要节流的函数\n * @param delay 节流间隔毫秒数,默认 50ms\n * @example\n * const handleScroll = Throttle(() => updatePosition(), 100)\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n *\n * 依赖 `Date.now()`,无 `setTimeout` 悬空回调风险。\n */\nexport const Throttle = <T extends (...args: Parameters<T>) => ReturnType<T>>(\n fn: T,\n delay = 50\n): ((...args: Parameters<T>) => void) => {\n let lastTime = 0\n return function (this: ThisParameterType<T>, ...args: Parameters<T>) {\n const now = Date.now()\n if (now - lastTime >= delay) {\n lastTime = now\n fn.apply(this, args)\n }\n }\n}\n\n/**\n * Promise 延迟:等待指定毫秒数后 resolve。\n * @param ms 延迟毫秒数\n * @example await Delay(1000) // 等待 1 秒\n * @remarks\n * 浏览器兼容性:Chrome 32+ · Firefox 29+ · Safari 8+ · Node.js 0.12+\n *\n * 依赖 `Promise`(ES2015)和 `setTimeout`。\n */\nexport const Delay = (ms: number): Promise<void> =>\n new Promise(resolve => setTimeout(resolve, ms))\n","/**\n * 字符串 / UUID / URL 工具\n */\n\n/**\n * 生成标准 RFC 4122 v4 UUID。\n *\n * 优先使用 `crypto.randomUUID()`(现代浏览器 / Node.js 19+),\n * 降级为基于 `crypto.getRandomValues` 的手动实现。\n * @example UUID() // 'f47ac10b-58cc-4372-a567-0e02b2c3d479'\n * @remarks\n * 浏览器兼容性:\n * - `crypto.randomUUID()`(优先):Chrome 92+ · Firefox 95+ · Safari 15.4+ · Node.js 19.0+\n * - `crypto.getRandomValues` 降级:Chrome 11+ · Firefox 21+ · Safari 6.1+ · Node.js 15.0+\n *\n * Node.js 14.17+ 可通过 `import { randomUUID } from 'crypto'` 单独使用,\n * 但全局 `crypto` 对象需 Node.js 15.0+ 才可用。\n */\nexport const UUID = (): string => {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID()\n }\n // 降级:RFC 4122 v4,使用 crypto.getRandomValues 保证随机性\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const arr = new Uint8Array(1)\n crypto.getRandomValues(arr)\n const r = arr[0] & 0xf\n const v = c === 'x' ? r : (r & 0x3) | 0x8\n return v.toString(16)\n })\n}\n\n/**\n * 从 URL 中获取指定查询参数的值,不存在则返回空字符串。\n * @param name 参数名\n * @param url 目标 URL,默认取 `window.location.href`\n * @example GetURLParam('page', 'https://example.com?page=2&size=10') // '2'\n * @remarks\n * 浏览器兼容性:Chrome 49+ · Firefox 44+ · Safari 10.1+ · Node.js 10.0+\n *\n * 依赖 `URL` API 和 `URLSearchParams`(WHATWG URL Standard)。\n * 若 URL 格式非法会静默返回空字符串。\n */\nexport const GetURLParam = (\n name: string,\n url: string = typeof window !== 'undefined' ? window.location.href : ''\n): string => {\n try {\n return new URL(url).searchParams.get(name) ?? ''\n } catch {\n return ''\n }\n}\n\n/**\n * 获取 URL 中所有查询参数,以键值对对象返回。\n *\n * 若同名参数出现多次,取最后一个值。\n * @param url 目标 URL,默认取 `window.location.href`\n * @example GetURLParams('https://example.com?a=1&b=2') // { a: '1', b: '2' }\n * @remarks\n * 浏览器兼容性:Chrome 49+ · Firefox 44+ · Safari 10.1+ · Node.js 10.0+\n *\n * 依赖 `URL` API 和 `URLSearchParams`(WHATWG URL Standard)。\n * 若 URL 格式非法会静默返回空对象。\n */\nexport const GetURLParams = (\n url: string = typeof window !== 'undefined' ? window.location.href : ''\n): Record<string, string> => {\n try {\n const result: Record<string, string> = {}\n new URL(url).searchParams.forEach((val, key) => {\n result[key] = val\n })\n return result\n } catch {\n return {}\n }\n}\n\n/**\n * 将对象转换为 URL 查询字符串(以 `?` 开头)。\n *\n * 值为 null / undefined 的属性会被跳过,特殊字符自动编码。\n * @example ObjectToQuery({ page: 1, size: 10 }) // '?page=1&size=10'\n * @example ObjectToQuery({}) // ''\n * @remarks\n * 浏览器兼容性:Chrome 49+ · Firefox 44+ · Safari 10.1+ · Node.js 10.0+\n *\n * 依赖 `URLSearchParams`(WHATWG URL Standard)。\n * 空格编码为 `+`(application/x-www-form-urlencoded 规范),\n * 与 `encodeURIComponent` 的 `%20` 编码略有差异。\n */\nexport const ObjectToQuery = (obj: Record<string, unknown>): string => {\n const params = new URLSearchParams()\n for (const [key, val] of Object.entries(obj)) {\n if (val !== null && val !== undefined) {\n params.append(key, String(val))\n }\n }\n const str = params.toString()\n return str ? `?${str}` : ''\n}\n\n/**\n * 将查询字符串解析为键值对对象。\n *\n * 支持以 `?` 开头或不以 `?` 开头的格式,自动解码编码字符。\n * @example QueryToObject('?a=1&b=hello%20world') // { a: '1', b: 'hello world' }\n * @remarks\n * 浏览器兼容性:Chrome 49+ · Firefox 44+ · Safari 10.1+ · Node.js 10.0+\n *\n * 依赖 `URLSearchParams`(WHATWG URL Standard)。\n */\nexport const QueryToObject = (query: string): Record<string, string> => {\n const str = query.startsWith('?') ? query.slice(1) : query\n const result: Record<string, string> = {}\n new URLSearchParams(str).forEach((val, key) => {\n result[key] = val\n })\n return result\n}\n","/**\n * 时间日期工具\n */\n\n/**\n * 格式化日期时间。\n *\n * 支持占位符:`yyyy`(年)、`MM`(月)、`dd`(日)、`HH`(24 小时制小时)、`mm`(分钟)、`ss`(秒)。\n * @param date 日期,默认当前时间,支持 Date 对象、日期字符串、时间戳\n * @param format 格式字符串,默认 `'yyyy-MM-dd HH:mm:ss'`\n * @example FormatDate(new Date('2024-01-05 09:05:03')) // '2024-01-05 09:05:03'\n * @example FormatDate(new Date('2024-01-05'), 'yyyy/MM/dd') // '2024/01/05'\n * @example FormatDate(new Date('2024-01-05'), 'yy-MM-dd') // '24-01-05'\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n *\n * 依赖原生 `Date` API,全平台支持。\n * 传入非法日期字符串时返回空字符串。\n */\nexport const FormatDate = (\n date: Date | string | number = new Date(),\n format = 'yyyy-MM-dd HH:mm:ss'\n): string => {\n const d = date instanceof Date ? date : new Date(date)\n if (isNaN(d.getTime())) return ''\n\n const map: Record<string, number> = {\n 'M+': d.getMonth() + 1,\n 'd+': d.getDate(),\n 'H+': d.getHours(),\n 'm+': d.getMinutes(),\n 's+': d.getSeconds(),\n }\n\n // 年份单独处理(支持 yy / yyyy)\n let result = format.replace(/(y+)/, (_, p: string) =>\n String(d.getFullYear()).slice(4 - p.length)\n )\n\n for (const [pattern, value] of Object.entries(map)) {\n result = result.replace(new RegExp(`(${pattern})`), (_, p: string) =>\n String(value).padStart(p.length, '0')\n )\n }\n\n return result\n}\n\n/**\n * 获取指定日期偏移 N 天后的日期字符串。\n *\n * 正数表示往后,负数表示往前。不修改传入的 Date 对象。\n * @param date 基准日期,默认当前时间\n * @param days 偏移天数(正数往后,负数往前)\n * @param format 格式字符串,默认 `'yyyy-MM-dd HH:mm:ss'`\n * @example GetDateOffset(new Date('2024-01-10'), 3, 'yyyy-MM-dd') // '2024-01-13'\n * @example GetDateOffset(new Date('2024-01-10'), -3, 'yyyy-MM-dd') // '2024-01-07'\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n *\n * 依赖原生 `Date` API,全平台支持。\n */\nexport const GetDateOffset = (\n date: Date = new Date(),\n days = 0,\n format = 'yyyy-MM-dd HH:mm:ss'\n): string => {\n const d = new Date(date.getTime())\n d.setDate(d.getDate() + days)\n return FormatDate(d, format)\n}\n\n/**\n * 获取指定日期当天的开始时间戳(00:00:00.000)和结束时间戳(23:59:59.999)。\n * @param date 指定日期,默认当前时间\n * @example GetDayRange(new Date('2024-01-05'))\n * // { start: 1704384000000, end: 1704470399999 }\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n *\n * 依赖原生 `Date` API,全平台支持。\n * 时间戳基于本地时区计算。\n */\nexport const GetDayRange = (\n date: Date = new Date()\n): { start: number; end: number } => {\n const y = date.getFullYear()\n const m = date.getMonth()\n const d = date.getDate()\n return {\n start: new Date(y, m, d, 0, 0, 0, 0).getTime(),\n end: new Date(y, m, d, 23, 59, 59, 999).getTime(),\n }\n}\n"]}
export { CleanObject, Debounce, DeepClone, Delay, FormatDate, GetDateOffset, GetDayRange, GetURLParam, GetURLParams, IsArray, IsBoolean, IsEmail, IsEqual, IsFunction, IsInteger, IsIpv4, IsNull, IsNumber, IsObject, IsPhone, IsPositiveInteger, IsRealNumber, IsString, IsUrl, Minus, ObjectToQuery, Omit, Pick, QueryToObject, REGEX, Throttle, UUID, Unique, UniqueByKey } from './chunk-WJX5Q3WL.js';
//# sourceMappingURL=utils.js.map
//# sourceMappingURL=utils.js.map
{"version":3,"sources":[],"names":[],"mappings":"","file":"utils.js"}
/**
* 类型检测工具
*
* 统一使用 Object.prototype.toString 确保跨环境准确性,
* 规避 typeof null === 'object' 等已知陷阱。
*/
/**
* 是否为数字(含可转换的字符串数字,如 '42'、'3.14')
* @example IsNumber(42) // true
* @example IsNumber('42') // true
* @example IsNumber('abc') // false
* @remarks
* 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+
*/
declare const IsNumber: (val: unknown) => boolean;
/**
* 是否为严格数字类型(不含字符串数字)
* @example IsRealNumber(42) // true
* @example IsRealNumber('42') // false
* @remarks
* 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+
*/
declare const IsRealNumber: (val: unknown) => val is number;
/**
* 是否为字符串
* @example IsString('hello') // true
* @example IsString(new String('hello')) // true
* @remarks
* 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+
*/
declare const IsString: (val: unknown) => val is string;
/**
* 是否为布尔值
* @example IsBoolean(true) // true
* @example IsBoolean(1) // false
* @remarks
* 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+
*/
declare const IsBoolean: (val: unknown) => val is boolean;
/**
* 是否为数组
* @example IsArray([1, 2]) // true
* @example IsArray({}) // false
* @remarks
* 浏览器兼容性:Chrome 5+ · Firefox 3.5+ · Safari 4+ · Node.js 0.10+
*/
declare const IsArray: (val: unknown) => val is unknown[];
/**
* 是否为函数
* @example IsFunction(() => {}) // true
* @remarks
* 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+
*/
declare const IsFunction: (val: unknown) => val is (...args: unknown[]) => unknown;
/**
* 是否为普通对象(排除 null 和数组)
* @example IsObject({}) // true
* @example IsObject([]) // false
* @example IsObject(null) // false
* @remarks
* 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+
*/
declare const IsObject: (val: unknown) => val is Record<string, unknown>;
/**
* 是否为空值(null / undefined / 空字符串)
* @example IsNull(null) // true
* @example IsNull(undefined) // true
* @example IsNull('') // true
* @example IsNull(0) // false
* @remarks
* 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+
*/
declare const IsNull: (val: unknown) => boolean;
/**
* 深度相等比较,支持对象和数组的递归比较。
*
* 注意:仅比较自身可枚举属性,不比较原型链上的属性。
* 不支持 Map、Set、Date、RegExp 等特殊对象的深度比较。
* @example IsEqual({ a: 1 }, { a: 1 }) // true
* @example IsEqual([1, 2], [1, 2]) // true
* @example IsEqual({ a: 1 }, { a: 2 }) // false
* @remarks
* 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+
*/
declare const IsEqual: (a: unknown, b: unknown) => boolean;
/**
* 输入校验工具 + 常用正则常量
*/
/**
* 常用正则规则常量,来源参考 any-rule(https://github.com/any86/any-rule)
* @remarks
* 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+
*/
declare const REGEX: {
/** 手机号(宽松:13-19 开头) */
readonly phone: RegExp;
/** 手机号(严谨,基于工信部 2019 年最新公布号段) */
readonly strictPhone: RegExp;
/** 邮箱(符合 RFC 标准) */
readonly email: RegExp;
/** URL(支持 http / https / ftp) */
readonly url: RegExp;
/** IPv4 地址 */
readonly ipv4: RegExp;
/** 整数(含负数和零) */
readonly integer: RegExp;
/** 正整数(不含零) */
readonly positiveInteger: RegExp;
/** 二代身份证 */
readonly idcard: RegExp;
/** 日期(宽松,如 2022-9-1) */
readonly date: RegExp;
/** 16 进制颜色值 */
readonly color: RegExp;
};
/**
* 是否为合法邮箱地址
* @example IsEmail('user@example.com') // true
* @example IsEmail('invalid') // false
* @remarks
* 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+
*/
declare const IsEmail: (val: string) => boolean;
/**
* 是否为中国大陆手机号(宽松校验)
* @example IsPhone('13812345678') // true
* @example IsPhone('12345678901') // false
* @remarks
* 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+
*/
declare const IsPhone: (val: string) => boolean;
/**
* 是否为合法 URL
* @example IsUrl('https://example.com') // true
* @example IsUrl('not-a-url') // false
* @remarks
* 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+
*/
declare const IsUrl: (val: string) => boolean;
/**
* 是否为合法 IPv4 地址
* @example IsIpv4('192.168.1.1') // true
* @example IsIpv4('999.0.0.1') // false
* @remarks
* 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+
*/
declare const IsIpv4: (val: string) => boolean;
/**
* 是否为整数(含负数和零)
* @example IsInteger('42') // true
* @example IsInteger('-10') // true
* @example IsInteger('3.14') // false
* @remarks
* 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+
*/
declare const IsInteger: (val: string) => boolean;
/**
* 是否为正整数(不含零)
* @example IsPositiveInteger('1') // true
* @example IsPositiveInteger('0') // false
* @example IsPositiveInteger('-1') // false
* @remarks
* 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+
*/
declare const IsPositiveInteger: (val: string) => boolean;
/**
* 数组工具
*/
/**
* 数组去重(基于 Set,时间复杂度 O(n))
* @example Unique([1, 2, 1, 3]) // [1, 2, 3]
* @remarks
* 浏览器兼容性:Chrome 38+ · Firefox 13+ · Safari 7.1+ · Node.js 0.12+
*
* 依赖 `Set`(ES2015)。
*/
declare const Unique: <T>(arr: T[]) => T[];
/**
* 按对象指定 key 的值去重,保留首次出现的元素
* @param arr 待去重数组
* @param key 用于去重的对象属性名
* @example
* UniqueByKey([{ id: 1, name: 'a' }, { id: 1, name: 'b' }], 'id')
* // [{ id: 1, name: 'a' }]
* @remarks
* 浏览器兼容性:Chrome 38+ · Firefox 13+ · Safari 7.1+ · Node.js 0.12+
*
* 依赖 `Set`(ES2015)。
*/
declare const UniqueByKey: <T extends object>(arr: T[], key: keyof T) => T[];
/**
* 差集:返回只在 arr 中存在、不在 other 中存在的元素(基于 Set,时间复杂度 O(n))
* @param arr 基础数组
* @param other 比较数组
* @example Minus([1, 2, 3], [2, 3, 4]) // [1]
* @remarks
* 浏览器兼容性:Chrome 38+ · Firefox 13+ · Safari 7.1+ · Node.js 0.12+
*
* 依赖 `Set`(ES2015)。
*/
declare const Minus: <T>(arr: T[], other: T[]) => T[];
/**
* 对象工具
*/
/**
* 深拷贝对象或数组。
*
* 优先使用原生 `structuredClone`(支持 Date、RegExp、Map、Set、循环引用等),
* 降级为 JSON 序列化(不支持 undefined、函数、循环引用)。
* @example DeepClone({ a: { b: 1 } }) // { a: { b: 1 } }(新对象)
* @remarks
* 浏览器兼容性:
* - `structuredClone`(优先):Chrome 98+ · Firefox 94+ · Safari 15.4+ · Node.js 17.0+
* - JSON 降级(自动回退):Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+
*
* 在不支持 `structuredClone` 的环境中自动降级为 `JSON.parse(JSON.stringify(obj))`,
* 降级时不支持 `undefined`、函数、`Date`、`RegExp`、循环引用。
*/
declare const DeepClone: <T>(obj: T) => T;
/**
* 删除对象中值为 null 或 undefined 的属性,返回新对象(不修改原对象)。
*
* 注意:空字符串、false、0 等假值不会被删除。
* @example CleanObject({ a: 1, b: null, c: undefined }) // { a: 1 }
* @remarks
* 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+
*/
declare const CleanObject: <T extends object>(obj: T) => Partial<T>;
/**
* 按 key 列表提取对象子集,返回新对象(类型安全)。
* @example Pick({ a: 1, b: 2, c: 3 }, ['a', 'c']) // { a: 1, c: 3 }
* @remarks
* 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+
*/
declare const Pick: <T extends object, K extends keyof T>(obj: T, keys: K[]) => Pick<T, K>;
/**
* 排除指定 key 后返回新对象(类型安全)。
* @example Omit({ a: 1, b: 2, c: 3 }, ['b']) // { a: 1, c: 3 }
* @remarks
* 浏览器兼容性:Chrome 38+ · Firefox 13+ · Safari 7.1+ · Node.js 0.12+
*
* 依赖 `Set`(ES2015)。
*/
declare const Omit: <T extends object, K extends keyof T>(obj: T, keys: K[]) => Omit<T, K>;
/**
* 函数工具
*/
/**
* 防抖:在最后一次调用后等待 delay 毫秒再执行(trailing edge)。
*
* 适合搜索输入、窗口 resize、表单提交等场景。
* @param fn 要防抖的函数
* @param delay 延迟毫秒数,默认 300ms
* @example
* const handleInput = Debounce((val: string) => search(val), 500)
* @remarks
* 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+
*
* 依赖 `setTimeout` / `clearTimeout`,全平台支持。
*/
declare const Debounce: <T extends (...args: Parameters<T>) => ReturnType<T>>(fn: T, delay?: number) => ((...args: Parameters<T>) => void);
/**
* 节流:在 delay 毫秒内最多执行一次(leading edge,时间戳实现)。
*
* 适合滚动监听、mousemove、高频点击等场景。
* @param fn 要节流的函数
* @param delay 节流间隔毫秒数,默认 50ms
* @example
* const handleScroll = Throttle(() => updatePosition(), 100)
* @remarks
* 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+
*
* 依赖 `Date.now()`,无 `setTimeout` 悬空回调风险。
*/
declare const Throttle: <T extends (...args: Parameters<T>) => ReturnType<T>>(fn: T, delay?: number) => ((...args: Parameters<T>) => void);
/**
* Promise 延迟:等待指定毫秒数后 resolve。
* @param ms 延迟毫秒数
* @example await Delay(1000) // 等待 1 秒
* @remarks
* 浏览器兼容性:Chrome 32+ · Firefox 29+ · Safari 8+ · Node.js 0.12+
*
* 依赖 `Promise`(ES2015)和 `setTimeout`。
*/
declare const Delay: (ms: number) => Promise<void>;
/**
* 字符串 / UUID / URL 工具
*/
/**
* 生成标准 RFC 4122 v4 UUID。
*
* 优先使用 `crypto.randomUUID()`(现代浏览器 / Node.js 19+),
* 降级为基于 `crypto.getRandomValues` 的手动实现。
* @example UUID() // 'f47ac10b-58cc-4372-a567-0e02b2c3d479'
* @remarks
* 浏览器兼容性:
* - `crypto.randomUUID()`(优先):Chrome 92+ · Firefox 95+ · Safari 15.4+ · Node.js 19.0+
* - `crypto.getRandomValues` 降级:Chrome 11+ · Firefox 21+ · Safari 6.1+ · Node.js 15.0+
*
* Node.js 14.17+ 可通过 `import { randomUUID } from 'crypto'` 单独使用,
* 但全局 `crypto` 对象需 Node.js 15.0+ 才可用。
*/
declare const UUID: () => string;
/**
* 从 URL 中获取指定查询参数的值,不存在则返回空字符串。
* @param name 参数名
* @param url 目标 URL,默认取 `window.location.href`
* @example GetURLParam('page', 'https://example.com?page=2&size=10') // '2'
* @remarks
* 浏览器兼容性:Chrome 49+ · Firefox 44+ · Safari 10.1+ · Node.js 10.0+
*
* 依赖 `URL` API 和 `URLSearchParams`(WHATWG URL Standard)。
* 若 URL 格式非法会静默返回空字符串。
*/
declare const GetURLParam: (name: string, url?: string) => string;
/**
* 获取 URL 中所有查询参数,以键值对对象返回。
*
* 若同名参数出现多次,取最后一个值。
* @param url 目标 URL,默认取 `window.location.href`
* @example GetURLParams('https://example.com?a=1&b=2') // { a: '1', b: '2' }
* @remarks
* 浏览器兼容性:Chrome 49+ · Firefox 44+ · Safari 10.1+ · Node.js 10.0+
*
* 依赖 `URL` API 和 `URLSearchParams`(WHATWG URL Standard)。
* 若 URL 格式非法会静默返回空对象。
*/
declare const GetURLParams: (url?: string) => Record<string, string>;
/**
* 将对象转换为 URL 查询字符串(以 `?` 开头)。
*
* 值为 null / undefined 的属性会被跳过,特殊字符自动编码。
* @example ObjectToQuery({ page: 1, size: 10 }) // '?page=1&size=10'
* @example ObjectToQuery({}) // ''
* @remarks
* 浏览器兼容性:Chrome 49+ · Firefox 44+ · Safari 10.1+ · Node.js 10.0+
*
* 依赖 `URLSearchParams`(WHATWG URL Standard)。
* 空格编码为 `+`(application/x-www-form-urlencoded 规范),
* 与 `encodeURIComponent` 的 `%20` 编码略有差异。
*/
declare const ObjectToQuery: (obj: Record<string, unknown>) => string;
/**
* 将查询字符串解析为键值对对象。
*
* 支持以 `?` 开头或不以 `?` 开头的格式,自动解码编码字符。
* @example QueryToObject('?a=1&b=hello%20world') // { a: '1', b: 'hello world' }
* @remarks
* 浏览器兼容性:Chrome 49+ · Firefox 44+ · Safari 10.1+ · Node.js 10.0+
*
* 依赖 `URLSearchParams`(WHATWG URL Standard)。
*/
declare const QueryToObject: (query: string) => Record<string, string>;
/**
* 时间日期工具
*/
/**
* 格式化日期时间。
*
* 支持占位符:`yyyy`(年)、`MM`(月)、`dd`(日)、`HH`(24 小时制小时)、`mm`(分钟)、`ss`(秒)。
* @param date 日期,默认当前时间,支持 Date 对象、日期字符串、时间戳
* @param format 格式字符串,默认 `'yyyy-MM-dd HH:mm:ss'`
* @example FormatDate(new Date('2024-01-05 09:05:03')) // '2024-01-05 09:05:03'
* @example FormatDate(new Date('2024-01-05'), 'yyyy/MM/dd') // '2024/01/05'
* @example FormatDate(new Date('2024-01-05'), 'yy-MM-dd') // '24-01-05'
* @remarks
* 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+
*
* 依赖原生 `Date` API,全平台支持。
* 传入非法日期字符串时返回空字符串。
*/
declare const FormatDate: (date?: Date | string | number, format?: string) => string;
/**
* 获取指定日期偏移 N 天后的日期字符串。
*
* 正数表示往后,负数表示往前。不修改传入的 Date 对象。
* @param date 基准日期,默认当前时间
* @param days 偏移天数(正数往后,负数往前)
* @param format 格式字符串,默认 `'yyyy-MM-dd HH:mm:ss'`
* @example GetDateOffset(new Date('2024-01-10'), 3, 'yyyy-MM-dd') // '2024-01-13'
* @example GetDateOffset(new Date('2024-01-10'), -3, 'yyyy-MM-dd') // '2024-01-07'
* @remarks
* 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+
*
* 依赖原生 `Date` API,全平台支持。
*/
declare const GetDateOffset: (date?: Date, days?: number, format?: string) => string;
/**
* 获取指定日期当天的开始时间戳(00:00:00.000)和结束时间戳(23:59:59.999)。
* @param date 指定日期,默认当前时间
* @example GetDayRange(new Date('2024-01-05'))
* // { start: 1704384000000, end: 1704470399999 }
* @remarks
* 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+
*
* 依赖原生 `Date` API,全平台支持。
* 时间戳基于本地时区计算。
*/
declare const GetDayRange: (date?: Date) => {
start: number;
end: number;
};
export { CleanObject, Debounce, DeepClone, Delay, FormatDate, GetDateOffset, GetDayRange, GetURLParam, GetURLParams, IsArray, IsBoolean, IsEmail, IsEqual, IsFunction, IsInteger, IsIpv4, IsNull, IsNumber, IsObject, IsPhone, IsPositiveInteger, IsRealNumber, IsString, IsUrl, Minus, ObjectToQuery, Omit, Pick, QueryToObject, REGEX, Throttle, UUID, Unique, UniqueByKey };
var SnackKit = (function (exports) {
'use strict';
// src/utils/detect.ts
var _toString = (val) => Object.prototype.toString.call(val);
var IsNumber = (val) => !isNaN(parseFloat(val)) && isFinite(val);
var IsRealNumber = (val) => typeof val === "number" && !isNaN(val);
var IsString = (val) => _toString(val) === "[object String]";
var IsBoolean = (val) => _toString(val) === "[object Boolean]";
var IsArray = (val) => Array.isArray(val);
var IsFunction = (val) => _toString(val) === "[object Function]";
var IsObject = (val) => _toString(val) === "[object Object]";
var IsNull = (val) => val === null || val === void 0 || val === "";
var IsEqual = (a, b) => {
if (a === b) return true;
if (typeof a !== typeof b) return false;
if (a === null || b === null) return false;
if (typeof a !== "object") return false;
if (Array.isArray(a) !== Array.isArray(b)) return false;
const keysA = Object.keys(a);
const keysB = Object.keys(b);
if (keysA.length !== keysB.length) return false;
for (const key of keysA) {
if (!IsEqual(a[key], b[key])) {
return false;
}
}
return true;
};
// src/utils/validate.ts
var REGEX = {
/** 手机号(宽松:13-19 开头) */
phone: /^(?:(?:\+|00)86)?1[3-9]\d{9}$/,
/** 手机号(严谨,基于工信部 2019 年最新公布号段) */
strictPhone: /^(?:(?:\+|00)86)?1(?:(?:3\d)|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8\d)|(?:9[189]))\d{8}$/,
/** 邮箱(符合 RFC 标准) */
email: /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-_0-9]+\.)+[a-zA-Z]{2,}))$/,
/** URL(支持 http / https / ftp) */
url: /^(https?|ftp):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:/~+#]*[\w\-@?^=%&/~+#])?/,
/** IPv4 地址 */
ipv4: /^((25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/,
/** 整数(含负数和零) */
integer: /^[+-]?\d+$/,
/** 正整数(不含零) */
positiveInteger: /^[1-9]\d*$/,
/** 二代身份证 */
idcard: /^[1-9]\d{5}(?:18|19|20)\d{2}(?:0[1-9]|10|11|12)(?:0[1-9]|[1-2]\d|30|31)\d{3}[\dXx]$/,
/** 日期(宽松,如 2022-9-1) */
date: /^\d{1,4}-(1[0-2]|0?[1-9])-(0?[1-9]|[1-2]\d|30|31)$/,
/** 16 进制颜色值 */
color: /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/
};
var IsEmail = (val) => REGEX.email.test(val);
var IsPhone = (val) => REGEX.phone.test(val);
var IsUrl = (val) => REGEX.url.test(val);
var IsIpv4 = (val) => REGEX.ipv4.test(val);
var IsInteger = (val) => REGEX.integer.test(val);
var IsPositiveInteger = (val) => REGEX.positiveInteger.test(val);
// src/utils/array.ts
var Unique = (arr) => [...new Set(arr)];
var UniqueByKey = (arr, key) => {
const seen = /* @__PURE__ */ new Set();
const result = [];
for (const item of arr) {
const k = item[key];
if (!seen.has(k)) {
seen.add(k);
result.push(item);
}
}
return result;
};
var Minus = (arr, other) => {
const otherSet = new Set(other);
return arr.filter((item) => !otherSet.has(item));
};
// src/utils/object.ts
var DeepClone = (obj) => {
if (typeof structuredClone === "function") {
return structuredClone(obj);
}
return JSON.parse(JSON.stringify(obj));
};
var CleanObject = (obj) => {
const result = {};
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
const val = obj[key];
if (val !== null && val !== void 0) {
result[key] = val;
}
}
}
return result;
};
var Pick = (obj, keys) => {
const result = {};
for (const key of keys) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
result[key] = obj[key];
}
}
return result;
};
var Omit = (obj, keys) => {
const excludeSet = new Set(keys);
const result = {};
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key) && !excludeSet.has(key)) {
result[key] = obj[key];
}
}
return result;
};
// src/utils/func.ts
var Debounce = (fn, delay = 300) => {
let timer = null;
return function(...args) {
if (timer !== null) clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, args);
timer = null;
}, delay);
};
};
var Throttle = (fn, delay = 50) => {
let lastTime = 0;
return function(...args) {
const now = Date.now();
if (now - lastTime >= delay) {
lastTime = now;
fn.apply(this, args);
}
};
};
var Delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
// src/utils/string.ts
var UUID = () => {
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
return crypto.randomUUID();
}
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
const arr = new Uint8Array(1);
crypto.getRandomValues(arr);
const r = arr[0] & 15;
const v = c === "x" ? r : r & 3 | 8;
return v.toString(16);
});
};
var GetURLParam = (name, url = typeof window !== "undefined" ? window.location.href : "") => {
try {
return new URL(url).searchParams.get(name) ?? "";
} catch {
return "";
}
};
var GetURLParams = (url = typeof window !== "undefined" ? window.location.href : "") => {
try {
const result = {};
new URL(url).searchParams.forEach((val, key) => {
result[key] = val;
});
return result;
} catch {
return {};
}
};
var ObjectToQuery = (obj) => {
const params = new URLSearchParams();
for (const [key, val] of Object.entries(obj)) {
if (val !== null && val !== void 0) {
params.append(key, String(val));
}
}
const str = params.toString();
return str ? `?${str}` : "";
};
var QueryToObject = (query) => {
const str = query.startsWith("?") ? query.slice(1) : query;
const result = {};
new URLSearchParams(str).forEach((val, key) => {
result[key] = val;
});
return result;
};
// src/utils/time.ts
var FormatDate = (date = /* @__PURE__ */ new Date(), format = "yyyy-MM-dd HH:mm:ss") => {
const d = date instanceof Date ? date : new Date(date);
if (isNaN(d.getTime())) return "";
const map = {
"M+": d.getMonth() + 1,
"d+": d.getDate(),
"H+": d.getHours(),
"m+": d.getMinutes(),
"s+": d.getSeconds()
};
let result = format.replace(
/(y+)/,
(_, p) => String(d.getFullYear()).slice(4 - p.length)
);
for (const [pattern, value] of Object.entries(map)) {
result = result.replace(
new RegExp(`(${pattern})`),
(_, p) => String(value).padStart(p.length, "0")
);
}
return result;
};
var GetDateOffset = (date = /* @__PURE__ */ new Date(), days = 0, format = "yyyy-MM-dd HH:mm:ss") => {
const d = new Date(date.getTime());
d.setDate(d.getDate() + days);
return FormatDate(d, format);
};
var GetDayRange = (date = /* @__PURE__ */ new Date()) => {
const y = date.getFullYear();
const m = date.getMonth();
const d = date.getDate();
return {
start: new Date(y, m, d, 0, 0, 0, 0).getTime(),
end: new Date(y, m, d, 23, 59, 59, 999).getTime()
};
};
exports.CleanObject = CleanObject;
exports.Debounce = Debounce;
exports.DeepClone = DeepClone;
exports.Delay = Delay;
exports.FormatDate = FormatDate;
exports.GetDateOffset = GetDateOffset;
exports.GetDayRange = GetDayRange;
exports.GetURLParam = GetURLParam;
exports.GetURLParams = GetURLParams;
exports.IsArray = IsArray;
exports.IsBoolean = IsBoolean;
exports.IsEmail = IsEmail;
exports.IsEqual = IsEqual;
exports.IsFunction = IsFunction;
exports.IsInteger = IsInteger;
exports.IsIpv4 = IsIpv4;
exports.IsNull = IsNull;
exports.IsNumber = IsNumber;
exports.IsObject = IsObject;
exports.IsPhone = IsPhone;
exports.IsPositiveInteger = IsPositiveInteger;
exports.IsRealNumber = IsRealNumber;
exports.IsString = IsString;
exports.IsUrl = IsUrl;
exports.Minus = Minus;
exports.ObjectToQuery = ObjectToQuery;
exports.Omit = Omit;
exports.Pick = Pick;
exports.QueryToObject = QueryToObject;
exports.REGEX = REGEX;
exports.Throttle = Throttle;
exports.UUID = UUID;
exports.Unique = Unique;
exports.UniqueByKey = UniqueByKey;
return exports;
})({});
//# sourceMappingURL=utils.global.js.map
//# sourceMappingURL=utils.global.js.map
{"version":3,"sources":["../../src/utils/detect.ts","../../src/utils/validate.ts","../../src/utils/array.ts","../../src/utils/object.ts","../../src/utils/func.ts","../../src/utils/string.ts","../../src/utils/time.ts"],"names":[],"mappings":"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","file":"utils.global.js","sourcesContent":["/**\n * 类型检测工具\n *\n * 统一使用 Object.prototype.toString 确保跨环境准确性,\n * 规避 typeof null === 'object' 等已知陷阱。\n */\n\nconst _toString = (val: unknown): string => Object.prototype.toString.call(val)\n\n/**\n * 是否为数字(含可转换的字符串数字,如 '42'、'3.14')\n * @example IsNumber(42) // true\n * @example IsNumber('42') // true\n * @example IsNumber('abc') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsNumber = (val: unknown): boolean =>\n !isNaN(parseFloat(val as string)) && isFinite(val as number)\n\n/**\n * 是否为严格数字类型(不含字符串数字)\n * @example IsRealNumber(42) // true\n * @example IsRealNumber('42') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsRealNumber = (val: unknown): val is number =>\n typeof val === 'number' && !isNaN(val)\n\n/**\n * 是否为字符串\n * @example IsString('hello') // true\n * @example IsString(new String('hello')) // true\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsString = (val: unknown): val is string =>\n _toString(val) === '[object String]'\n\n/**\n * 是否为布尔值\n * @example IsBoolean(true) // true\n * @example IsBoolean(1) // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsBoolean = (val: unknown): val is boolean =>\n _toString(val) === '[object Boolean]'\n\n/**\n * 是否为数组\n * @example IsArray([1, 2]) // true\n * @example IsArray({}) // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3.5+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsArray = (val: unknown): val is unknown[] => Array.isArray(val)\n\n/**\n * 是否为函数\n * @example IsFunction(() => {}) // true\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsFunction = (val: unknown): val is (...args: unknown[]) => unknown =>\n _toString(val) === '[object Function]'\n\n/**\n * 是否为普通对象(排除 null 和数组)\n * @example IsObject({}) // true\n * @example IsObject([]) // false\n * @example IsObject(null) // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsObject = (val: unknown): val is Record<string, unknown> =>\n _toString(val) === '[object Object]'\n\n/**\n * 是否为空值(null / undefined / 空字符串)\n * @example IsNull(null) // true\n * @example IsNull(undefined) // true\n * @example IsNull('') // true\n * @example IsNull(0) // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsNull = (val: unknown): boolean =>\n val === null || val === undefined || val === ''\n\n/**\n * 深度相等比较,支持对象和数组的递归比较。\n *\n * 注意:仅比较自身可枚举属性,不比较原型链上的属性。\n * 不支持 Map、Set、Date、RegExp 等特殊对象的深度比较。\n * @example IsEqual({ a: 1 }, { a: 1 }) // true\n * @example IsEqual([1, 2], [1, 2]) // true\n * @example IsEqual({ a: 1 }, { a: 2 }) // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsEqual = (a: unknown, b: unknown): boolean => {\n if (a === b) return true\n if (typeof a !== typeof b) return false\n if (a === null || b === null) return false\n if (typeof a !== 'object') return false\n // 数组与普通对象不相等\n if (Array.isArray(a) !== Array.isArray(b)) return false\n\n const keysA = Object.keys(a as object)\n const keysB = Object.keys(b as object)\n if (keysA.length !== keysB.length) return false\n\n for (const key of keysA) {\n if (!IsEqual((a as Record<string, unknown>)[key], (b as Record<string, unknown>)[key])) {\n return false\n }\n }\n return true\n}\n","/**\n * 输入校验工具 + 常用正则常量\n */\n\n/**\n * 常用正则规则常量,来源参考 any-rule(https://github.com/any86/any-rule)\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const REGEX = {\n /** 手机号(宽松:13-19 开头) */\n phone: /^(?:(?:\\+|00)86)?1[3-9]\\d{9}$/,\n /** 手机号(严谨,基于工信部 2019 年最新公布号段) */\n strictPhone: /^(?:(?:\\+|00)86)?1(?:(?:3\\d)|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8\\d)|(?:9[189]))\\d{8}$/,\n /** 邮箱(符合 RFC 标准) */\n email: /^(([^<>()[\\]\\\\.,;:\\s@\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-_0-9]+\\.)+[a-zA-Z]{2,}))$/,\n /** URL(支持 http / https / ftp) */\n url: /^(https?|ftp):\\/\\/[\\w\\-]+(\\.[\\w\\-]+)+([\\w\\-.,@?^=%&:/~+#]*[\\w\\-@?^=%&/~+#])?/,\n /** IPv4 地址 */\n ipv4: /^((25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)\\.){3}(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)$/,\n /** 整数(含负数和零) */\n integer: /^[+-]?\\d+$/,\n /** 正整数(不含零) */\n positiveInteger: /^[1-9]\\d*$/,\n /** 二代身份证 */\n idcard: /^[1-9]\\d{5}(?:18|19|20)\\d{2}(?:0[1-9]|10|11|12)(?:0[1-9]|[1-2]\\d|30|31)\\d{3}[\\dXx]$/,\n /** 日期(宽松,如 2022-9-1) */\n date: /^\\d{1,4}-(1[0-2]|0?[1-9])-(0?[1-9]|[1-2]\\d|30|31)$/,\n /** 16 进制颜色值 */\n color: /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/,\n} as const\n\n/**\n * 是否为合法邮箱地址\n * @example IsEmail('user@example.com') // true\n * @example IsEmail('invalid') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsEmail = (val: string): boolean => REGEX.email.test(val)\n\n/**\n * 是否为中国大陆手机号(宽松校验)\n * @example IsPhone('13812345678') // true\n * @example IsPhone('12345678901') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsPhone = (val: string): boolean => REGEX.phone.test(val)\n\n/**\n * 是否为合法 URL\n * @example IsUrl('https://example.com') // true\n * @example IsUrl('not-a-url') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsUrl = (val: string): boolean => REGEX.url.test(val)\n\n/**\n * 是否为合法 IPv4 地址\n * @example IsIpv4('192.168.1.1') // true\n * @example IsIpv4('999.0.0.1') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsIpv4 = (val: string): boolean => REGEX.ipv4.test(val)\n\n/**\n * 是否为整数(含负数和零)\n * @example IsInteger('42') // true\n * @example IsInteger('-10') // true\n * @example IsInteger('3.14') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsInteger = (val: string): boolean => REGEX.integer.test(val)\n\n/**\n * 是否为正整数(不含零)\n * @example IsPositiveInteger('1') // true\n * @example IsPositiveInteger('0') // false\n * @example IsPositiveInteger('-1') // false\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const IsPositiveInteger = (val: string): boolean => REGEX.positiveInteger.test(val)\n","/**\n * 数组工具\n */\n\n/**\n * 数组去重(基于 Set,时间复杂度 O(n))\n * @example Unique([1, 2, 1, 3]) // [1, 2, 3]\n * @remarks\n * 浏览器兼容性:Chrome 38+ · Firefox 13+ · Safari 7.1+ · Node.js 0.12+\n *\n * 依赖 `Set`(ES2015)。\n */\nexport const Unique = <T>(arr: T[]): T[] => [...new Set(arr)]\n\n/**\n * 按对象指定 key 的值去重,保留首次出现的元素\n * @param arr 待去重数组\n * @param key 用于去重的对象属性名\n * @example\n * UniqueByKey([{ id: 1, name: 'a' }, { id: 1, name: 'b' }], 'id')\n * // [{ id: 1, name: 'a' }]\n * @remarks\n * 浏览器兼容性:Chrome 38+ · Firefox 13+ · Safari 7.1+ · Node.js 0.12+\n *\n * 依赖 `Set`(ES2015)。\n */\nexport const UniqueByKey = <T extends object>(arr: T[], key: keyof T): T[] => {\n const seen = new Set<unknown>()\n const result: T[] = []\n for (const item of arr) {\n const k = item[key]\n if (!seen.has(k)) {\n seen.add(k)\n result.push(item)\n }\n }\n return result\n}\n\n/**\n * 差集:返回只在 arr 中存在、不在 other 中存在的元素(基于 Set,时间复杂度 O(n))\n * @param arr 基础数组\n * @param other 比较数组\n * @example Minus([1, 2, 3], [2, 3, 4]) // [1]\n * @remarks\n * 浏览器兼容性:Chrome 38+ · Firefox 13+ · Safari 7.1+ · Node.js 0.12+\n *\n * 依赖 `Set`(ES2015)。\n */\nexport const Minus = <T>(arr: T[], other: T[]): T[] => {\n const otherSet = new Set(other)\n return arr.filter(item => !otherSet.has(item))\n}\n","/**\n * 对象工具\n */\n\n/**\n * 深拷贝对象或数组。\n *\n * 优先使用原生 `structuredClone`(支持 Date、RegExp、Map、Set、循环引用等),\n * 降级为 JSON 序列化(不支持 undefined、函数、循环引用)。\n * @example DeepClone({ a: { b: 1 } }) // { a: { b: 1 } }(新对象)\n * @remarks\n * 浏览器兼容性:\n * - `structuredClone`(优先):Chrome 98+ · Firefox 94+ · Safari 15.4+ · Node.js 17.0+\n * - JSON 降级(自动回退):Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n *\n * 在不支持 `structuredClone` 的环境中自动降级为 `JSON.parse(JSON.stringify(obj))`,\n * 降级时不支持 `undefined`、函数、`Date`、`RegExp`、循环引用。\n */\nexport const DeepClone = <T>(obj: T): T => {\n if (typeof structuredClone === 'function') {\n return structuredClone(obj)\n }\n // 降级:仅适用于纯 JSON 可序列化的数据\n return JSON.parse(JSON.stringify(obj)) as T\n}\n\n/**\n * 删除对象中值为 null 或 undefined 的属性,返回新对象(不修改原对象)。\n *\n * 注意:空字符串、false、0 等假值不会被删除。\n * @example CleanObject({ a: 1, b: null, c: undefined }) // { a: 1 }\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const CleanObject = <T extends object>(obj: T): Partial<T> => {\n const result = {} as Partial<T>\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n const val = obj[key]\n if (val !== null && val !== undefined) {\n result[key] = val\n }\n }\n }\n return result\n}\n\n/**\n * 按 key 列表提取对象子集,返回新对象(类型安全)。\n * @example Pick({ a: 1, b: 2, c: 3 }, ['a', 'c']) // { a: 1, c: 3 }\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n */\nexport const Pick = <T extends object, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> => {\n const result = {} as Pick<T, K>\n for (const key of keys) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n result[key] = obj[key]\n }\n }\n return result\n}\n\n/**\n * 排除指定 key 后返回新对象(类型安全)。\n * @example Omit({ a: 1, b: 2, c: 3 }, ['b']) // { a: 1, c: 3 }\n * @remarks\n * 浏览器兼容性:Chrome 38+ · Firefox 13+ · Safari 7.1+ · Node.js 0.12+\n *\n * 依赖 `Set`(ES2015)。\n */\nexport const Omit = <T extends object, K extends keyof T>(obj: T, keys: K[]): Omit<T, K> => {\n const excludeSet = new Set<keyof T>(keys)\n const result = {} as Omit<T, K>\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key) && !excludeSet.has(key as keyof T)) {\n (result as Record<string, unknown>)[key] = obj[key]\n }\n }\n return result\n}\n","/**\n * 函数工具\n */\n\n/**\n * 防抖:在最后一次调用后等待 delay 毫秒再执行(trailing edge)。\n *\n * 适合搜索输入、窗口 resize、表单提交等场景。\n * @param fn 要防抖的函数\n * @param delay 延迟毫秒数,默认 300ms\n * @example\n * const handleInput = Debounce((val: string) => search(val), 500)\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n *\n * 依赖 `setTimeout` / `clearTimeout`,全平台支持。\n */\nexport const Debounce = <T extends (...args: Parameters<T>) => ReturnType<T>>(\n fn: T,\n delay = 300\n): ((...args: Parameters<T>) => void) => {\n let timer: ReturnType<typeof setTimeout> | null = null\n return function (this: ThisParameterType<T>, ...args: Parameters<T>) {\n if (timer !== null) clearTimeout(timer)\n timer = setTimeout(() => {\n fn.apply(this, args)\n timer = null\n }, delay)\n }\n}\n\n/**\n * 节流:在 delay 毫秒内最多执行一次(leading edge,时间戳实现)。\n *\n * 适合滚动监听、mousemove、高频点击等场景。\n * @param fn 要节流的函数\n * @param delay 节流间隔毫秒数,默认 50ms\n * @example\n * const handleScroll = Throttle(() => updatePosition(), 100)\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n *\n * 依赖 `Date.now()`,无 `setTimeout` 悬空回调风险。\n */\nexport const Throttle = <T extends (...args: Parameters<T>) => ReturnType<T>>(\n fn: T,\n delay = 50\n): ((...args: Parameters<T>) => void) => {\n let lastTime = 0\n return function (this: ThisParameterType<T>, ...args: Parameters<T>) {\n const now = Date.now()\n if (now - lastTime >= delay) {\n lastTime = now\n fn.apply(this, args)\n }\n }\n}\n\n/**\n * Promise 延迟:等待指定毫秒数后 resolve。\n * @param ms 延迟毫秒数\n * @example await Delay(1000) // 等待 1 秒\n * @remarks\n * 浏览器兼容性:Chrome 32+ · Firefox 29+ · Safari 8+ · Node.js 0.12+\n *\n * 依赖 `Promise`(ES2015)和 `setTimeout`。\n */\nexport const Delay = (ms: number): Promise<void> =>\n new Promise(resolve => setTimeout(resolve, ms))\n","/**\n * 字符串 / UUID / URL 工具\n */\n\n/**\n * 生成标准 RFC 4122 v4 UUID。\n *\n * 优先使用 `crypto.randomUUID()`(现代浏览器 / Node.js 19+),\n * 降级为基于 `crypto.getRandomValues` 的手动实现。\n * @example UUID() // 'f47ac10b-58cc-4372-a567-0e02b2c3d479'\n * @remarks\n * 浏览器兼容性:\n * - `crypto.randomUUID()`(优先):Chrome 92+ · Firefox 95+ · Safari 15.4+ · Node.js 19.0+\n * - `crypto.getRandomValues` 降级:Chrome 11+ · Firefox 21+ · Safari 6.1+ · Node.js 15.0+\n *\n * Node.js 14.17+ 可通过 `import { randomUUID } from 'crypto'` 单独使用,\n * 但全局 `crypto` 对象需 Node.js 15.0+ 才可用。\n */\nexport const UUID = (): string => {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID()\n }\n // 降级:RFC 4122 v4,使用 crypto.getRandomValues 保证随机性\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const arr = new Uint8Array(1)\n crypto.getRandomValues(arr)\n const r = arr[0] & 0xf\n const v = c === 'x' ? r : (r & 0x3) | 0x8\n return v.toString(16)\n })\n}\n\n/**\n * 从 URL 中获取指定查询参数的值,不存在则返回空字符串。\n * @param name 参数名\n * @param url 目标 URL,默认取 `window.location.href`\n * @example GetURLParam('page', 'https://example.com?page=2&size=10') // '2'\n * @remarks\n * 浏览器兼容性:Chrome 49+ · Firefox 44+ · Safari 10.1+ · Node.js 10.0+\n *\n * 依赖 `URL` API 和 `URLSearchParams`(WHATWG URL Standard)。\n * 若 URL 格式非法会静默返回空字符串。\n */\nexport const GetURLParam = (\n name: string,\n url: string = typeof window !== 'undefined' ? window.location.href : ''\n): string => {\n try {\n return new URL(url).searchParams.get(name) ?? ''\n } catch {\n return ''\n }\n}\n\n/**\n * 获取 URL 中所有查询参数,以键值对对象返回。\n *\n * 若同名参数出现多次,取最后一个值。\n * @param url 目标 URL,默认取 `window.location.href`\n * @example GetURLParams('https://example.com?a=1&b=2') // { a: '1', b: '2' }\n * @remarks\n * 浏览器兼容性:Chrome 49+ · Firefox 44+ · Safari 10.1+ · Node.js 10.0+\n *\n * 依赖 `URL` API 和 `URLSearchParams`(WHATWG URL Standard)。\n * 若 URL 格式非法会静默返回空对象。\n */\nexport const GetURLParams = (\n url: string = typeof window !== 'undefined' ? window.location.href : ''\n): Record<string, string> => {\n try {\n const result: Record<string, string> = {}\n new URL(url).searchParams.forEach((val, key) => {\n result[key] = val\n })\n return result\n } catch {\n return {}\n }\n}\n\n/**\n * 将对象转换为 URL 查询字符串(以 `?` 开头)。\n *\n * 值为 null / undefined 的属性会被跳过,特殊字符自动编码。\n * @example ObjectToQuery({ page: 1, size: 10 }) // '?page=1&size=10'\n * @example ObjectToQuery({}) // ''\n * @remarks\n * 浏览器兼容性:Chrome 49+ · Firefox 44+ · Safari 10.1+ · Node.js 10.0+\n *\n * 依赖 `URLSearchParams`(WHATWG URL Standard)。\n * 空格编码为 `+`(application/x-www-form-urlencoded 规范),\n * 与 `encodeURIComponent` 的 `%20` 编码略有差异。\n */\nexport const ObjectToQuery = (obj: Record<string, unknown>): string => {\n const params = new URLSearchParams()\n for (const [key, val] of Object.entries(obj)) {\n if (val !== null && val !== undefined) {\n params.append(key, String(val))\n }\n }\n const str = params.toString()\n return str ? `?${str}` : ''\n}\n\n/**\n * 将查询字符串解析为键值对对象。\n *\n * 支持以 `?` 开头或不以 `?` 开头的格式,自动解码编码字符。\n * @example QueryToObject('?a=1&b=hello%20world') // { a: '1', b: 'hello world' }\n * @remarks\n * 浏览器兼容性:Chrome 49+ · Firefox 44+ · Safari 10.1+ · Node.js 10.0+\n *\n * 依赖 `URLSearchParams`(WHATWG URL Standard)。\n */\nexport const QueryToObject = (query: string): Record<string, string> => {\n const str = query.startsWith('?') ? query.slice(1) : query\n const result: Record<string, string> = {}\n new URLSearchParams(str).forEach((val, key) => {\n result[key] = val\n })\n return result\n}\n","/**\n * 时间日期工具\n */\n\n/**\n * 格式化日期时间。\n *\n * 支持占位符:`yyyy`(年)、`MM`(月)、`dd`(日)、`HH`(24 小时制小时)、`mm`(分钟)、`ss`(秒)。\n * @param date 日期,默认当前时间,支持 Date 对象、日期字符串、时间戳\n * @param format 格式字符串,默认 `'yyyy-MM-dd HH:mm:ss'`\n * @example FormatDate(new Date('2024-01-05 09:05:03')) // '2024-01-05 09:05:03'\n * @example FormatDate(new Date('2024-01-05'), 'yyyy/MM/dd') // '2024/01/05'\n * @example FormatDate(new Date('2024-01-05'), 'yy-MM-dd') // '24-01-05'\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n *\n * 依赖原生 `Date` API,全平台支持。\n * 传入非法日期字符串时返回空字符串。\n */\nexport const FormatDate = (\n date: Date | string | number = new Date(),\n format = 'yyyy-MM-dd HH:mm:ss'\n): string => {\n const d = date instanceof Date ? date : new Date(date)\n if (isNaN(d.getTime())) return ''\n\n const map: Record<string, number> = {\n 'M+': d.getMonth() + 1,\n 'd+': d.getDate(),\n 'H+': d.getHours(),\n 'm+': d.getMinutes(),\n 's+': d.getSeconds(),\n }\n\n // 年份单独处理(支持 yy / yyyy)\n let result = format.replace(/(y+)/, (_, p: string) =>\n String(d.getFullYear()).slice(4 - p.length)\n )\n\n for (const [pattern, value] of Object.entries(map)) {\n result = result.replace(new RegExp(`(${pattern})`), (_, p: string) =>\n String(value).padStart(p.length, '0')\n )\n }\n\n return result\n}\n\n/**\n * 获取指定日期偏移 N 天后的日期字符串。\n *\n * 正数表示往后,负数表示往前。不修改传入的 Date 对象。\n * @param date 基准日期,默认当前时间\n * @param days 偏移天数(正数往后,负数往前)\n * @param format 格式字符串,默认 `'yyyy-MM-dd HH:mm:ss'`\n * @example GetDateOffset(new Date('2024-01-10'), 3, 'yyyy-MM-dd') // '2024-01-13'\n * @example GetDateOffset(new Date('2024-01-10'), -3, 'yyyy-MM-dd') // '2024-01-07'\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n *\n * 依赖原生 `Date` API,全平台支持。\n */\nexport const GetDateOffset = (\n date: Date = new Date(),\n days = 0,\n format = 'yyyy-MM-dd HH:mm:ss'\n): string => {\n const d = new Date(date.getTime())\n d.setDate(d.getDate() + days)\n return FormatDate(d, format)\n}\n\n/**\n * 获取指定日期当天的开始时间戳(00:00:00.000)和结束时间戳(23:59:59.999)。\n * @param date 指定日期,默认当前时间\n * @example GetDayRange(new Date('2024-01-05'))\n * // { start: 1704384000000, end: 1704470399999 }\n * @remarks\n * 浏览器兼容性:Chrome 5+ · Firefox 3+ · Safari 4+ · Node.js 0.10+\n *\n * 依赖原生 `Date` API,全平台支持。\n * 时间戳基于本地时区计算。\n */\nexport const GetDayRange = (\n date: Date = new Date()\n): { start: number; end: number } => {\n const y = date.getFullYear()\n const m = date.getMonth()\n const d = date.getDate()\n return {\n start: new Date(y, m, d, 0, 0, 0, 0).getTime(),\n end: new Date(y, m, d, 23, 59, 59, 999).getTime(),\n }\n}\n"]}
+138
-1

@@ -6,5 +6,6 @@ 'use strict';

var chunkN7BJS6LI_cjs = require('./chunk-N7BJS6LI.cjs');
var chunkU6KYHCBL_cjs = require('./chunk-U6KYHCBL.cjs');
// package.json
var version = "0.2.0";
var version = "0.3.0";

@@ -63,4 +64,140 @@ Object.defineProperty(exports, "Debugger", {

});
Object.defineProperty(exports, "CleanObject", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.CleanObject; }
});
Object.defineProperty(exports, "Debounce", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.Debounce; }
});
Object.defineProperty(exports, "DeepClone", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.DeepClone; }
});
Object.defineProperty(exports, "Delay", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.Delay; }
});
Object.defineProperty(exports, "FormatDate", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.FormatDate; }
});
Object.defineProperty(exports, "GetDateOffset", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.GetDateOffset; }
});
Object.defineProperty(exports, "GetDayRange", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.GetDayRange; }
});
Object.defineProperty(exports, "GetURLParam", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.GetURLParam; }
});
Object.defineProperty(exports, "GetURLParams", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.GetURLParams; }
});
Object.defineProperty(exports, "IsArray", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.IsArray; }
});
Object.defineProperty(exports, "IsBoolean", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.IsBoolean; }
});
Object.defineProperty(exports, "IsEmail", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.IsEmail; }
});
Object.defineProperty(exports, "IsEqual", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.IsEqual; }
});
Object.defineProperty(exports, "IsFunction", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.IsFunction; }
});
Object.defineProperty(exports, "IsInteger", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.IsInteger; }
});
Object.defineProperty(exports, "IsIpv4", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.IsIpv4; }
});
Object.defineProperty(exports, "IsNull", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.IsNull; }
});
Object.defineProperty(exports, "IsNumber", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.IsNumber; }
});
Object.defineProperty(exports, "IsObject", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.IsObject; }
});
Object.defineProperty(exports, "IsPhone", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.IsPhone; }
});
Object.defineProperty(exports, "IsPositiveInteger", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.IsPositiveInteger; }
});
Object.defineProperty(exports, "IsRealNumber", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.IsRealNumber; }
});
Object.defineProperty(exports, "IsString", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.IsString; }
});
Object.defineProperty(exports, "IsUrl", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.IsUrl; }
});
Object.defineProperty(exports, "Minus", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.Minus; }
});
Object.defineProperty(exports, "ObjectToQuery", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.ObjectToQuery; }
});
Object.defineProperty(exports, "Omit", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.Omit; }
});
Object.defineProperty(exports, "Pick", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.Pick; }
});
Object.defineProperty(exports, "QueryToObject", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.QueryToObject; }
});
Object.defineProperty(exports, "REGEX", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.REGEX; }
});
Object.defineProperty(exports, "Throttle", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.Throttle; }
});
Object.defineProperty(exports, "UUID", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.UUID; }
});
Object.defineProperty(exports, "Unique", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.Unique; }
});
Object.defineProperty(exports, "UniqueByKey", {
enumerable: true,
get: function () { return chunkU6KYHCBL_cjs.UniqueByKey; }
});
exports.VERSION = version;
//# sourceMappingURL=index.cjs.map
//# sourceMappingURL=index.cjs.map
+1
-1

@@ -1,1 +0,1 @@

{"version":3,"sources":["../../package.json"],"names":[],"mappings":";;;;;;;AAEE,IAAA,OAAA,GAAW","file":"index.cjs","sourcesContent":["{\n \"name\": \"@snack-kit/lib\",\n \"version\": \"0.2.0\",\n \"description\": \"Enterprise-grade utility library\",\n \"keywords\": [],\n \"license\": \"MIT\",\n \"type\": \"module\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/types/index.d.ts\",\n \"import\": \"./dist/es/index.js\",\n \"require\": \"./dist/cjs/index.cjs\"\n },\n \"./http\": {\n \"types\": \"./dist/types/http.d.ts\",\n \"import\": \"./dist/es/http.js\",\n \"require\": \"./dist/cjs/http.cjs\"\n },\n \"./debugger\": {\n \"types\": \"./dist/types/debugger.d.ts\",\n \"import\": \"./dist/es/debugger.js\",\n \"require\": \"./dist/cjs/debugger.cjs\"\n }\n },\n \"main\": \"./dist/cjs/index.cjs\",\n \"module\": \"./dist/es/index.js\",\n \"types\": \"./dist/types/index.d.ts\",\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"build:watch\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\",\n \"docs\": \"typedoc && cp -r docs/demo docs/api/demo\",\n \"docs:watch\": \"typedoc --watch\",\n \"lint\": \"tsc --noEmit\",\n \"prepublishOnly\": \"npm run build\",\n \"release\": \"npm run build && npm publish --access public\"\n },\n \"devDependencies\": {\n \"@vitest/coverage-v8\": \"^2.0.0\",\n \"tsup\": \"^8.0.0\",\n \"typedoc\": \"^0.26.0\",\n \"typescript\": \"^5.5.3\",\n \"vitest\": \"^2.0.0\"\n },\n \"dependencies\": {\n \"axios\": \"^1.13.6\"\n }\n}\n"]}
{"version":3,"sources":["../../package.json"],"names":[],"mappings":";;;;;;;;AAEE,IAAA,OAAA,GAAW","file":"index.cjs","sourcesContent":["{\n \"name\": \"@snack-kit/lib\",\n \"version\": \"0.3.0\",\n \"description\": \"Enterprise-grade utility library\",\n \"keywords\": [],\n \"license\": \"MIT\",\n \"type\": \"module\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/types/index.d.ts\",\n \"import\": \"./dist/es/index.js\",\n \"require\": \"./dist/cjs/index.cjs\"\n },\n \"./http\": {\n \"types\": \"./dist/types/http.d.ts\",\n \"import\": \"./dist/es/http.js\",\n \"require\": \"./dist/cjs/http.cjs\"\n },\n \"./debugger\": {\n \"types\": \"./dist/types/debugger.d.ts\",\n \"import\": \"./dist/es/debugger.js\",\n \"require\": \"./dist/cjs/debugger.cjs\"\n },\n \"./utils\": {\n \"types\": \"./dist/types/utils.d.ts\",\n \"import\": \"./dist/es/utils.js\",\n \"require\": \"./dist/cjs/utils.cjs\"\n }\n },\n \"main\": \"./dist/cjs/index.cjs\",\n \"module\": \"./dist/es/index.js\",\n \"types\": \"./dist/types/index.d.ts\",\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"build:watch\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\",\n \"docs\": \"typedoc && cp -r docs/demo docs/api/demo\",\n \"docs:watch\": \"typedoc --watch\",\n \"lint\": \"tsc --noEmit\",\n \"prepublishOnly\": \"npm run build\",\n \"release\": \"npm run build && npm publish --access public\"\n },\n \"devDependencies\": {\n \"@vitest/coverage-v8\": \"^2.0.0\",\n \"tsup\": \"^8.0.0\",\n \"typedoc\": \"^0.26.0\",\n \"typescript\": \"^5.5.3\",\n \"vitest\": \"^2.0.0\"\n },\n \"dependencies\": {\n \"axios\": \"^1.13.6\"\n }\n}\n"]}
import './chunk-BEL6AFK4.js';
export { Debugger } from './chunk-4DLFIN3C.js';
export { Cancel, CancelAll, Context, Ctx, Del, Get, HttpContext, Origin, Patch, Post, Put, Request } from './chunk-JQYH5FWE.js';
export { CleanObject, Debounce, DeepClone, Delay, FormatDate, GetDateOffset, GetDayRange, GetURLParam, GetURLParams, IsArray, IsBoolean, IsEmail, IsEqual, IsFunction, IsInteger, IsIpv4, IsNull, IsNumber, IsObject, IsPhone, IsPositiveInteger, IsRealNumber, IsString, IsUrl, Minus, ObjectToQuery, Omit, Pick, QueryToObject, REGEX, Throttle, UUID, Unique, UniqueByKey } from './chunk-WJX5Q3WL.js';
// package.json
var version = "0.2.0";
var version = "0.3.0";

@@ -8,0 +9,0 @@ export { version as VERSION };

@@ -1,1 +0,1 @@

{"version":3,"sources":["../../package.json"],"names":[],"mappings":";;;;;AAEE,IAAA,OAAA,GAAW","file":"index.js","sourcesContent":["{\n \"name\": \"@snack-kit/lib\",\n \"version\": \"0.2.0\",\n \"description\": \"Enterprise-grade utility library\",\n \"keywords\": [],\n \"license\": \"MIT\",\n \"type\": \"module\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/types/index.d.ts\",\n \"import\": \"./dist/es/index.js\",\n \"require\": \"./dist/cjs/index.cjs\"\n },\n \"./http\": {\n \"types\": \"./dist/types/http.d.ts\",\n \"import\": \"./dist/es/http.js\",\n \"require\": \"./dist/cjs/http.cjs\"\n },\n \"./debugger\": {\n \"types\": \"./dist/types/debugger.d.ts\",\n \"import\": \"./dist/es/debugger.js\",\n \"require\": \"./dist/cjs/debugger.cjs\"\n }\n },\n \"main\": \"./dist/cjs/index.cjs\",\n \"module\": \"./dist/es/index.js\",\n \"types\": \"./dist/types/index.d.ts\",\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"build:watch\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\",\n \"docs\": \"typedoc && cp -r docs/demo docs/api/demo\",\n \"docs:watch\": \"typedoc --watch\",\n \"lint\": \"tsc --noEmit\",\n \"prepublishOnly\": \"npm run build\",\n \"release\": \"npm run build && npm publish --access public\"\n },\n \"devDependencies\": {\n \"@vitest/coverage-v8\": \"^2.0.0\",\n \"tsup\": \"^8.0.0\",\n \"typedoc\": \"^0.26.0\",\n \"typescript\": \"^5.5.3\",\n \"vitest\": \"^2.0.0\"\n },\n \"dependencies\": {\n \"axios\": \"^1.13.6\"\n }\n}\n"]}
{"version":3,"sources":["../../package.json"],"names":[],"mappings":";;;;;;AAEE,IAAA,OAAA,GAAW","file":"index.js","sourcesContent":["{\n \"name\": \"@snack-kit/lib\",\n \"version\": \"0.3.0\",\n \"description\": \"Enterprise-grade utility library\",\n \"keywords\": [],\n \"license\": \"MIT\",\n \"type\": \"module\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/types/index.d.ts\",\n \"import\": \"./dist/es/index.js\",\n \"require\": \"./dist/cjs/index.cjs\"\n },\n \"./http\": {\n \"types\": \"./dist/types/http.d.ts\",\n \"import\": \"./dist/es/http.js\",\n \"require\": \"./dist/cjs/http.cjs\"\n },\n \"./debugger\": {\n \"types\": \"./dist/types/debugger.d.ts\",\n \"import\": \"./dist/es/debugger.js\",\n \"require\": \"./dist/cjs/debugger.cjs\"\n },\n \"./utils\": {\n \"types\": \"./dist/types/utils.d.ts\",\n \"import\": \"./dist/es/utils.js\",\n \"require\": \"./dist/cjs/utils.cjs\"\n }\n },\n \"main\": \"./dist/cjs/index.cjs\",\n \"module\": \"./dist/es/index.js\",\n \"types\": \"./dist/types/index.d.ts\",\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"build:watch\": \"tsup --watch\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\",\n \"docs\": \"typedoc && cp -r docs/demo docs/api/demo\",\n \"docs:watch\": \"typedoc --watch\",\n \"lint\": \"tsc --noEmit\",\n \"prepublishOnly\": \"npm run build\",\n \"release\": \"npm run build && npm publish --access public\"\n },\n \"devDependencies\": {\n \"@vitest/coverage-v8\": \"^2.0.0\",\n \"tsup\": \"^8.0.0\",\n \"typedoc\": \"^0.26.0\",\n \"typescript\": \"^5.5.3\",\n \"vitest\": \"^2.0.0\"\n },\n \"dependencies\": {\n \"axios\": \"^1.13.6\"\n }\n}\n"]}
export { Cancel, CancelAll, Context, ContextInfo, Ctx, Del, Get, HttpContext, HttpError, HttpRequestConfig, HttpResult, Origin, Patch, Post, Put, Request, ServerItem } from './http.js';
export { Debugger, DebuggerOptions } from './debugger.js';
export { CleanObject, Debounce, DeepClone, Delay, FormatDate, GetDateOffset, GetDayRange, GetURLParam, GetURLParams, IsArray, IsBoolean, IsEmail, IsEqual, IsFunction, IsInteger, IsIpv4, IsNull, IsNumber, IsObject, IsPhone, IsPositiveInteger, IsRealNumber, IsString, IsUrl, Minus, ObjectToQuery, Omit, Pick, QueryToObject, REGEX, Throttle, UUID, Unique, UniqueByKey } from './utils.js';
import 'axios';
var version = "0.2.0";
var version = "0.3.0";
export { version as VERSION };
{
"name": "@snack-kit/lib",
"version": "0.2.0",
"version": "0.3.0",
"description": "Enterprise-grade utility library",

@@ -23,2 +23,7 @@ "keywords": [],

"require": "./dist/cjs/debugger.cjs"
},
"./utils": {
"types": "./dist/types/utils.d.ts",
"import": "./dist/es/utils.js",
"require": "./dist/cjs/utils.cjs"
}

@@ -25,0 +30,0 @@ },

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display