{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/utils/string/index.ts"],"sourcesContent":["const defaultRandomAlphabet = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\nconst maximumRandomStringLength = 1_000_000;\nconst maximumRandomValuesPerBatch = 16_384;\nconst uint32Range = 0x1_0000_0000;\n\n/** 使用 Web Crypto 填充随机值，能力缺失时回退到 `Math.random()`。 */\nconst fillRandomValues = (values: Uint8Array<ArrayBuffer> | Uint32Array<ArrayBuffer>): void => {\n\tif (typeof crypto !== \"undefined\" && typeof crypto?.getRandomValues === \"function\") {\n\t\tcrypto.getRandomValues(values);\n\t\treturn;\n\t}\n\tconst range = values.BYTES_PER_ELEMENT === Uint8Array.BYTES_PER_ELEMENT ? 0x100 : uint32Range;\n\tfor (let index = 0; index < values.length; index += 1) values[index] = Math.floor(Math.random() * range);\n};\n\n/**\n * 把文本复制到系统剪贴板。\n *\n * @remarks 浏览器优先使用 Clipboard API，并在该 API 不可用时\n * 回退到 `document.execCommand(\"copy\")`。平台拒绝访问剪贴板时不会静默忽略错误。\n * @param value - 要复制的文本\n * @returns 复制完成后兑现的 Promise\n * @throws `Error` 当运行时没有可用的剪贴板能力或复制失败。\n */\nexport async function copy(value: string): Promise<void> {\n\tif (\n\t\ttypeof isSecureContext !== \"undefined\" &&\n\t\tisSecureContext &&\n\t\ttypeof navigator !== \"undefined\" &&\n\t\ttypeof navigator.clipboard?.writeText === \"function\"\n\t) {\n\t\tawait navigator.clipboard.writeText(value);\n\t\treturn;\n\t}\n\n\tif (typeof document === \"undefined\" || document === null) {\n\t\tthrow new Error(\"The current runtime does not support clipboard access.\");\n\t}\n\t// eslint-disable-next-line @typescript-eslint/no-deprecated -- 兼容不支持 Clipboard API 的旧 WebView。\n\tif (typeof document.createElement !== \"function\" || document.body == null || typeof document.execCommand !== \"function\") {\n\t\tthrow new Error(\"The current runtime does not support clipboard access.\");\n\t}\n\tconst textarea = document.createElement(\"textarea\");\n\ttextarea.value = value;\n\ttextarea.style.left = \"-999999px\";\n\ttextarea.style.opacity = \"0\";\n\ttextarea.style.position = \"fixed\";\n\ttextarea.style.top = \"-999999px\";\n\tdocument.body.appendChild(textarea);\n\tlet copied: boolean;\n\ttry {\n\t\ttextarea.focus();\n\t\ttextarea.select();\n\t\t// eslint-disable-next-line @typescript-eslint/no-deprecated -- 兼容不支持 Clipboard API 的旧 WebView。\n\t\tcopied = document.execCommand(\"copy\");\n\t} finally {\n\t\ttextarea.remove();\n\t}\n\tif (!copied) throw new Error(\"Failed to copy text to the clipboard.\");\n}\n\n/**\n * 生成随机字符串。\n *\n * @remarks 优先使用 Web Crypto；平台缺少安全随机能力时回退到 `Math.random()`。\n * @param length - 字符数量，必须是 0 至 1,000,000 的安全整数。\n * @param alphabet - 不得为空、包含重复字符或超过 2^32 个 Unicode 码点。\n * @returns 由 `alphabet` 中 Unicode 码点组成的随机文本\n * @throws `RangeError` 当长度或字母表非法。\n */\nexport function randomString(length: number, alphabet: string = defaultRandomAlphabet): string {\n\tif (!Number.isSafeInteger(length) || length < 0 || length > maximumRandomStringLength) {\n\t\tthrow new RangeError(`\\`length\\` must be a safe integer between 0 and ${maximumRandomStringLength}.`);\n\t}\n\tconst characters = Array.from(alphabet);\n\tif (characters.length === 0) throw new RangeError(\"`alphabet` must not be empty.\");\n\tif (new Set(characters).size !== characters.length) throw new RangeError(\"`alphabet` must not contain duplicate characters.\");\n\tif (characters.length > 0x1_0000_0000) throw new RangeError(\"`alphabet` must not contain more than 2^32 characters.\");\n\tif (length === 0) return \"\";\n\n\t// 丢弃不能平均映射到字母表的尾部区间，避免 `%` 造成前部字符概率偏高。\n\tconst acceptanceLimit = Math.floor(uint32Range / characters.length) * characters.length;\n\tconst result: string[] = [];\n\twhile (result.length < length) {\n\t\tconst remaining = length - result.length;\n\t\t// 分批填充可控制临时内存，并避开 Web Crypto 单次随机数组大小限制。\n\t\tconst samples = new Uint32Array(Math.min(remaining, maximumRandomValuesPerBatch));\n\t\tfillRandomValues(samples);\n\t\tfor (const sample of samples) {\n\t\t\tif (sample >= acceptanceLimit) continue;\n\t\t\tconst character = characters[sample % characters.length];\n\t\t\tif (character === undefined) continue;\n\t\t\tresult.push(character);\n\t\t\tif (result.length === length) break;\n\t\t}\n\t}\n\treturn result.join(\"\");\n}\n"],"mappings":";AAAA,MAAM,wBAAwB;AAC9B,MAAM,4BAA4B;AAClC,MAAM,8BAA8B;AACpC,MAAM,cAAc;;AAGpB,MAAM,oBAAoB,WAAqE;CAC9F,IAAI,OAAO,WAAW,eAAe,OAAO,QAAQ,oBAAoB,YAAY;EACnF,OAAO,gBAAgB,MAAM;EAC7B;CACD;CACA,MAAM,QAAQ,OAAO,sBAAsB,WAAW,oBAAoB,MAAQ;CAClF,KAAK,IAAI,QAAQ,GAAG,QAAQ,OAAO,QAAQ,SAAS,GAAG,OAAO,SAAS,KAAK,MAAM,KAAK,OAAO,IAAI,KAAK;AACxG;;;;;;;;;;AAWA,eAAsB,KAAK,OAA8B;CACxD,IACC,OAAO,oBAAoB,eAC3B,mBACA,OAAO,cAAc,eACrB,OAAO,UAAU,WAAW,cAAc,YACzC;EACD,MAAM,UAAU,UAAU,UAAU,KAAK;EACzC;CACD;CAEA,IAAI,OAAO,aAAa,eAAe,aAAa,MACnD,MAAM,IAAI,MAAM,wDAAwD;CAGzE,IAAI,OAAO,SAAS,kBAAkB,cAAc,SAAS,QAAQ,QAAQ,OAAO,SAAS,gBAAgB,YAC5G,MAAM,IAAI,MAAM,wDAAwD;CAEzE,MAAM,WAAW,SAAS,cAAc,UAAU;CAClD,SAAS,QAAQ;CACjB,SAAS,MAAM,OAAO;CACtB,SAAS,MAAM,UAAU;CACzB,SAAS,MAAM,WAAW;CAC1B,SAAS,MAAM,MAAM;CACrB,SAAS,KAAK,YAAY,QAAQ;CAClC,IAAI;CACJ,IAAI;EACH,SAAS,MAAM;EACf,SAAS,OAAO;EAEhB,SAAS,SAAS,YAAY,MAAM;CACrC,UAAU;EACT,SAAS,OAAO;CACjB;CACA,IAAI,CAAC,QAAQ,MAAM,IAAI,MAAM,uCAAuC;AACrE;;;;;;;;;;AAWA,SAAgB,aAAa,QAAgB,WAAmB,uBAA+B;CAC9F,IAAI,CAAC,OAAO,cAAc,MAAM,KAAK,SAAS,KAAK,SAAS,2BAC3D,MAAM,IAAI,WAAW,mDAAmD,0BAA0B,EAAE;CAErG,MAAM,aAAa,MAAM,KAAK,QAAQ;CACtC,IAAI,WAAW,WAAW,GAAG,MAAM,IAAI,WAAW,+BAA+B;CACjF,IAAI,IAAI,IAAI,UAAU,CAAC,CAAC,SAAS,WAAW,QAAQ,MAAM,IAAI,WAAW,mDAAmD;CAC5H,IAAI,WAAW,SAAS,YAAe,MAAM,IAAI,WAAW,wDAAwD;CACpH,IAAI,WAAW,GAAG,OAAO;CAGzB,MAAM,kBAAkB,KAAK,MAAM,cAAc,WAAW,MAAM,IAAI,WAAW;CACjF,MAAM,SAAmB,CAAC;CAC1B,OAAO,OAAO,SAAS,QAAQ;EAC9B,MAAM,YAAY,SAAS,OAAO;EAElC,MAAM,UAAU,IAAI,YAAY,KAAK,IAAI,WAAW,2BAA2B,CAAC;EAChF,iBAAiB,OAAO;EACxB,KAAK,MAAM,UAAU,SAAS;GAC7B,IAAI,UAAU,iBAAiB;GAC/B,MAAM,YAAY,WAAW,SAAS,WAAW;GACjD,IAAI,cAAc,KAAA,GAAW;GAC7B,OAAO,KAAK,SAAS;GACrB,IAAI,OAAO,WAAW,QAAQ;EAC/B;CACD;CACA,OAAO,OAAO,KAAK,EAAE;AACtB"}