@h3ravel/support 0.14.0 → 0.14.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.cjs +1 -2
- package/dist/index.d.cts +1 -2
- package/dist/index.d.ts +1 -2
- package/dist/index.js +1 -2
- package/package.json +2 -2
- package/dist/index.cjs.map +0 -1
- package/dist/index.js.map +0 -1
package/dist/index.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["numString: string","classes: string[]","parts: string[]","result: Record<string, any>","node: any","current: any","current: Record<string, any>","result: X[]","inputs: A[] | A[][]","product: A[][]","result: Record<string, A | Record<string, A>>","out: Record<string, A>","result: Record<string, T>","k: string | number","result: Record<string, V>","truthy: T[]","falsy: T[]","chunks: T[][]","result: T[]","result: number[]","utc","timezone","dayOfYear","isBetween","isLeapYear","relativeTime","advancedFormat","customParseFormat","format","position: number","result: string","position: number | null","results: string","result: boolean","radius: number","omission: string","results: string[]","matches: string[]","start: string","end: string","wordsArray: string[]","patterns: string[]","pattern","protocolPattern: string","trimmed: string","start: number | string","endIndex: number","segment: string","strLen: number","startIndex: number","segmentLen: number","body: string","flags: string","expression: RegExp","matches: RegExpMatchArray | null","matches: RegExpMatchArray[]","short: number","shortLeft: number","shortRight: number","plural: { [key: string]: string }","irregular: { [key: string]: string }","pattern: RegExp","parts: string[]","lastWord: string","password: string[]","collection: string[]","byteSize: number","bytes: string","string: string","next: number","factoryCache: Function | null","randomString: string","segments: string[]","quoted: string","str","minorWords: string[]","endPunctuation: string[]","words: string[]","i: number","lowercaseWord: string","hyphenatedWords: string[]","singular: { [key: string]: string }","flip: string","regex: RegExp","breakWithSpace: string","time: number","randomChar: number","timestamp: number","randomA: number","randomBHi: number","randomBLo: number","uuid: string","uuid","encoding: string","encodingLength: number","timeLength: number","randomLength: number","encodedTime: string","now: number","length: number","mod: number","buffer: Uint8Array","randomNumber: number","ulid: string","#value","basename: string","dirname: string","isValidDirname: boolean","hasValidLevels: boolean","value: number","format","date: string","now: Date","month: number","dayOfTheWeek: number","dayOfTheMonth: number","year: number","hours: number","minutes: number","seconds: number","milliseconds: number","elements: RegExpMatchArray | null","start: Date","diff: number","currentDay: number","parsedDate: Date","weekDay: number","yearStart: Date","weekNumber: number","currentMonth: number","hours","minutes","seconds","january: number","july: number","timeZoneData: string","timezone: string","symbol: RegExpMatchArray | null","timezone","data: string[]","sign: string","offset: string","offsetInSeconds: number","tag: RegExpExecArray | null","DOM: HTMLElement","html: HtmlStringType","expression: RegExpExecArray | null","escaped: string","cases: ((value: string) => string)[]","value","globalHelpers: GlobalHelpers","DumpDie","SimpleObj.dot","SimpleObj.undot","SimpleObj.extractProperties","SimpleObj.getValue","SimpleObj.modObj","SimpleObj.safeDot","SimpleObj.setNested","SimpleObj.toCssClasses","SimpleObj.slugifyKeys","SimpleObj.toCssStyles","SimpleObj.data_get","SimpleObj.data_set","SimpleObj.data_fill","SimpleObj.data_forget","Crypto.uuid","Crypto.random","Crypto.randomSecure","Crypto.hash","Crypto.hmac","Crypto.base64Encode","Crypto.base64Decode","Crypto.xor","Crypto.randomColor","Crypto.randomPassword","Crypto.secureToken","Crypto.checksum","Crypto.verifyChecksum","Crypto.caesarCipher","Number.abbreviate","Number.humanize","Number.toBytes","Number.toHumanTime","DumpDie.dump","DumpDie.dd"],"sources":["../src/Exceptions/InvalidArgumentException.ts","../src/Exceptions/RuntimeException.ts","../src/Helpers/Crypto.ts","../src/Helpers/DumpDie.ts","../src/Helpers/Number.ts","../src/Helpers/Obj.ts","../src/Helpers/Arr.ts","../src/Helpers/Time.ts","../src/Helpers/Str.ts","../src/GlobalBootstrap.ts"],"sourcesContent":["/**\n * Custom error for invalid type coercion\n */\nexport class InvalidArgumentException extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'InvalidArgumentException'\n }\n}\n","/**\n * Custom error for invalid type coercion\n */\nexport class RuntimeException extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'RuntimeException'\n }\n}\n","import { createHash, createHmac, randomBytes, randomUUID } from 'crypto'\n\n/**\n * Generate a random UUID string.\n * \n * @returns A random UUID string\n */\nexport const uuid = (): string => {\n return randomUUID()\n}\n\n/**\n * Generate a random string of specified length.\n * \n * @param length - Length of the random string (default: 16)\n * @param charset - Character set to use (default: alphanumeric)\n * @returns A random string\n */\nexport const random = (length: number = 16, charset: string = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'): string => {\n let result = ''\n for (let i = 0; i < length; i++) {\n result += charset.charAt(Math.floor(Math.random() * charset.length))\n }\n return result\n}\n\n/**\n * Secure random string generator that uses crypto.randomBytes.\n * \n * @param length - Length of the random string (default: 32)\n * @returns A cryptographically secure random string\n */\nexport const randomSecure = (length: number = 32): string => {\n return randomBytes(Math.ceil(length / 2)).toString('hex').slice(0, length)\n}\n\n/**\n * Hash a string using the specified algorithm.\n * \n * @param data - Data to hash\n * @param algorithm - Hash algorithm (default: 'sha256')\n * @returns Hexadecimal hash string\n */\nexport const hash = (data: string, algorithm: string = 'sha256'): string => {\n return createHash(algorithm).update(data).digest('hex')\n}\n\n/**\n * Hash a string with salt using HMAC.\n * \n * @param data - Data to hash\n * @param key - Secret key for HMAC\n * @param algorithm - Hash algorithm (default: 'sha256')\n * @returns Hexadecimal hash string\n */\nexport const hmac = (data: string, key: string, algorithm: string = 'sha256'): string => {\n return createHmac(algorithm, key).update(data).digest('hex')\n}\n\n/**\n * Encode data to base64.\n * \n * @param data - Data to encode\n * @returns Base64 encoded string\n */\nexport const base64Encode = (data: string): string => {\n return Buffer.from(data, 'utf8').toString('base64')\n}\n\n/**\n * Decode base64 data.\n * \n * @param data - Base64 string to decode\n * @returns Decoded string\n */\nexport const base64Decode = (data: string): string => {\n return Buffer.from(data, 'base64').toString('utf8')\n}\n\n/**\n * Simple XOR encryption/decryption.\n * \n * @param data - Data to encrypt/decrypt\n * @param key - Encryption key\n * @returns Encrypted/decrypted string\n */\nexport const xor = (data: string, key: string): string => {\n let result = ''\n const keyLength = key.length\n\n for (let i = 0; i < data.length; i++) {\n const dataCharCode = data.charCodeAt(i)\n const keyCharCode = key.charCodeAt(i % keyLength)\n result += String.fromCharCode(dataCharCode ^ keyCharCode)\n }\n\n return result\n}\n\n/**\n * Generate a random hex color code.\n * \n * @returns A hex color code string (e.g., '#a3b2f3')\n */\nexport const randomColor = (): string => {\n const hex = random(6, '0123456789abcdef').toLowerCase()\n return `#${hex}`\n}\n\n/**\n * Generate a secure password using configurable parameters.\n * \n * @param length - Password length (default: 16)\n * @param options - Character options\n * @returns A secure password string\n */\ninterface PasswordOptions {\n useUppercase?: boolean\n useLowercase?: boolean\n useNumbers?: boolean\n useSymbols?: boolean\n}\n\nexport const randomPassword = (length: number = 16, options: PasswordOptions = {}): string => {\n const defaults: Required<PasswordOptions> = {\n useUppercase: true,\n useLowercase: true,\n useNumbers: true,\n useSymbols: true\n }\n\n const opts = { ...defaults, ...options }\n let charset = ''\n\n if (opts.useUppercase) charset += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'\n if (opts.useLowercase) charset += 'abcdefghijklmnopqrstuvwxyz'\n if (opts.useNumbers) charset += '0123456789'\n if (opts.useSymbols) charset += '!@#$%^&*()_+-=[]{}|;:,.<>?'\n\n if (charset.length === 0) {\n throw new Error('At least one character type must be enabled')\n }\n\n return random(length, charset)\n}\n\n/**\n * Generate a cryptographically secure token for APIs, sessions, etc.\n * \n * @param strength - Token strength (bytes) (default: 32)\n * @returns A secure token string\n */\nexport const secureToken = (strength: number = 32): string => {\n return randomBytes(strength).toString('hex')\n}\n\n/**\n * Create a checksum for data integrity verification.\n * \n * @param data - Data to create checksum for\n * @param algorithm - Hash algorithm (default: 'sha256')\n * @returns SHA256 checksum\n */\nexport const checksum = (data: string, algorithm: string = 'sha256'): string => {\n return hash(data, algorithm)\n}\n\n/**\n * Verify data integrity using checksum.\n * \n * @param data - Data to verify\n * @param expectedChecksum - Expected checksum\n * @param algorithm - Hash algorithm (default: 'sha256')\n * @returns True if checksums match\n */\nexport const verifyChecksum = (data: string, expectedChecksum: string, algorithm: string = 'sha256'): boolean => {\n const actualChecksum = checksum(data, algorithm)\n return actualChecksum === expectedChecksum\n}\n\n/**\n * Simple Caesar cipher implementation.\n * \n * @param text - Text to encrypt/decrypt\n * @param shift - Number of positions to shift (default: 13)\n * @returns Encrypted/decrypted text\n */\nexport const caesarCipher = (text: string, shift: number = 13): string => {\n return text.replace(/[a-zA-Z]/g, (char: string) => {\n const isUpperCase = char === char.toUpperCase()\n const baseCharCode = isUpperCase ? 'A' : 'a'\n const shiftedCharCode = ((char.charCodeAt(0) - baseCharCode.charCodeAt(0) + shift) % 26)\n const newCharCode = (shiftedCharCode < 0 ? 26 + shiftedCharCode : shiftedCharCode) + baseCharCode.charCodeAt(0)\n return String.fromCharCode(newCharCode)\n })\n}\n","import process from 'process'\nimport util from 'util'\n\nconst inspect = (thing: any) => {\n return util.inspect(thing, {\n showHidden: true,\n depth: null,\n colors: true\n })\n}\n\n/**\n * Dump something and kill the process for quick debugging. Based on Laravel's dd()\n * \n * @param args \n */\nexport const dd = (...args: unknown[]): never => {\n args.forEach((thing) => {\n console.log(inspect(thing))\n })\n\n process.exit(1)\n}\n\n/**\n * Dump something but keep the process for quick debugging. Based on Laravel's dump()\n * \n * @param args \n */\nexport const dump = (...args: unknown[]): void => {\n args.forEach((thing) => {\n console.log(inspect(thing))\n })\n} \n","/**\n * Abbreviates large numbers using SI symbols (K, M, B...) \n * and formats the output according to the given locale.\n *\n * @param value - The number to abbreviate\n * @param locale - Optional locale string (default: \"en-US\")\n * @returns A localized, abbreviated number string\n */\nexport const abbreviate = (value?: number, locale: string = 'en-US'): string => {\n if (!value) return '0'\n\n // Numbers less than 1000 don't need abbreviation\n if (value < 1000) {\n return new Intl.NumberFormat(locale).format(value)\n }\n\n const si = [\n { v: 1e18, s: 'E' },\n { v: 1e15, s: 'P' },\n { v: 1e12, s: 'T' },\n { v: 1e9, s: 'B' },\n { v: 1e6, s: 'M' },\n { v: 1e3, s: 'K' },\n ]\n\n const match = si.find(scale => value >= scale.v)\n if (!match) return new Intl.NumberFormat(locale).format(value)\n\n const formatted = value / match.v\n\n return (\n new Intl.NumberFormat(locale, {\n minimumFractionDigits: 0,\n maximumFractionDigits: 2,\n }).format(formatted) + match.s\n )\n}\n\n/**\n * Concverts a number into human readable string\n *\n * @param num The number to convert\n * @param slugify convert the ouput into a slug using this as a separator\n * @returns\n */\nexport const humanize = (num: number, slugify?: '-' | '_'): string => {\n if (!num) {\n return ''\n }\n\n if (slugify === '-' || slugify === '_') {\n const h = humanize(num)\n return typeof h === 'string' ? h.replace(' ', slugify).toLowerCase() : h\n }\n\n const ones = [\n '',\n 'one',\n 'two',\n 'three',\n 'four',\n 'five',\n 'six',\n 'seven',\n 'eight',\n 'nine',\n 'ten',\n 'eleven',\n 'twelve',\n 'thirteen',\n 'fourteen',\n 'fifteen',\n 'sixteen',\n 'seventeen',\n 'eighteen',\n 'nineteen',\n ]\n const tens = [\n '',\n '',\n 'twenty',\n 'thirty',\n 'forty',\n 'fifty',\n 'sixty',\n 'seventy',\n 'eighty',\n 'ninety',\n ]\n\n const numString: string = num.toString()\n\n if (num < 0) throw new Error('Negative numbers are not supported.')\n\n if (num === 0) return 'zero'\n\n //the case of 1 - 20\n if (num < 20) {\n return ones[num] ?? ''\n }\n\n if (numString.length === 2) {\n return tens[numString[0] as unknown as number] + ' ' + ones[numString[1] as unknown as number]\n }\n\n //100 and more\n if (numString.length == 3) {\n if (numString[1] === '0' && numString[2] === '0')\n return ones[numString[0] as unknown as number] + ' hundred'\n else\n return (\n ones[numString[0] as unknown as number] +\n ' hundred and ' +\n humanize(+((numString[1] || '') + numString[2]), slugify)\n )\n }\n\n if (numString.length === 4) {\n const end = +((numString[1] || '') + numString[2] + numString[3])\n if (end === 0) return ones[numString[0] as unknown as number] + ' thousand'\n if (end < 100)\n return ones[numString[0] as unknown as number] + ' thousand and ' + humanize(end, slugify)\n return ones[numString[0] as unknown as number] + ' thousand ' + humanize(end, slugify)\n }\n\n return num as unknown as string\n}\n\n/**\n * Converts a number of bytes into a human-readable string.\n *\n * @param bytes - The size in bytes to convert\n * @param decimals - Number of decimal places to display (default: 2)\n * @param bits - If true, uses 1000-based (SI) units (B, KB, MB...); \n * otherwise uses 1024-based binary units (Bytes, KiB...)\n * @returns A formatted string with the appropriate unit\n */\nexport const toBytes = (\n bytes?: number,\n decimals: number = 2,\n bits: boolean = false\n): string => {\n if (!bytes || isNaN(bytes)) {\n return bits ? '0 B' : '0 Bytes'\n }\n\n const base = bits ? 1000 : 1024\n const dm = decimals < 0 ? 0 : decimals\n const sizes = bits\n ? ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] // SI units\n : ['Bytes', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'] // Binary units\n\n const index = Math.floor(Math.log(bytes) / Math.log(base))\n\n const value = parseFloat((bytes / Math.pow(base, index)).toFixed(dm))\n return `${value} ${sizes[index]}`\n}\n\n/**\n * Formats a duration (in seconds) into a human-readable string.\n *\n * @param seconds - Duration in seconds\n * @param worded - If true, outputs worded format (e.g., \"1hr 2min 3sec\"),\n * otherwise HH:MM:SS (e.g., \"01:02:03\")\n * @returns A formatted time string\n */\nexport const toHumanTime = (\n seconds: number = 0,\n worded: boolean = false\n): string => {\n // Ensure seconds is a number and not negative\n if (isNaN(seconds) || seconds < 0) seconds = 0\n\n const hours = Math.floor(seconds / 3600)\n const minutes = Math.floor((seconds % 3600) / 60)\n const secs = Math.floor(seconds % 60)\n\n // Worded format → \"1hr 2min 3sec\"\n if (worded) {\n const parts = []\n if (hours) parts.push(`${hours}hr`)\n if (minutes) parts.push(`${minutes}min`)\n if (secs || (!hours && !minutes)) parts.push(`${secs}sec`)\n return parts.join(' ')\n }\n\n // HH:MM:SS format → zero-padded\n const hh = hours > 0 ? `${hours}:` : ''\n const mm = (hours > 0 && minutes < 10 ? `0${minutes}` : minutes) + ':'\n const ss = secs < 10 ? `0${secs}` : secs\n\n return `${hh}${mm}${ss}`\n}\n\n","import type { DotFlatten, DotNestedKeys, DotNestedValue } from '@h3ravel/shared'\nimport type { DotPath, KeysToSnakeCase } from '../Contracts/ObjContract'\n\n/**\n * Flattens a nested object into a single-level object\n * with dot-separated keys.\n *\n * Example:\n * doter({\n * user: { name: \"John\", address: { city: \"NY\" } },\n * active: true\n * })\n * \n * Output:\n * {\n * \"user.name\": \"John\",\n * \"user.address.city\": \"NY\",\n * \"active\": true\n * }\n *\n * @template T - The type of the input object\n * @param obj - The nested object to flatten\n * @returns A flattened object with dotted keys and inferred types\n */\nexport const dot = <T extends Record<string, any>> (obj: T): DotFlatten<T> => {\n const result = {} as Record<string, unknown>\n\n /**\n * Internal recursive function to traverse and flatten the object.\n * \n * @param o - Current object to flatten\n * @param prefix - Key path accumulated so far\n */\n const recurse = (o: Record<string, any>, prefix = ''): void => {\n for (const [key, value] of Object.entries(o)) {\n const newKey = prefix ? `${prefix}.${key}` : key\n\n /**\n * Recurse if the value is a plain object\n */\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n recurse(value, newKey)\n } else {\n /**\n * Otherwise, assign directly\n */\n result[newKey] = value\n }\n }\n }\n\n recurse(obj)\n return result as DotFlatten<T>\n}\n\n/**\n * Extracts a subset of properties from an object.\n *\n * @template T - Type of the source object\n * @template K - Keys of T to extract\n * @param obj - The source object\n * @param keys - Array of keys to extract\n * @returns A new object with only the specified keys\n */\nexport const extractProperties = <T extends object, K extends keyof T> (\n obj: T,\n keys: readonly K[] = []\n): Pick<T, K> => {\n return Object.fromEntries(\n keys.map(key => [key, obj[key]])\n ) as Pick<T, K>\n}\n\n/**\n * Safely retrieves a value from an object by key or nested keys.\n *\n * @template T - Type of the source object\n * @param key - Single key or tuple [parentKey, childKey]\n * @param item - The source object\n * @returns The found value as a string or the key itself if not found\n */\nexport const getValue = <\n T extends Record<string, any> // Allow nested objects\n> (\n key: string | [keyof T, keyof T[string]],\n item: T\n): string => {\n if (Array.isArray(key)) {\n const [parent, child] = key\n\n if (child !== undefined) {\n // Access nested property: item[parent][child]\n return (\n String(item?.[parent]?.[child] ??\n item?.[parent] ??\n `${String(parent)}.${String(child)}`)\n )\n }\n\n // Only top-level key\n return String(item?.[parent] ?? parent)\n }\n\n // Single key access\n return String(item?.[key] ?? key)\n}\n\n/**\n * Maps over an object's entries and returns a new object \n * with transformed keys and/or values.\n *\n * @template T - Type of the input object\n * @template R - Type of the new values\n * @param obj - The object to transform\n * @param callback - Function that receives [key, value] and returns [newKey, newValue]\n * @returns A new object with transformed entries\n */\nexport const modObj = <T extends object, R> (\n obj: T,\n callback: (_entry: [keyof T & string, T[keyof T]]) => [string, R]\n): Record<string, R> => {\n return Object.fromEntries(\n Object.entries(obj).map(([key, value]) =>\n callback([key as keyof T & string, value as T[keyof T]])\n )\n ) as Record<string, R>\n}\n\n\nexport function safeDot<T extends Record<string, any>> (_data: T): T\nexport function safeDot<\n T extends Record<string, any>,\n K extends DotNestedKeys<T>\n> (_data: T, _key?: K): DotNestedValue<T, K>\nexport function safeDot<\n T extends Record<string, any>,\n K extends DotNestedKeys<T>\n> (data: T, key?: K): any {\n if (!key) return data\n return key.split('.').reduce((acc: any, k) => acc?.[k], data)\n}\n\n/**\n * Sets a nested property on an object using dot notation.\n * \n * @example\n * const obj = {}\n * setNested(obj, 'app.user.name', 'Legacy')\n * console.log(obj)\n * // Output: { app: { user: { name: 'Legacy' } } }\n * \n * @param obj - The target object to modify.\n * @param key - The dot-separated key (e.g., 'app.user.name').\n * @param value - The value to set at the specified path.\n */\nexport const setNested = (\n obj: Record<string, any>,\n key: string,\n value: any\n): void => {\n if (!key.includes('.')) {\n obj[key] = value\n return\n }\n\n const parts = key.split('.')\n let current = obj\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i]\n\n /**\n * If we're at the last key, assign the value\n */\n if (i === parts.length - 1) {\n current[part] = value\n } else {\n /**\n * If the key doesn't exist or isn't an object, create it\n */\n if (typeof current[part] !== 'object' || current[part] === null) {\n current[part] = {}\n }\n current = current[part]\n }\n }\n}\n\n/**\n * Converts object keys to a slugified format (e.g., snake_case).\n *\n * @template T - Type of the input object\n * @param obj - The object whose keys will be slugified\n * @param only - Optional array of keys to slugify (others remain unchanged)\n * @param separator - Separator for slugified keys (default: \"_\")\n * @returns A new object with slugified keys\n */\nexport const slugifyKeys = <T extends object> (\n obj: T,\n only: string[] = [],\n separator: string = '_'\n): KeysToSnakeCase<T> => {\n const slugify = (key: string): string =>\n key\n .replace(/([a-z])([A-Z])/g, `$1${separator}$2`) // Handle camelCase\n .replace(/[\\s\\W]+/g, separator) // Replace spaces/symbols\n .replace(new RegExp(`${separator}{2,}`, 'g'), separator) // Remove duplicate separators\n .replace(new RegExp(`^${separator}|${separator}$`, 'g'), '') // Trim edges\n .toLowerCase()\n\n let entries = Object.entries(obj)\n\n // Filter if `only` is provided\n if (only.length) {\n entries = entries.filter(([key]) => only.includes(key))\n }\n\n return Object.fromEntries(\n entries.map(([key, value]) => [slugify(key), value])\n ) as KeysToSnakeCase<T>\n}\n\n/**\n * toCssClasses\n *\n * Convert array/object/string input into a CSS class string.\n * - Arrays: included if truthy\n * - Objects: keys included if value is truthy\n * - Strings: included as-is\n */\nexport function toCssClasses<T extends string | Record<string, boolean> | Array<string | false | null | undefined>> (\n input: T\n): string {\n if (!input) return ''\n const classes: string[] = []\n\n if (typeof input === 'string') {\n return input.trim()\n }\n\n if (Array.isArray(input)) {\n input.forEach(item => {\n if (item) classes.push(String(item).trim())\n })\n } else if (typeof input === 'object') {\n for (const [key, value] of Object.entries(input)) {\n if (value) classes.push(key)\n }\n }\n\n return classes.join(' ')\n}\n\n/**\n * toCssStyles\n *\n * Convert object input into CSS style string.\n * - Only includes truthy values (ignores null/undefined/false)\n */\nexport function toCssStyles<T extends Record<string, string | number | boolean | null | undefined>> (styles: T): string {\n const parts: string[] = []\n for (const [k, v] of Object.entries(styles)) {\n if (v === null || v === undefined || v === false) continue\n parts.push(`${k}:${v}`)\n }\n return parts.join(';')\n}\n\n/**\n * undot\n *\n * Convert a dot-notated object back into nested structure.\n *\n * Example:\n * undot({ 'a.b': 1, 'c.0': 2 }) -> { a: { b: 1 }, c: [2] }\n */\nexport function undot (obj: Record<string, any>): Record<string, any> {\n const result: Record<string, any> = {}\n\n for (const [key, value] of Object.entries(obj)) {\n const parts = key.split('.')\n let node: any = result\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i]\n const isLast = i === parts.length - 1\n const nextPart = parts[i + 1]\n\n const isArrayIndex = !isNaN(Number(nextPart))\n\n if (isLast) {\n node[part] = value\n } else {\n if (!(part in node)) {\n node[part] = isArrayIndex ? [] : {}\n }\n node = node[part]\n }\n }\n }\n\n return result\n}\n\n/**\n * data_get\n *\n * Get a value from an object using dot notation.\n */\nexport function data_get<\n T extends object,\n P extends DotPath<T> | DotPath<T>[],\n D = undefined\n> (obj: T, path: P, defaultValue?: D): T | any {\n if (!obj) return defaultValue\n const parts = Array.isArray(path) ? path : path.split('.')\n let current: any = obj\n for (const part of parts) {\n if (!current || !(part in current)) return defaultValue\n current = current[part]\n }\n return current\n}\n\n/**\n * data_set\n *\n * Set a value in an object using dot notation. Mutates the object.\n */\nexport function data_set<\n T extends Record<string, any>,\n P extends string | string[],\n V\n> (obj: T, path: P, value: V): asserts obj is T & Record<P extends string ? P : P[0], V> {\n const parts = Array.isArray(path) ? path : path.split('.')\n let current: Record<string, any> = obj\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i]\n if (i === parts.length - 1) {\n current[part] = value\n } else {\n if (!(part in current) || typeof current[part] !== 'object' || current[part] === null) {\n current[part] = {}\n }\n current = current[part]\n }\n }\n}\n\n/**\n * data_fill\n *\n * Like data_set, but only sets the value if the key does NOT exist.\n */\nexport function data_fill (\n obj: Record<string, any>,\n path: string | string[],\n value: any\n): void {\n if (data_get(obj, path) === undefined) {\n data_set(obj, path, value)\n }\n}\n\n/**\n * data_forget\n *\n * Remove a key from an object using dot notation.\n */\nexport function data_forget (\n obj: Record<string, any>,\n path: string | string[]\n): void {\n const parts = Array.isArray(path) ? path : path.split('.')\n let current = obj\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i]\n if (i === parts.length - 1) {\n delete current[part]\n } else {\n if (!current[part] || typeof current[part] !== 'object') break\n current = current[part]\n }\n }\n}\n\nexport class Obj {\n /**\n * Check if the value is a non-null object (associative/accessible).\n */\n static accessible (value: unknown): value is Record<string, any> {\n return value !== null && typeof value === 'object'\n }\n\n /**\n * Add a key-value pair to an object only if the key does not already exist.\n *\n * Returns a new object (does not mutate original).\n */\n static add<T extends Record<string, any>, K extends string, V> (\n obj: T,\n key: K,\n value: V\n ): T & Record<K, V> {\n if (!(key in obj)) {\n return { ...obj, [key]: value }\n }\n return obj as T & Record<K, V>\n }\n\n /**\n * Split object into [keys, values]\n */\n static divide<T extends Record<string, any>> (obj: T): [string[], any[]] {\n const keys = Object.keys(obj)\n const values = Object.values(obj)\n return [keys, values]\n }\n\n /**\n * Check if a key exists in the object.\n */\n static exists<T extends Record<string, any>> (obj: T, key: string | number): boolean {\n return Object.prototype.hasOwnProperty.call(obj, key)\n }\n\n /**\n * Get a value from an object using dot notation.\n *\n * Example:\n * Obj.get({a:{b:1}}, 'a.b') -> 1\n */\n static get<\n T extends object,\n P extends DotPath<T>,\n D = undefined\n > (obj: T, path: P, defaultValue?: D): any {\n if (!Obj.accessible(obj)) return defaultValue\n\n const parts = Array.isArray(path) ? path : path.split('.')\n let current: any = obj\n\n for (const part of parts) {\n if (!Obj.accessible(current) || !(part in current)) {\n return defaultValue\n }\n current = current[part]\n }\n return current\n }\n\n /**\n * Check if the object has a given key or keys (dot notation supported).\n */\n static has<T extends object, P extends DotPath<T>> (\n obj: T,\n keys: P | P[]\n ): boolean {\n if (!Obj.accessible(obj)) return false\n const keyArray = Array.isArray(keys) ? keys : [keys]\n\n return keyArray.every(key => {\n const parts = key.split('.')\n let current: any = obj\n for (const part of parts) {\n if (!Obj.accessible(current) || !(part in current)) return false\n current = current[part]\n }\n return true\n })\n }\n\n /**\n * Check if an object is associative (has at least one non-numeric key).\n */\n static isAssoc (obj: unknown): obj is Record<string, any> {\n if (!Obj.accessible(obj)) return false\n return Object.keys(obj).some(k => isNaN(Number(k)))\n }\n\n /**\n * Add a prefix to all keys of the object.\n */\n static prependKeysWith<T extends Record<string, any>> (obj: T, prefix: string): Record<string, any> {\n if (!Obj.accessible(obj)) return {}\n const result: Record<string, any> = {}\n for (const [k, v] of Object.entries(obj)) {\n result[`${prefix}${k}`] = v\n }\n return result\n }\n\n /**\n * Convert an object into a URL query string.\n *\n * Nested objects/arrays are flattened using bracket notation.\n */\n static query (obj: Record<string, any>): string {\n const encode = encodeURIComponent\n const parts: string[] = []\n\n function build (key: string, value: any) {\n if (Array.isArray(value)) {\n value.forEach((v, i) => build(`${key}[${i}]`, v))\n } else if (Obj.accessible(value)) {\n Object.entries(value).forEach(([k, v]) => build(`${key}[${k}]`, v))\n } else {\n parts.push(`${encode(key)}=${encode(value)}`)\n }\n }\n\n Object.entries(obj).forEach(([k, v]) => build(k, v))\n return parts.join('&')\n }\n}\n","\nimport { Arrayable, Jsonable, JsonSerializable } from '../Contracts/TypeCast'\nimport { InvalidArgumentException } from '../Exceptions/InvalidArgumentException'\nimport { data_get } from './Obj'\n\n/**\n * Arr — Laravel-like array helpers for JavaScript.\n *\n * - Methods aim for clear, predictable JS behavior.\n * - Inputs are validated where useful; functions try not to mutate arguments.\n */\n\nexport class Arr {\n /**\n * Helper: is a value an object (but not null).\n */\n static _isObject (value: any) {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n }\n\n /**\n * Helper: deep clone for safety (simple).\n * Uses JSON methods — good for typical data shapes (no functions, Dates, Maps).\n */\n static _clone<A = any> (value: A): A {\n try {\n return JSON.parse(JSON.stringify(value))\n } catch {\n return value\n }\n }\n\n /**\n * Retrieve a value using dot notation\n * Throws if value is not an array\n */\n static array (obj: any, path: string, defaultValue?: number): any[] {\n const val = data_get(obj, path, defaultValue)\n if (!Array.isArray(val)) {\n throw new InvalidArgumentException(`Value at \"${path}\" is not an array.`)\n }\n return val\n }\n\n /**\n * Retrieve a value using dot notation\n * Throws if value is not a boolean\n */\n static boolean (obj: any, path: string, defaultValue?: boolean): boolean {\n const val = data_get(obj, path, defaultValue)\n if (typeof val !== 'boolean') {\n throw new InvalidArgumentException(`Value at \"${path}\" is not a boolean.`)\n }\n return val\n }\n\n /**\n * Flatten an array of arrays by one level.\n *\n * Example:\n * Arr.collapse([[1,2], [3], 4]) -> [1,2,3,4]\n */\n static collapse<X> (array: X[][] | X[]) {\n if (!Array.isArray(array)) return []\n const result: X[] = []\n for (const item of array) {\n if (Array.isArray(item)) {\n result.push(...item)\n } else {\n result.push(item)\n }\n }\n return result\n }\n\n /**\n * Cartesian product of arrays.\n *\n * Example:\n * Arr.crossJoin([1,2], ['a','b']) -> [[1,'a'], [1,'b'], [2,'a'], [2,'b']]\n *\n * Accepts any number of array arguments (or single array-of-arrays).\n */\n static crossJoin<A> (...arrays: A[][]) {\n let inputs: A[] | A[][] = arrays\n if (arrays.length === 1 && Array.isArray(arrays[0]) && arrays[0].some(Array.isArray)) {\n inputs = arrays[0]\n }\n\n // validate\n inputs = inputs.map(a => (Array.isArray(a) ? a : [a]))\n\n // start with an empty product\n let product: A[][] = [[]]\n for (const arr of inputs) {\n const next = []\n for (const prefix of product) {\n for (const value of arr) {\n next.push([...prefix, value])\n }\n }\n product = next\n }\n return product\n }\n\n /**\n * Split an array (or object) into two arrays: [keys, values].\n *\n * For arrays, keys are numeric indices. For objects, keys are property names.\n *\n * Example:\n * Arr.divide(['a','b']) -> [[0,1], ['a','b']]\n * Arr.divide({x:1,y:2}) -> [['x','y'], [1,2]]\n */\n static divide<A> (input: A[] | Record<string, A>) {\n if (Array.isArray(input)) {\n const keys = input.map((_, i) => i)\n const values = input.slice()\n return [keys, values]\n }\n if (Arr._isObject(input)) {\n const keys = Object.keys(input)\n const values = keys.map(k => input[k])\n return [keys, values]\n }\n return [[], []]\n }\n\n /**\n * Flatten a nested array/object structure into a single-level object\n * with dot-notated keys.\n *\n * Example:\n * Arr.dot({ a: { b: 1 }, c: [2,3] }) -> { 'a.b': 1, 'c.0': 2, 'c.1': 3 }\n *\n * Works for arrays and plain objects.\n */\n static dot<A> (input: A[] | Record<string, A>, prefix = ''): Record<string, A> {\n const result: Record<string, A | Record<string, A>> = {}\n\n const recurse = (val: A[] | Record<string, A>, path: string) => {\n if (Array.isArray(val)) {\n for (let i = 0; i < val.length; i++) {\n recurse(<never>val[i], path ? `${path}.${i}` : String(i))\n }\n } else if (Arr._isObject(val)) {\n for (const [k, v] of Object.entries(val)) {\n const next = path ? `${path}.${k}` : k\n recurse(<never>v, next)\n }\n } else {\n result[path] = val\n }\n }\n\n if (Array.isArray(input) || Arr._isObject(input)) {\n recurse(input, prefix)\n }\n return result as Record<string, A>\n }\n\n /**\n * Checks if all elements satisfy the predicate\n */\n static every<T> (array: T[], predicate: (item: T) => boolean): boolean {\n return array.every(predicate)\n }\n\n /**\n * Remove items by keys/indices from an array or properties from an object.\n *\n * For arrays: keys are numeric indices (single number or array of numbers).\n *\n * Returns a shallow-copied result (does not mutate input).\n *\n * Example:\n * Arr.except([10,20,30], [1]) -> [10,30]\n */\n static except<A extends any[] | Record<string, any>, X> (input: A, keys: X[]): A {\n const keySet = new Set(Array.isArray(keys) ? keys : [keys])\n\n if (Array.isArray(input)) {\n return input.filter((_, idx) => !keySet.has(<never>idx)) as never\n }\n if (Arr._isObject(input)) {\n const out: Record<string, A> = {}\n for (const [k, v] of Object.entries(input)) {\n if (!keySet.has(<never>k)) out[k] = v\n }\n return out as never\n }\n return input as never\n }\n\n /**\n * Return the first element of an array that satisfies the predicate,\n * or the first element if no predicate is provided, otherwise the defaultValue.\n *\n * Predicate can be true (boolean), a function or a value to match (strict equality).\n * \n * When predicate is true (boolean), the first element will be removed and a tuple will be returned [el, rest].\n * \n * @param array \n * @param predicate \n * @param defaultValue \n * \n * @returns \n */\n static first<A, P extends (((arg: A) => true) | true)> (\n array: A[],\n predicate?: P | undefined,\n defaultValue?: A | undefined\n ): P extends true ? [A, A[]] : A | undefined {\n if (predicate === true) {\n if (!array.length) throw new Error('Cannot shift from empty array')\n return [array[0], array.slice(1)] as never\n }\n\n if (!Array.isArray(array) || array.length === 0) return defaultValue as never\n if (predicate === undefined) return array[0] as never\n\n if (typeof predicate === 'function') {\n for (const item of array) {\n if (predicate(item)) return item as never\n }\n return defaultValue as never\n }\n\n // value match\n for (const item of array) {\n if (typeof predicate !== 'boolean' && item === <never>predicate) return item\n }\n return defaultValue as never\n }\n\n /**\n * Recursively flatten an array up to `depth` levels (default: Infinity).\n *\n * Example:\n * Arr.flatten([1, [2, [3]]], 1) -> [1,2,[3]]\n */\n static flatten<A> (array: A[], depth = Infinity): A[] {\n if (!Array.isArray(array)) return []\n if (depth < 1) return array.slice()\n\n const result = []\n for (const item of array) {\n if (Array.isArray(item) && depth > 0) {\n result.push(...Arr.flatten(item, depth - 1))\n } else {\n result.push(item)\n }\n }\n return result\n }\n\n /**\n * Retrieve a value from an array/object using dot notation\n * Throws if value is not a float\n */\n static float (obj: any, path: string, defaultValue?: number): number {\n const val = data_get(obj, path, defaultValue)\n if (typeof val !== 'number' || Number.isNaN(val)) {\n throw new InvalidArgumentException(`Value at \"${path}\" is not a float.`)\n }\n return val\n }\n\n /**\n * Remove element(s) by index or dot-notated path from an array/object.\n *\n * For arrays: accepts numeric index or array of indices. Returns a new array.\n *\n * For objects: supports dot notation to remove nested keys.\n *\n * Example:\n * Arr.forget([1,2,3], 1) -> [1,3]\n * Arr.forget({a:{b:1}}, 'a.b') -> { a: {} }\n */\n static forget<A extends any[] | Record<string, any>> (input: A, keys: any): A {\n // arrays\n if (Array.isArray(input)) {\n const removeSet = new Set(Array.isArray(keys) ? keys : [keys])\n return input.filter((_, i) => !removeSet.has(i)) as A\n }\n\n // objects with dot support\n if (Arr._isObject(input)) {\n const out = Arr._clone(input)\n const keyList = Array.isArray(keys) ? keys : [keys]\n\n for (const key of keyList) {\n const parts = String(key).split('.')\n let node = out\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i]\n if (i === parts.length - 1) {\n if (node && Object.prototype.hasOwnProperty.call(node, part)) {\n delete node[<never>part]\n }\n } else {\n if (!Arr._isObject(node[<never>part])) break\n node = node[<never>part]\n }\n }\n }\n return out\n }\n\n return input\n }\n\n /**\n * Converts various input types into a plain array\n * Supports Arrays, Objects, Iterables, Map, WeakMap, and custom toArray/toJSON/jsonSerialize methods\n */\n static from<T> (\n value: T | Iterable<T> | Arrayable | Jsonable | JsonSerializable | null | undefined\n ): any[] {\n if (value == null) return []\n\n // Array\n if (Array.isArray(value)) return value\n\n // Iterable (generators, sets, maps)\n if (Symbol.iterator in Object(value)) return [...(value as Iterable<any>)]\n\n // Arrayable\n if ((value as Arrayable).toArray) return (value as Arrayable).toArray()\n\n // Jsonable\n if ((value as Jsonable).toJSON) return (value as Jsonable).toJSON()\n\n // JsonSerializable\n if ((value as JsonSerializable).jsonSerialize) return (value as JsonSerializable).jsonSerialize()\n\n // WeakMap / Map / Object fallback\n if (value instanceof Map) return Array.from(value.entries())\n if (value instanceof WeakMap) return [] // can't enumerate WeakMap keys\n if (typeof value === 'object') return Object.values(value)\n\n // Fallback for primitives\n return [value]\n }\n\n /**\n * Checks if an object has all the specified keys\n */\n static hasAll<T extends object> (obj: T, keys: (keyof T)[]): boolean {\n return keys.every(k => k in obj)\n }\n\n /**\n * For arrays: check if the array contains any of the provided values.\n *\n * values can be single value or array of values.\n *\n * Example:\n * Arr.hasAny([1,2,3], [4,2]) -> true\n */\n static hasAny<A> (array: A[], values: A[] | A) {\n if (!Array.isArray(array)) return false\n const vs = Array.isArray(values) ? values : [values]\n const set = new Set(array)\n for (const v of vs) {\n if (set.has(v)) return true\n }\n return false\n }\n\n /**\n * Retrieve a value using dot notation\n * Throws if value is not an integer\n */\n static integer (obj: any, path: string, defaultValue?: number): number {\n const val = data_get(obj, path, defaultValue)\n if (!Number.isInteger(val)) {\n throw new InvalidArgumentException(`Value at \"${path}\" is not an integer.`)\n }\n return val\n }\n\n /**\n * Determine if the input is a \"list-like\" array: an Array with\n * contiguous numeric indices starting at 0 (no gaps).\n *\n * Example:\n * Arr.isList([1,2,3]) -> true\n * const a = []; a[2] = 5; Arr.isList(a) -> false\n */\n static isList<A> (value: A[]) {\n if (!Array.isArray(value)) return false\n for (let i = 0; i < value.length; i++) {\n if (!(i in value)) return false // holes\n }\n return true\n }\n\n /**\n * Join array elements into a string using the given separator.\n *\n * Example:\n * Arr.join([1,2,3], '-') -> '1-2-3'\n */\n static join (array: any[], separator: string = ','): string {\n return Array.isArray(array) ? array.join(separator) : ''\n }\n\n /**\n * Create an object indexed by a key or callback function.\n *\n * Example:\n * Arr.keyBy([{id:1},{id:2}], 'id') -> { '1': {id:1}, '2': {id:2} }\n */\n static keyBy<T> (\n array: T[],\n key: keyof T | ((item: T) => string | number)\n ): Record<string, T> {\n const result: Record<string, T> = {}\n if (!Array.isArray(array)) return result\n\n for (const item of array) {\n let k: string | number\n if (typeof key === 'function') {\n k = key(item)\n } else {\n k = String(item[key])\n }\n result[k] = item\n }\n return result\n }\n\n /**\n * Get the last element of an array, optionally matching a predicate,\n * or the last element if no predicate is provided, otherwise the defaultValue.\n *\n * Predicate can be a true (boolean), a function or a value to match (strict equality).\n * \n * When predicate is true (boolean), the last element will be removed and a tuple will be returned [el, rest].\n * \n * @param array \n * @param predicate \n * @param defaultValue \n * \n * @returns \n */\n static last<T, P extends ((item: T) => boolean) | true> (\n array: T[],\n predicate?: P | T,\n defaultValue?: T\n ): P extends true ? [T, T[]] : T | undefined {\n\n if (predicate === true) {\n if (!array.length) throw new Error('Cannot pop from empty array')\n const lastItem = array[array.length - 1]\n return [lastItem, array.slice(0, -1)] as never\n }\n\n if (!Array.isArray(array) || array.length === 0) return defaultValue as never\n if (!predicate) return array[array.length - 1] as never\n\n if (typeof predicate === 'function') {\n for (let i = array.length - 1; i >= 0; i--) {\n if ((predicate as (item: T) => boolean)(array[i])) return array[i] as never\n }\n } else {\n for (let i = array.length - 1; i >= 0; i--) {\n if (array[i] === predicate) return array[i] as never\n }\n }\n\n return defaultValue as never\n }\n\n /**\n * Transform each element in an array using a callback.\n */\n static map<T, U> (array: T[], callback: (item: T, index: number) => U): U[] {\n return Array.isArray(array) ? array.map(callback) : []\n }\n\n /**\n * Maps a multi-dimensional array with a spread callback\n */\n static mapSpread<T extends any[], U> (array: T[], callback: (...items: T) => U): U[] {\n return array.map(item => callback(...(Array.isArray(item) ? item : [item]) as any))\n }\n\n /**\n * Map each element to a key-value pair.\n *\n * Example:\n * Arr.mapWithKeys([{id:1, name:'A'}], x => [x.id, x.name])\n * -> { '1': 'A' }\n */\n static mapWithKeys<T, K extends string | number, V> (\n array: T[],\n callback: (item: T, index: number) => [K, V]\n ): Record<string, V> {\n const result: Record<string, V> = {}\n if (!Array.isArray(array)) return result\n\n array.forEach((item, idx) => {\n const [k, v] = callback(item, idx)\n result[String(k)] = v\n })\n return result\n }\n\n /**\n * Return only elements at the given indices.\n *\n * Example:\n * Arr.only([10,20,30], [0,2]) -> [10,30]\n */\n static only<T> (array: T[], keys: number | number[]): T[] {\n if (!Array.isArray(array)) return []\n const keyArray = Array.isArray(keys) ? keys : [keys]\n return array.filter((_, idx) => keyArray.includes(idx))\n }\n\n /**\n * Split an array into two arrays based on a predicate\n */\n static partition<T> (array: T[], predicate: (item: T) => boolean): [T[], T[]] {\n const truthy: T[] = []\n const falsy: T[] = []\n array.forEach(item => (predicate(item) ? truthy : falsy).push(item))\n return [truthy, falsy]\n }\n\n /**\n * Extract a property from each element in an array of objects.\n *\n * Example:\n * Arr.pluck([{name:'A'},{name:'B'}], 'name') -> ['A','B']\n */\n static pluck<T, K extends keyof T> (array: T[], key: K): T[K][] {\n if (!Array.isArray(array)) return []\n return array.map(item => item[key])\n }\n\n /**\n * Add elements to the beginning of an array and return a new array.\n * \n * @param array \n * @param value \n * @returns \n */\n static prepend<T> (array: T[], ...value: T[]): T[] {\n return [...value, ...(Array.isArray(array) ? array : [])]\n }\n\n /**\n * Remove a value from an array by index and return it.\n * Returns a tuple: [newArray, removedValue]\n */\n static pull<T> (array: T[], key: number): [T[], T | undefined] {\n if (!Array.isArray(array) || key < 0 || key >= array.length) return [array, undefined]\n const copy = array.slice()\n const [removed] = copy.splice(key, 1)\n return [copy, removed]\n }\n\n /**\n * Append values to an array (mutable)\n */\n static push<T> (array: T[], ...values: T[]): T[] {\n array.push(...values)\n return array\n }\n\n /**\n * Pick one or more random elements from an array.\n */\n static random<T> (array: T[], count: number = 1): T | T[] | undefined {\n if (!Array.isArray(array) || array.length === 0) return undefined\n const shuffled = Arr.shuffle(array)\n if (count === 1) return shuffled[0]\n return shuffled.slice(0, count)\n }\n\n /**\n * Returns array elements that do NOT satisfy the predicate\n */\n static reject<T> (array: T[], predicate: (item: T) => boolean): T[] {\n return array.filter(item => !predicate(item))\n }\n\n /**\n * Pick keys from an array of objects or an object\n */\n static select<T extends object, K extends keyof T> (obj: T, keys: K[]): Pick<T, K> {\n const result = {} as Pick<T, K>\n keys.forEach(k => {\n if (k in obj) result[k] = obj[k]\n })\n return result\n }\n\n\n /**\n * Returns the only element that passes a callback, throws if none or multiple\n */\n static sole<T> (array: T[], predicate: (item: T) => boolean): T {\n const filtered = array.filter(predicate)\n if (filtered.length === 0) throw new InvalidArgumentException('No element satisfies the condition.')\n if (filtered.length > 1) throw new InvalidArgumentException('Multiple elements satisfy the condition.')\n return filtered[0]\n }\n\n /**\n * Checks if at least one element satisfies the predicate\n */\n static some<T> (array: T[], predicate: (item: T) => boolean): boolean {\n return array.some(predicate)\n }\n\n /**\n * Randomly shuffle an array and return a new array.\n */\n static shuffle<T> (array: T[]): T[] {\n if (!Array.isArray(array)) return []\n const copy = array.slice()\n for (let i = copy.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [copy[i], copy[j]] = [copy[j], copy[i]]\n }\n return copy\n }\n\n\n /**\n * Sort an array ascending using optional comparator.\n */\n static sort<T> (array: T[], comparator?: (a: T, b: T) => number): T[] {\n if (!Array.isArray(array)) return []\n return array.slice().sort(comparator)\n }\n\n /**\n * Sort an array descending using optional comparator.\n */\n static sortDesc<T> (array: T[], comparator?: (a: T, b: T) => number): T[] {\n return Arr.sort(array, comparator ? (a, b) => comparator(b, a) : undefined)\n }\n\n /**\n * Recursively sort arrays inside an array.\n */\n static sortRecursive<T> (array: T[]): T[] {\n if (!Array.isArray(array)) return []\n return array.map(item =>\n Array.isArray(item) ? Arr.sortRecursive(item) : item\n ).sort() as T[]\n }\n\n /**\n * Recursively sort arrays inside an array descending.\n */\n static sortRecursiveDesc<T> (array: T[]): T[] {\n if (!Array.isArray(array)) return []\n return array.map(item =>\n Array.isArray(item) ? Arr.sortRecursiveDesc(item) : item\n ).sort().reverse() as T[]\n }\n\n /**\n * Retrieve a value using dot notation\n * Throws if value is not a string\n */\n static string (obj: any, path: string, defaultValue?: string): string {\n const val = data_get(obj, path, defaultValue)\n if (typeof val !== 'string') {\n throw new InvalidArgumentException(`Value at \"${path}\" is not a string.`)\n }\n return val\n }\n\n /**\n * Return the first N elements of an array.\n * \n * @param array \n * @param count \n * @returns \n */\n static take<T> (array: T[], count: number): T[] {\n if (!Array.isArray(array)) return []\n return array.slice(0, count)\n }\n\n /**\n * Filter an array based on a predicate function or key-value match.\n */\n static where<T> (\n array: T[],\n predicate: ((item: T) => boolean) | Partial<T>\n ): T[] {\n if (!Array.isArray(array)) return []\n if (typeof predicate === 'function') {\n return array.filter(predicate)\n }\n return array.filter(item =>\n Object.entries(predicate).every(([k, v]) => (item as any)[k] === v)\n )\n }\n\n /**\n * Filter an array of objects, keeping elements where the given key is not null/undefined.\n */\n static whereNotNull<T> (\n array: T[],\n key: keyof T\n ): T[] {\n if (!Array.isArray(array)) return []\n return array.filter(item => (item[key] !== null && item[key] !== undefined))\n }\n\n /**\n * If the given value is not an array and not null, wrap it in one.\n * \n * Non-array values become [value]; null/undefined becomes [].\n * \n * @param value \n * @returns \n */\n static wrap<T> (value: T | T[] | null | undefined): T[] {\n if (value === null || value === undefined) return []\n return Array.isArray(value) ? value : [value]\n }\n\n /**\n * Return the first element of an array, undefined if empty.\n */\n static head<T> (array: T[]): T | undefined {\n return Array.isArray(array) && array.length ? array[0] : undefined\n }\n\n // ============= Additional Non Cannon Arr methods\n\n /**\n * Splits an array into chunks of a specified size.\n *\n * @template T - Type of elements in the array\n * @param arr - The input array\n * @param size - Size of each chunk (default: 2)\n * @returns An array of chunks (arrays)\n */\n static chunk = <T> (arr: T[], size: number = 2): T[][] => {\n if (size <= 0) throw new Error('Chunk size must be greater than 0')\n\n const chunks: T[][] = []\n\n for (let i = 0; i < arr.length; i += size) {\n chunks.push(arr.slice(i, i + size))\n }\n\n return chunks\n }\n\n /**\n * Alternates between two arrays, creating a zipped result.\n * \n * @param a \n * @param b \n * @returns \n */\n static alternate<T> (a: T[], b: T[]): T[] {\n const result: T[] = []\n const max = Math.max(a.length, b.length)\n for (let i = 0; i < max; i++) {\n if (i < a.length) result.push(a[i])\n if (i < b.length) result.push(b[i])\n }\n return result\n }\n\n /**\n * Combine arrays and sum their values element by element.\n * \n * @param arr \n * @returns \n */\n static combine (...arr: number[][]): number[] {\n const maxLength = Math.max(...arr.map(a => a.length))\n const result: number[] = new Array(maxLength).fill(0)\n for (let i = 0; i < maxLength; i++) {\n for (const array of arr) result[i] += (array[i] || 0)\n }\n return result\n }\n\n /** \n * Find the value associated with a given key. \n * \n * @param key \n * @param arr \n * @returns \n */\n static find<T> (key: T, arr: T[]): T | null {\n return arr.find(item => item === key) || null\n }\n\n /**\n * Check if array is empty.\n * \n * @param arr \n * @returns \n */\n static isEmpty<T> (arr: T[]): boolean {\n if (arr.length === 0) return true\n else return false\n }\n\n /**\n * Check if array is empty. \n * \n * @param arr \n * @returns \n */\n static isNotEmpty<T> (arr: T[]): boolean {\n return arr.length > 0\n }\n\n /**\n * Pop the element off the end of array.\n * \n * @param arr \n * @returns \n */\n static pop<T> (arr: T[]): T[] {\n return arr.slice(0, -1)\n }\n\n /**\n * Create a new array in reverse order. \n * \n * @param arr \n * @returns \n */\n static reverse<T> (arr: T[]): T[] {\n return [...arr].reverse()\n }\n\n /**\n * Return the first element of an array that satisfies the predicate,\n * or the first element if no predicate is provided, otherwise the defaultValue.\n *\n * Predicate can be true (boolean), a function or a value to match (strict equality).\n * \n * When predicate is true (boolean), the first element will be removed and a tuple will be returned [el, rest].\n * \n * @param array \n * @param predicate \n * @param defaultValue \n * \n * @alias Arr.first()\n * @returns \n */\n static shift<A, P extends (((arg: A) => true) | true)> (\n array: A[],\n predicate?: P | undefined,\n defaultValue?: A | undefined\n ): P extends true ? [A, A[]] : A | undefined {\n return Arr.first(array, predicate, defaultValue)\n }\n\n /**\n * Generates an array of sequential numbers.\n *\n * @param size - Number of elements in the range\n * @param startAt - Starting number (default: 0)\n * @returns An array of numbers from startAt to startAt + size - 1\n */\n static range (size: number, startAt: number = 0): number[] {\n if (size <= 0 || !Number.isFinite(size)) return []\n return Array.from({ length: size }, (_, i) => startAt + i)\n }\n}\n","import dayjs, { ConfigType, Dayjs, OpUnitType } from 'dayjs'\n\nimport advancedFormat from 'dayjs/plugin/advancedFormat.js'\nimport customParseFormat from 'dayjs/plugin/customParseFormat.js'\nimport dayOfYear from 'dayjs/plugin/dayOfYear.js'\nimport isBetween from 'dayjs/plugin/isBetween.js'\nimport isLeapYear from 'dayjs/plugin/isLeapYear.js'\nimport relativeTime from 'dayjs/plugin/relativeTime.js'\nimport timezone from 'dayjs/plugin/timezone.js'\nimport utc from 'dayjs/plugin/utc.js'\n\ndayjs.extend(utc)\ndayjs.extend(timezone)\ndayjs.extend(dayOfYear)\ndayjs.extend(isBetween)\ndayjs.extend(isLeapYear)\ndayjs.extend(relativeTime)\ndayjs.extend(advancedFormat)\ndayjs.extend(customParseFormat)\n\nconst phpToDayjsTokens = (format: string): string => format\n .replace(/Y/g, 'YYYY')\n .replace(/m/g, 'MM')\n .replace(/d/g, 'DD')\n .replace(/H/g, 'HH')\n .replace(/i/g, 'mm')\n .replace(/s/g, 'ss')\n\nexport function format (date: ConfigType, fmt: string) {\n return dayjs(date).format(phpToDayjsTokens(fmt))\n}\n\n// export interface Time extends Dayjs { }\nconst TimeClass = class { } as { new(date?: dayjs.ConfigType): Dayjs } & typeof Dayjs\n\nexport class DateTime extends TimeClass {\n private instance: Dayjs\n\n constructor(config?: ConfigType) {\n super(config)\n\n this.instance = dayjs(config)\n return new Proxy(this, {\n get: (target, prop, receiver) => {\n if (prop in target) return Reflect.get(target, prop, receiver)\n\n const value = Reflect.get(this.instance, prop, receiver)\n if (typeof value === 'function') {\n return (...args: any[]) => {\n const result = value.apply(this.instance, args)\n // If result is Dayjs, wrap in Time\n return dayjs.isDayjs(result) ? new DateTime(result) : result\n }\n }\n return value\n }\n })\n }\n\n /**\n * Start time of a specific unit.\n * \n * @returns \n */\n start (unit: OpUnitType = 'days') {\n return this.startOf(unit)\n }\n\n /**\n * End time of a specific unit.\n * \n * @returns \n */\n end (unit: OpUnitType = 'days') {\n return this.endOf(unit)\n }\n\n /**\n * Get the first day of the month of the given date\n * \n * @returns \n */\n firstDayOfMonth (): DateTime {\n return new DateTime(new Date(Date.UTC(this.year(), this.month(), 1)))\n }\n\n carbonFormat (template?: string | undefined) {\n return template ? this.format(phpToDayjsTokens(template)) : this.format()\n }\n\n /**\n * Get the last day of the month of the given date\n * \n * @returns \n */\n lastDayOfMonth (): DateTime {\n return new DateTime(new Date(Date.UTC(this.year(), this.month() + 1, 0)))\n }\n\n /**\n * Get a random time between the specified hour and minute.\n * \n * @param startHour \n * @param startMinute \n * @param endHour \n * @param endMinute \n * @returns \n */\n randomTime (\n startHour: number = 9,\n startMinute: number = 0,\n endHour: number = 17,\n endMinute: number = 0\n ): DateTime {\n const today = new Date()\n const startMinutes = startHour * 60 + startMinute\n const endMinutes = endHour * 60 + endMinute\n const randomMinutes = Math.floor(Math.random() * (endMinutes - startMinutes)) + startMinutes\n const hour = Math.floor(randomMinutes / 60)\n const minute = randomMinutes % 60\n const date = new Date(today)\n date.setHours(hour, minute, 0, 0)\n return new DateTime(date)\n }\n\n /**\n * Create a date for a given timestamp.\n *\n * @param timestamp - Unix timestamp\n * \n * @return {Date} object\n */\n static fromTimestamp (timestamp: number): Date {\n return new Date(timestamp * 1000)\n }\n\n /**\n * Get current time instance.\n *\n * @returns Current time\n */\n static now (): DateTime {\n return new DateTime()\n }\n\n /**\n * Parse the time\n * \n * @param date \n * @returns \n */\n static parse (date: dayjs.ConfigType): DateTime {\n return new DateTime(date)\n }\n\n /**\n * Get the formatted date according to the string of tokens passed in.\n * \n * To escape characters, wrap them in square brackets (e.g. [MM]).\n *\n * @param time - current time\n * @param template - time format\n */\n static format (time?: ConfigType, template?: string | undefined): string {\n return new DateTime(time).format(template)\n }\n\n\n /**\n * Get the difference in days from today.\n *\n * @param time \n * @param startHour \n * @param startMinute \n * @param endHour \n * @param endMinute \n * @returns \n */\n static randomTime (\n time?: ConfigType,\n startHour?: number,\n startMinute?: number,\n endHour?: number,\n endMinute?: number\n ): DateTime {\n return new DateTime(time).randomTime(startHour, startMinute, endHour, endMinute)\n }\n\n /**\n * Get the first day of the month of the given date\n * \n * @param time \n * \n * @returns \n */\n static firstDayOfMonth (time: ConfigType): DateTime {\n return new DateTime(time).firstDayOfMonth()\n }\n\n /**\n * Get the last day of the month of the given date\n * \n * @param time \n * \n * @returns \n */\n static lastDayOfMonth (time: ConfigType): DateTime {\n return new DateTime(time).lastDayOfMonth()\n }\n}\n","import type { Callback, ExcerptOptions, Fallback, Function, HtmlStringType, Value } from '../Contracts/StrContract'\n\nimport { dot } from './Obj'\n\nexport enum Mode {\n MB_CASE_UPPER = 0,\n MB_CASE_LOWER = 1,\n MB_CASE_TITLE = 2,\n MB_CASE_FOLD = 3,\n MB_CASE_UPPER_SIMPLE = 4,\n MB_CASE_LOWER_SIMPLE = 5,\n MB_CASE_TITLE_SIMPLE = 6,\n MB_CASE_FOLD_SIMPLE = 7\n}\n\nexport class Str {\n /**\n * The callback that should be used to generate UUIDs.\n *\n * @type { Function | null }\n */\n protected static uuidFactory: Function | null = null\n\n /**\n * The callback that should be used to generate ULIDs.\n *\n * @type { Function | null }\n */\n protected static ulidFactory: Function | null = null\n\n /**\n * The callback that should be used to generate random strings.\n *\n * @type { Function | null }\n */\n protected static randomStringFactory: Function | null = null\n\n /**\n * Get a new Stringable object from the given string.\n *\n * @param { string } string\n */\n static of (string: string): Stringable {\n return new Stringable(string)\n }\n\n /**\n * Return the remainder of a string after the first occurrence of a given value.\n *\n * @param { string } subject\n * @param { string } search\n *\n * @return { string }\n */\n static after (subject: string, search: string): string {\n if (search === '') {\n return subject\n }\n\n return subject.slice(subject.indexOf(search) + search.length)\n }\n\n /**\n * Return the remainder of a string after the last occurrence of a given value.\n *\n * @param { string } subject\n * @param { string } search\n *\n * @return { string }\n */\n static afterLast (subject: string, search: string): string {\n if (search === '') {\n return subject\n }\n\n const position: number = subject.lastIndexOf(search)\n\n if (position === -1) {\n return subject\n }\n\n return subject.substring(position + search.length)\n }\n\n /**\n * Transliterate a UTF-8 value to ASCII.\n *\n * @param { string } value\n *\n * @return { string }\n */\n static ascii (value: string): string {\n return value.normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^a-zA-Z0-9]/g, '')\n }\n\n /**\n * Get the portion of a string before the first occurrence of a given value.\n *\n * @param { string } subject\n * @param { string } search\n *\n * @return { string }\n */\n static before (subject: string, search: string): string {\n if (search === '') {\n return subject\n }\n\n const result: string = subject.substring(0, subject.indexOf(search))\n\n if (result === '') {\n return subject\n }\n\n return result\n }\n\n /**\n * Get the portion of a string before the last occurrence of a given value.\n *\n * @param { string } subject\n * @param { string } search\n *\n * @return { string }\n */\n static beforeLast (subject: string, search: string): string {\n if (search === '') {\n return subject\n }\n\n const position: number | null = subject.lastIndexOf(search) ?? null\n\n if (position === -1) {\n return subject\n }\n\n return this.substr(subject, 0, position)\n }\n\n /**\n * Get the portion of a string between two given values.\n *\n * @param { string } subject\n * @param { string } from\n * @param { string } to\n *\n * @return { string }\n */\n static between (subject: string, from: string, to: string): string {\n if (from === '' || to === '') {\n return subject\n }\n\n return this.beforeLast(this.after(subject, from), to)\n }\n\n /**\n * Get the smallest possible portion of a string between two given values.\n *\n * @param { string } subject\n * @param { string } from\n * @param { string } to\n *\n * @return { string }\n */\n static betweenFirst (subject: string, from: string, to: string): string {\n if (from === '' || to === '') {\n return subject\n }\n\n return this.before(this.after(subject, from), to)\n }\n\n /**\n * Convert a value to camel case.\n *\n * @param { string } value\n *\n * @return { string }\n */\n static camel (value: string): string {\n return this.lcfirst(this.studly(value))\n }\n\n /**\n * Get the character at the specified index.\n *\n * @param { string } subject\n * @param { number } index\n *\n * @return { string | false }\n */\n static charAt (subject: string, index: number): string | false {\n return subject.charAt(index)\n }\n\n /**\n * Remove the given string(s) if it exists at the start of the haystack.\n *\n * @param { string } subject\n * @param { string | string[] } needle\n *\n * @return string\n */\n static chopStart (subject: string, needle: string | string[]): string {\n let results: string = subject\n\n needle = Array.isArray(needle) ? needle : [needle]\n\n needle.forEach((word: string): void => {\n if (subject.startsWith(word)) {\n results = subject.substring(word.length)\n }\n })\n\n return results\n }\n\n /**\n * Remove the given string(s) if it exists at the end of the haystack.\n *\n * @param { string } subject\n * @param { string | string[] } needle\n *\n * @return string\n *\n */\n static chopEnd (subject: string, needle: string | string[]): string {\n let results: string = subject\n\n needle = Array.isArray(needle) ? needle : [needle]\n\n needle.forEach((word: string): void => {\n if (subject.endsWith(word)) {\n results = subject.substring(0, subject.length - word.length)\n }\n })\n\n return results\n }\n\n /**\n * Determine if a given string contains a given substring.\n *\n * @param { string } haystack\n * @param { string | string[] } needles\n * @param { boolean } ignoreCase\n *\n * @return { boolean }\n */\n static contains (haystack: string, needles: string | string[], ignoreCase: boolean = false): boolean {\n let result: boolean = false\n\n if (ignoreCase) {\n haystack = haystack.toLowerCase()\n }\n\n needles = Array.isArray(needles) ? needles : [needles]\n\n needles.forEach((needle: string): void => {\n if (ignoreCase) {\n needle = needle.toLowerCase()\n }\n\n if (needle !== '' && haystack.includes(needle)) {\n result = true\n }\n })\n\n return result\n }\n\n /**\n * Determine if a given string contains all array values.\n *\n * @param { string } haystack\n * @param { string[] } needles\n * @param { boolean } ignoreCase\n *\n * @return { boolean }\n */\n static containsAll (haystack: string, needles: string[], ignoreCase: boolean = false): boolean {\n let result: boolean = true\n\n needles.forEach((needle: string): void => {\n if (!this.contains(haystack, needle, ignoreCase)) {\n result = false\n }\n })\n\n return result\n }\n\n /**\n * Determine if a given string doesn't contain a given substring.\n *\n * @param { string } haystack\n * @param { string | string[] } needles\n * @param { boolean } ignoreCase\n *\n * @return { boolean }\n */\n static doesntContain (haystack: string, needles: string | string[], ignoreCase: boolean = false): boolean {\n return !this.contains(haystack, needles, ignoreCase)\n }\n\n /**\n * Convert the case of a string.\n *\n * @param { string } string\n * @param { Mode | number } mode\n *\n * @return { string }\n */\n static convertCase (string: string, mode: Mode | number = Mode.MB_CASE_FOLD): string {\n switch (mode) {\n case Mode.MB_CASE_UPPER: {\n string = string.toLocaleUpperCase()\n\n break\n }\n case Mode.MB_CASE_LOWER: {\n string = string.toLocaleLowerCase()\n\n break\n }\n case Mode.MB_CASE_TITLE: {\n string = this.title(string)\n\n break\n }\n case Mode.MB_CASE_FOLD: {\n string = string.toLocaleLowerCase()\n\n break\n }\n case Mode.MB_CASE_UPPER_SIMPLE: {\n string = string.toUpperCase()\n\n break\n }\n case Mode.MB_CASE_LOWER_SIMPLE: {\n string = string.toLowerCase()\n\n break\n }\n case Mode.MB_CASE_TITLE_SIMPLE: {\n string = this.title(string)\n\n break\n }\n case Mode.MB_CASE_FOLD_SIMPLE: {\n string = string.toLowerCase()\n\n break\n }\n }\n\n return string\n }\n\n /**\n * Replace consecutive instances of a given character with a single character in the given string.\n *\n * @param { string } string\n * @param { string | string[] } characters\n *\n * @return { string }\n */\n static deduplicate (string: string, characters: string | string[] = ' '): string {\n if (Array.isArray(characters)) {\n return characters.reduce((carry: string, character: string): string => carry.replace(new RegExp(`${character.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}+`, 'gu'), character), string)\n }\n\n return string.replace(new RegExp(`${preg_quote(characters)}+`, 'gu'), characters)\n }\n\n /**\n * Determine if a given string ends with a given substring.\n *\n * @param { string } haystack\n * @param { string | string[] } needles\n *\n * @return { boolean }\n */\n static endsWith (haystack: string, needles: string | string[]): boolean {\n needles = Array.isArray(needles) ? needles : [needles]\n\n return needles.some((needle: string): boolean => needle !== '' && haystack.endsWith(needle))\n }\n\n /**\n * Determine if a given string doesn't end with a given substring.\n *\n * @param { string } haystack\n * @param { string | string[] } needles\n *\n * @return { boolean }\n */\n static doesntEndWith (haystack: string, needles: string | string[]): boolean {\n return !this.endsWith(haystack, needles)\n }\n\n /**\n * Returns all the characters except the last.\n * \n * @param string \n * @returns \n */\n static chop (string: string): string {\n return string.slice(0, -1)\n }\n\n /**\n * Escape string for JSON encoding (returns string without quotes). \n * \n * @param string \n * @returns \n */\n static esc (string: string): string {\n return JSON.stringify(string).slice(1, -1)\n }\n\n /**\n * Extracts an excerpt from text that matches the first instance of a phrase.\n *\n * @param { string } text\n * @param { string } phrase\n * @param { ExcerptOptions } options\n *\n * @return { string | null }\n */\n static excerpt (text: string, phrase: string = '', options: ExcerptOptions = {}): string | null {\n const radius: number = options.radius ?? 100\n const omission: string = options.omission ?? '...'\n const results: string[] = text.split(phrase)\n\n if (results.length === 1) {\n return null\n }\n\n const matches: string[] = [text, (results[0] as string), phrase, results.splice(1).join(phrase)]\n\n let start: string = (matches[1] as string).trimStart()\n let end: string = (matches[3] as string).trimEnd()\n\n start = this.of(this.substr(start, Math.max((start.length - radius), 0), radius))\n .ltrim()\n .unless(\n (startWithRadius: Stringable): boolean => startWithRadius.exactly(start),\n (startWithRadius: Stringable): Stringable => startWithRadius.prepend(omission))\n .toString()\n\n end = this.of(this.substr(end, 0, radius))\n .rtrim()\n .unless(\n (endWithRadius: Stringable): boolean => endWithRadius.exactly(end),\n (endWithRadius: Stringable): Stringable => endWithRadius.append(omission))\n .toString()\n\n return (start + ' ' + matches[2] + end).replace(/\\s+/g, ' ').trim()\n }\n\n /**\n * Explode the string into an array.\n *\n * @param { string } string\n * @param { string } delimiter\n * @param { number } limit\n *\n * @return { string[] }\n */\n static explode (string: string, delimiter: string, limit: number = 0): string[] {\n let wordsArray: string[] = string.split(delimiter)\n\n const position: number = limit - 1 >= wordsArray.length\n ? wordsArray.length - 1\n : limit - 1\n\n wordsArray = [...wordsArray.slice(0, position), wordsArray.splice(position).join(' ')]\n\n return wordsArray\n }\n\n /**\n * Cap a string with a single instance of a given value.\n *\n * @param { string } value\n * @param { string } cap\n *\n * @return { string }\n */\n static finish (value: string, cap: string): string {\n return value.endsWith(cap) ? value : value + cap\n }\n\n /**\n * Wrap the string with the given strings.\n *\n * @param { string } value\n * @param { string } before\n * @param { string | null } after\n *\n * @return string\n */\n static wrap (value: string, before: string, after: string | null = null): string {\n return before + value + (after ?? before)\n }\n\n /**\n * Unwrap the string with the given strings.\n *\n * @param { string } value\n * @param { string } before\n * @param { string | null } after\n *\n * @return { string }\n */\n static unwrap (value: string, before: string, after: string | null = null): string {\n if (this.startsWith(value, before)) {\n value = this.replaceFirst(before, '', value)\n }\n\n if (this.endsWith(value, after ?? before)) {\n value = this.replaceLast(after ?? before, '', value)\n }\n\n return value\n }\n\n /**\n * Determine if a given string matches a given pattern.\n *\n * @param { string | string[] } pattern\n * @param { string } value\n * @param { boolean } ignoreCase\n *\n * @return { boolean }\n */\n static is (pattern: string | string[], value: string, ignoreCase: boolean = false): boolean {\n const patterns: string[] = Array.isArray(pattern) ? pattern : [pattern]\n\n for (let pattern of patterns) {\n if (pattern === value) {\n return true\n }\n\n if (ignoreCase && pattern.toLowerCase() === value.toLowerCase()) {\n return true\n }\n\n pattern = pattern.replace(/[-/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&').replace(/\\\\\\*/g, '.*')\n\n const regex: RegExp = new RegExp('^' + pattern + '$', ignoreCase ? 'iu' : 'u')\n\n if (regex.test(value)) {\n return true\n }\n }\n\n return false\n }\n\n /**\n * Determine if a given string is 7-bit ASCII.\n *\n * @param { string } value\n *\n * @return { boolean }\n */\n static isAscii (value: string): boolean {\n return !/[^ -~\\t\\r\\n]/.test(value)\n }\n\n /**\n * Determine if a given string is valid JSON.\n *\n * @param { string } value\n *\n * @return { boolean }\n */\n static isJson (value: string): boolean {\n try {\n JSON.parse(value)\n } catch {\n return false\n }\n\n return true\n }\n\n /**\n * Determine if a given value is a valid URL.\n *\n * @param { string } value\n * @param { string[] } protocols\n *\n * @return { boolean }\n */\n static isUrl (value: string, protocols: string[] = []): boolean {\n const protocolPattern: string = protocols.length === 0 ? 'https?|ftp|file|mailto|tel|data|irc|magnet' : protocols.join('|')\n\n const pattern: RegExp = new RegExp(`^(?:${protocolPattern}):\\\\/\\\\/(?:[\\\\w-]+(?:\\\\.[\\\\w-]+)+|localhost|\\\\d{1,3}(?:\\\\.\\\\d{1,3}){3})(?::\\\\d+)?(?:\\\\S*)?$`, 'i')\n\n return pattern.test(value)\n }\n\n /**\n * Determine if a given string is a valid UUID.\n *\n * @param { string } value\n *\n * @return { boolean }\n */\n static isUuid (value: string): boolean {\n return new RegExp(/^[\\da-f]{8}-[\\da-f]{4}-[\\da-f]{4}-[\\da-f]{4}-[\\da-f]{12}$/).test(value)\n }\n\n /**\n * Determine if a given string is a valid ULID.\n *\n * @param { string } value\n *\n * @return { boolean }\n */\n static isUlid (value: string): boolean {\n if (value.length !== 26) {\n return false\n }\n\n if (value.length !== value.match(/[0123456789ABCDEFGHJKMNPQRSTVWXYZabcdefghjkmnpqrstvwxyz]/g)?.length) {\n return false\n }\n\n return Number(value.charAt(0)) <= 7\n }\n\n /**\n * Convert a string to kebab case.\n *\n * @param { string } value\n *\n * @return { string }\n */\n static kebab (value: string): string {\n return this.snake(value, '-')\n }\n\n /**\n * Return the length of the given string.\n *\n * @param { string } value\n *\n * @return { number }\n */\n static length (value: string): number {\n return value.length\n }\n\n /**\n * Limit the number of characters in a string.\n *\n * @param { string } value\n * @param { number } limit\n * @param { string } end\n * @param { boolean } preserveWords\n *\n * @return { string }\n */\n static limit (\n value: string,\n limit: number = 100,\n end: string = '...',\n preserveWords: boolean = false\n ): string {\n value = value.replace(/<[^>]+>/g, '')\n\n if (value.length <= limit) {\n return value\n }\n\n if (!preserveWords) {\n return this.substr(value, 0, limit).trim() + end\n }\n\n value = value.replace(/[\\n\\r]+/, ' ')\n\n const trimmed: string = this.substr(value, 0, limit).trim()\n\n if (this.substr(value, limit, 1) === ' ') {\n return `${trimmed}${end}`\n }\n\n return `${trimmed.replace(/(.*)\\s.*/, '$1')}${end}`\n }\n\n /**\n * Limit the number of characters in a string.\n *\n * @param { string } value\n * @param { number } limit\n * @param { string } end\n * @param { boolean } preserveWords\n *\n * @alias limit\n * @return { string }\n */\n static truncate (\n value: string, limit: number = 100, end: string = '...', preserveWords: boolean = false\n ): string {\n return this.limit(value, limit, end, preserveWords)\n }\n\n /**\n * Convert the given string to lower-case.\n *\n * @param { string } value\n *\n * @return { string }\n */\n static lower (value: string): string {\n return value.toLowerCase()\n }\n\n /**\n * Get substring by start/stop indexes.\n * \n * @param string \n * @param start \n * @param stop \n * @returns \n */\n static sub (string: string, start: number, stop: number): string {\n return string.substring(start, stop)\n }\n\n /**\n * Limit the number of words in a string.\n *\n * @param { string } value\n * @param { number } words\n * @param { string } end\n *\n * @return { string }\n */\n static words (value: string, words: number = 100, end: string = '...'): string {\n const wordsArray: string[] = value.match(/\\S+\\s*/g)?.splice(0, words) ?? []\n\n const result: string = wordsArray.join('')\n\n if (wordsArray.length === 1 || this.length(value) === this.length(result)) {\n return value\n }\n\n return result.trim() + end\n }\n\n /**\n * Masks a portion of a string with a repeated character.\n *\n * @param { string } string\n * @param { string } character\n * @param { number } index\n * @param { number | null } length\n *\n * @return { string }\n */\n static mask (string: string, character: string, index: number, length: number | null = null): string {\n if (character === '') {\n return string\n }\n\n let start: number | string = index\n let endIndex: number = length ?? string.length\n\n if (start < 0) {\n start = string.length + start\n endIndex = start + (length ?? 0)\n }\n\n if (endIndex === 0) {\n endIndex = start\n }\n\n const segment: string = string.substring(start, endIndex)\n\n if (segment === '') {\n return string\n }\n\n const strLen: number = string.length\n let startIndex: number = index\n\n if (index < 0) {\n startIndex = index < -strLen ? 0 : strLen + index\n }\n\n start = string.substring(0, startIndex)\n\n const segmentLen: number = segment.length\n const end: string = string.substring(startIndex + segmentLen)\n\n return start + character.substring(0, 1).repeat(segmentLen) + end\n }\n\n /**\n * Get the string matching the given pattern.\n *\n * @param { string } pattern\n * @param { string } subject\n *\n * @return { string }\n */\n static match (pattern: string, subject: string): string {\n const body: string = RegExpString.make(/^\\/(.*)\\/\\w*$/, pattern)\n const flags: string = RegExpString.make(/^\\/.*\\/(\\w*)$/, pattern)\n const expression: RegExp = new RegExp(body, flags)\n\n const matches: RegExpMatchArray | null = RegExp(expression).exec(subject)\n\n if (!matches) {\n return ''\n }\n\n return matches[1] ?? matches[0]\n }\n\n /**\n * Determine if a given string matches a given pattern.\n *\n * @param { string | string[] } pattern\n * @param { string } value\n *\n * @return { boolean }\n */\n static isMatch (pattern: string | string[], value: string): boolean {\n let result: boolean = false\n\n pattern = Array.isArray(pattern) ? pattern : [pattern]\n\n pattern.forEach((item: string): void => {\n if (item === value) {\n result = true\n }\n\n const body: string = (/^\\/(.*)\\/\\w*$/.exec(item) as string[])[1] as string\n const flags: string = (/^\\/.*\\/(\\w*)$/.exec(item) as string[])[1] as string\n const expression: RegExp = new RegExp(body, flags)\n\n if (expression.exec(value)) {\n result = true\n }\n })\n\n return result\n }\n\n /**\n * Get the string matching the given pattern.\n *\n * @param { string } pattern\n * @param { string } subject\n *\n * @return { string[] }\n */\n static matchAll (pattern: string, subject: string): string[] {\n const body: string = RegExpString.make(/^\\/(.*)\\/\\w*$/, pattern)\n const flags: string = RegExpString.make(/^\\/.*\\/(\\w*)$/, pattern)\n\n const expression: RegExp = new RegExp(body, flags + (flags.indexOf('g') !== -1 ? '' : 'g'))\n\n const matches: RegExpMatchArray[] = [...subject.matchAll(new RegExp(expression, 'g'))]\n\n if (matches.length === 0) {\n return []\n }\n\n return matches.map((match: RegExpMatchArray): string => String(match.length === 1 ? match[0] : match[1]))\n }\n\n /**\n * Remove all non-numeric characters from a string.\n *\n * @param { string } value\n *\n * @return { string }\n */\n static numbers (value: string): string {\n return value.replace(/\\D/g, '')\n }\n\n /**\n * Pad both sides of a string with another.\n *\n * @param { string } value\n * @param { number } length\n * @param { string } pad\n *\n * @return { string }\n */\n static padBoth (value: string, length: number, pad: string = ' '): string {\n const short: number = Math.max(0, length - value.length)\n const shortLeft: number = Math.floor(short / 2)\n const shortRight: number = Math.ceil(short / 2)\n\n return pad.repeat(shortLeft).substring(0, shortLeft) + value + pad.repeat(shortRight).substring(0, shortRight)\n }\n\n /**\n * Pad the left side of a string with another.\n *\n * @param { string } value\n * @param { number } length\n * @param { string } pad\n *\n * @return { string }\n */\n static padLeft (value: string, length: number, pad: string = ' '): string {\n const short: number = Math.max(0, length - (value.length ?? 0))\n\n return pad.repeat(short).substring(0, short) + value\n }\n\n /**\n * Pad the right side of a string with another.\n *\n * @param { string } value\n * @param { number } length\n * @param { string } pad\n *\n * @return { string }\n */\n static padRight (value: string, length: number, pad: string = ' '): string {\n const short: number = Math.max(0, length - value.length)\n\n return value + pad.repeat(short).substring(0, short)\n }\n\n /**\n * Get the plural form of an English word.\n *\n * @param { string } value\n * @param { number | array } count\n *\n * @return { string }\n */\n static plural (value: string, count: number | number[] = 2): string {\n if ((count !== undefined && count === 1) || value.trim() === '') {\n return value\n }\n\n // List of rules for plural words.\n const plural: { [key: string]: string } = {\n // Special cases (unchanged plurals)\n '^(.*)menu$': '$1menus',\n '^tights$': 'tights',\n '^shorts$': 'shorts',\n '^glasses$': 'glasses',\n '^pants$': 'pants',\n\n // -us -> -i (second declension nouns)\n '(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|vir)us$': '$1i',\n '(vir)us$': '$1i',\n\n // -um/on -> -a (neuter nouns)\n '([ti])um$': '$1a',\n '(tax)on$': '$1a',\n '(criteri)on$': '$1a',\n\n // -ix/ex -> -ices\n '(matr)ix$': '$1ices',\n '(vert|ind)ex$': '$1ices',\n\n // -o -> -oes\n '(buffal|her|potat|tomat|volcan)o$': '$1oes',\n\n // -ouse -> -ouses\n '(h|bl)ouse$': '$1ouses',\n 'ouse$': 'ouses',\n\n // -y -> -ies\n '([^aeiouy]|qu)y$': '$1ies',\n\n // -f/fe -> -ves\n '([lr])f$': '$1ves',\n '([^fo])fe$': '$1ves',\n '(shea|loa|lea|thie)f$': '$1ves',\n '(li|wi|kni)fe$': '$1ves',\n\n // -is -> -es\n '(analys|ax|cris|test|thes)is$': '$1es',\n\n // -e exceptions\n '(alias|status|bus)$': '$1es',\n '(shoe|slave)$': '$1s',\n '(corpse)$': '$1s',\n '(drive|dive|hive|olive|tive)$': '$1s',\n\n // -x -> -xes\n '([ftw]ax)$': '$1es',\n\n // -ouse -> -ice\n '([m|l])ouse$': '$1ice',\n\n // -e -> -es\n '(x|ch|ss|sh)$': '$1es',\n 'o$': 'oes',\n\n // -ze -> -zes\n '(quiz)$': '$1zes',\n\n // -ox -> -oxen\n '^(ox)$': '$1en',\n\n // -person -> -people\n '(p)erson$': '$1eople',\n\n // Irregular singulars\n '(m)an$': '$1en',\n '(c)hild$': '$1hildren',\n '(f)oot$': '$1eet',\n '(m)ouse$': '$1ice',\n '(t)ooth$': '$1eeth',\n '(g)oose$': '$1eese',\n\n // -news (unchanged)\n '(n)ews$': '$1ews',\n\n // -eau -> -eaus\n 'eau$': 'eaus',\n\n // -sis -> -ses\n '(^analy)sis$': '$1ses',\n '((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)sis$': '$1$2ses',\n\n // -ovie -> -ovies\n '(m)ovie$': '$1ovies',\n\n // -eries -> -eries (unchanged)\n '(s)eries$': '$1eries',\n\n // -us -> -uses\n '([^a])us$': '$1uses',\n 'us$': 'uses',\n\n // -status -> -statuses\n '(s)tatus$': '$1tatuses',\n\n // -campus -> -campuses\n '(c)ampus$': '$1ampuses',\n\n // General case (add -s)\n '$': 's'\n }\n\n // List of words that change irregularly.\n const irregular: { [key: string]: string } = {\n // A\n 'abuse': 'abuses',\n 'alumna': 'alumnae',\n 'alumnus': 'alumni',\n 'analysis': 'analyses',\n 'appendix': 'appendices',\n 'atlas': 'atlases',\n 'avalanche': 'avalanches',\n 'axis': 'axes',\n 'axe': 'axes',\n\n // B\n 'bacillus': 'bacilli',\n 'bacterium': 'bacteria',\n 'basis': 'bases',\n 'beau': 'beaux',\n 'beef': 'beefs',\n 'blouse': 'blouses',\n 'brother': 'brothers',\n 'brownie': 'brownies',\n 'bureau': 'bureaux',\n\n // C\n 'cache': 'caches',\n 'cactus': 'cacti',\n 'cafe': 'cafes',\n 'calf': 'calves',\n 'canvas': 'canvases',\n 'cave': 'caves',\n 'chateau': 'chateaux',\n 'child': 'children',\n 'cookie': 'cookies',\n 'corpus': 'corpuses',\n 'cow': 'cows',\n 'crisis': 'crises',\n 'criterion': 'criteria',\n 'curriculum': 'curricula',\n 'curve': 'curves',\n\n // D\n 'datum': 'data',\n 'deer': 'deer',\n 'demo': 'demos',\n 'diagnosis': 'diagnoses',\n 'domino': 'dominoes',\n\n // E\n 'echo': 'echoes',\n 'elf': 'elves',\n 'ellipsis': 'ellipses',\n 'emphasis': 'emphases',\n 'epoch': 'epochs',\n\n // F\n 'fish': 'fish',\n 'focus': 'foci',\n 'foe': 'foes',\n 'foot': 'feet',\n 'formula': 'formulae',\n 'fungus': 'fungi',\n\n // G\n 'ganglion': 'ganglions',\n 'gas': 'gases',\n 'genie': 'genies',\n 'genus': 'genera',\n 'goose': 'geese',\n 'graffito': 'graffiti',\n 'grave': 'graves',\n\n // H\n 'half': 'halves',\n 'hippopotamus': 'hippopotami',\n 'hoax': 'hoaxes',\n 'hoof': 'hoofs',\n 'human': 'humans',\n\n // I\n 'iris': 'irises',\n\n // K\n 'knife': 'knives',\n\n // L\n 'larva': 'larvae',\n 'leaf': 'leaves',\n 'lens': 'lenses',\n 'life': 'lives',\n 'loaf': 'loaves',\n\n // M\n 'man': 'men',\n 'matrix': 'matrices',\n 'means': 'means',\n 'medium': 'media',\n 'memorandum': 'memoranda',\n 'money': 'monies',\n 'mongoose': 'mongooses',\n 'mouse': 'mice',\n 'motto': 'mottoes',\n 'move': 'moves',\n 'mythos': 'mythoi',\n\n // N\n 'nebula': 'nebulae',\n 'neurosis': 'neuroses',\n 'niche': 'niches',\n 'niveau': 'niveaux',\n 'nucleus': 'nuclei',\n 'numen': 'numina',\n\n // O\n 'oasis': 'oases',\n 'occiput': 'occiputs',\n 'octopus': 'octopuses',\n 'offspring': 'offspring',\n 'opus': 'opuses',\n 'ox': 'oxen',\n\n // P\n 'parenthesis': 'parentheses', 'passerby': 'passersby',\n 'penis': 'penises',\n 'person': 'people',\n 'phenomenon': 'phenomena',\n 'plateau': 'plateaux',\n\n // R\n 'radius': 'radii',\n 'runner-up': 'runners-up',\n\n // S\n 'safe': 'safes',\n 'save': 'saves',\n 'scarf': 'scarves',\n 'self': 'selves',\n 'series': 'series',\n 'sex': 'sexes',\n 'sheep': 'sheep',\n 'shelf': 'shelves',\n 'sieve': 'sieves',\n 'soliloquy': 'soliloquies',\n 'son-in-law': 'sons-in-law',\n 'species': 'species',\n 'stadium': 'stadiums',\n 'stimulus': 'stimuli',\n 'stratum': 'strata',\n 'swine': 'swine',\n 'syllabus': 'syllabi',\n 'synthesis': 'syntheses',\n\n // T\n 'testis': 'testes',\n 'thesis': 'theses',\n 'thief': 'thieves',\n 'tooth': 'teeth',\n 'tornado': 'tornadoes',\n 'trilby': 'trilbys',\n 'turf': 'turfs',\n\n // V\n 'valve': 'valves',\n 'volcano': 'volcanoes',\n\n // W\n 'wave': 'waves',\n 'wife': 'wives',\n 'wolf': 'wolves',\n\n // Z\n 'zombie': 'zombies'\n }\n\n // List of words that do not change.\n const uncountable: string[] = [\n // A\n 'advice',\n 'aircraft',\n 'amoyese',\n 'art',\n 'audio',\n\n // B\n 'baggage',\n 'bison',\n 'borghese',\n 'bream',\n 'breeches',\n 'britches',\n 'buffalo',\n 'butter',\n\n // C\n 'cantus',\n 'carp',\n 'cattle',\n 'chassis',\n 'clippers',\n 'clothing',\n 'coal',\n 'cod',\n 'coitus',\n 'compensation',\n 'congoese',\n 'contretemps',\n 'coreopsis',\n 'corps',\n 'cotton',\n\n // D\n 'data',\n 'debris',\n 'deer',\n 'diabetes',\n 'djinn',\n\n // E\n 'education',\n 'eland',\n 'elk',\n 'emoji',\n 'equipment',\n 'evidence',\n\n // F\n 'faroese',\n 'feedback',\n 'fish',\n 'flounder',\n 'flour',\n 'foochowese',\n 'food',\n 'furniture',\n\n // G\n 'gallows',\n 'genevese',\n 'genoese',\n 'gilbertese',\n 'gold',\n\n // H\n 'headquarters',\n 'herpes',\n 'hijinks',\n 'homework',\n 'hovercraft',\n 'hottentotese',\n\n // I\n 'impatience',\n 'information',\n 'innings',\n\n // J\n 'jackanapes',\n 'jeans',\n 'jedi',\n\n // K\n 'kin',\n 'kiplingese',\n 'knowledge',\n 'kongoese',\n\n // L\n 'leather',\n 'love',\n 'lucchese',\n 'luggage',\n\n // M\n 'mackerel',\n 'Maltese',\n 'management',\n 'metadata',\n 'mews',\n 'money',\n 'moose',\n 'mumps',\n 'music',\n\n // N\n 'nankingese',\n 'news',\n 'nexus',\n 'niasese',\n 'nutrition',\n\n // O\n 'oil',\n 'offspring',\n\n // P\n 'patience',\n 'pekingese',\n 'piedmontese',\n 'pike',\n 'pincers',\n 'pistoiese',\n 'plankton',\n 'pliers',\n 'pokemon',\n 'police',\n 'polish',\n 'portuguese',\n 'proceedings',\n 'progress',\n\n // Q\n // (none yet)\n\n // R\n 'rabies',\n 'rain',\n 'research',\n 'rhinoceros',\n 'rice',\n\n // S\n 'salmon',\n 'sand',\n 'sarawakese',\n 'scissors',\n 'sea[- ]bass',\n 'series',\n 'shavese',\n 'shears',\n 'sheep',\n 'shrimp',\n 'siemens',\n 'silk',\n 'sms',\n 'soap',\n 'social media',\n 'spacecraft',\n 'spam',\n 'species',\n 'staff',\n 'sugar',\n 'swine',\n\n // T\n 'talent',\n 'toothpaste',\n 'traffic',\n 'travel',\n 'trousers',\n 'trout',\n 'tuna',\n\n // U\n 'us',\n\n // V\n 'vermontese',\n 'vinegar',\n\n // W\n 'weather',\n 'wenchowese',\n 'wheat',\n 'whiting',\n 'wildebeest',\n 'wood',\n 'wool',\n\n // Y\n 'yengeese',\n 'you'\n ]\n\n if (uncountable.indexOf(value.toLowerCase()) >= 0) {\n return matchCase(value, value)\n }\n\n for (const word in irregular) {\n const pattern: RegExp = new RegExp(`${word}$`, 'i')\n\n if (pattern.test(value)) {\n return matchCase(value.replace(pattern, (irregular[word] as string)), value)\n }\n }\n\n for (const word in plural) {\n const pattern: RegExp = new RegExp(word, 'i')\n\n if (pattern.test(value)) {\n return matchCase(value.replace(pattern, (plural[word] as string)), value)\n }\n }\n\n return matchCase(value, value)\n }\n\n /**\n * Get the plural form of an English word.\n *\n * @param { string } value\n * @param { number | array } count\n * \n * @alias plural\n *\n * @return { string }\n */\n static pluralize = (value: string, count: number | number[] = 2): string => {\n return this.plural(value, count)\n }\n\n /**\n * Pluralize the last word of an English, studly caps case string.\n *\n * @param { string } value\n * @param { number | array } count\n *\n * @return { string }\n */\n static pluralStudly (value: string, count: number | number[] = 2): string {\n const parts: string[] = value.split(/(.)(?=[A-Z])/)\n\n const lastWord: string = (parts.pop() as string)\n\n return parts.join('') + this.ucfirst(this.plural(lastWord, count))\n }\n\n /**\n * Pluralize the last word of an English, Pascal case string.\n *\n * @param { string } value\n * @param { number | array } count\n *\n * @return { string }\n */\n static pluralPascal (value: string, count: number | number[] = 2): string {\n return this.pluralStudly(value, count)\n }\n\n /**\n * Generate a random, secure password.\n *\n * @param { number } length\n * @param { boolean } letters\n * @param { boolean } numbers\n * @param { boolean } symbols\n * @param { boolean } spaces\n *\n * @return { string }\n */\n static password (length: number = 32, letters: boolean = true, numbers: boolean = true, symbols: boolean = true, spaces: boolean = false): string {\n const password: string[] = []\n let collection: string[] = []\n\n while (password.length < length) {\n if (letters) {\n collection = collection.concat([\n 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',\n 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',\n 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G',\n 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',\n 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',\n ])\n }\n\n if (numbers) {\n collection = collection.concat([\n '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',\n ])\n }\n\n if (symbols) {\n collection = collection.concat([\n '~', '!', '#', '$', '%', '^', '&', '*', '(', ')', '-',\n '_', '.', ',', '<', '>', '?', '/', '\\\\', '{', '}', '[',\n ']', '|', ':', ';',\n ])\n }\n\n if (spaces) {\n collection = collection.concat([' '])\n }\n\n password.push((collection[Math.floor(Math.random() * collection.length)] as string))\n }\n\n return password.join('')\n }\n\n /**\n * Find the position of the first occurrence of a given substring in a string.\n *\n * @param { string } haystack\n * @param { string } needle\n * @param { number } offset\n *\n * @return { number | false }\n */\n static position (haystack: string, needle: string, offset: number = 0): number | false {\n const position: number = haystack.indexOf(needle, Math.max(offset, 0))\n\n return position !== -1 ? position : false\n }\n\n /**\n * Generate a more truly \"random\" alpha-numeric string.\n *\n * @param { number } length\n *\n * @return { string }\n */\n static random (length: number = 16): string {\n if (this.randomStringFactory !== null) {\n return this.randomStringFactory(length)\n }\n\n const byteSize: number = Math.ceil((length) / 3) * 3\n\n const bytes: string = crypto.getRandomValues(new Uint8Array(byteSize)).join('')\n\n let string: string = btoa(bytes);\n\n ['/', '+', '='].forEach((character: string): string => string = string.replace(character, ''))\n\n return string.substring(0, length)\n }\n\n /**\n * Set the callable that will be used to generate random strings.\n *\n * @param { ((length: number) => string) | null } factory\n *\n * @return { void }\n */\n static createRandomStringsUsing (factory: ((length: number) => string) | null = null): void {\n this.randomStringFactory = factory\n }\n\n /**\n * Set the sequence that will be used to generate random strings.\n *\n * @param { (string | undefined)[] } sequence\n * @param { Function | null } whenMissing\n *\n * @return { void }\n */\n static createRandomStringsUsingSequence (sequence: (string | undefined)[], whenMissing: Function | null = null): void {\n let next: number = 0\n\n whenMissing ??= (length: number): string => {\n const factoryCache: Function | null = this.randomStringFactory\n\n this.randomStringFactory = null\n\n const randomString: string = this.random(length)\n\n this.randomStringFactory = factoryCache\n\n next++\n\n return randomString\n }\n\n this.createRandomStringsUsing((length: number): any => {\n if (sequence[next] !== undefined) {\n return sequence[next++]\n }\n\n return whenMissing(length)\n })\n }\n\n /**\n * Indicate that random strings should be created normally and not using a custom factory.\n *\n * @return { void }\n */\n static createRandomStringsNormally (): void {\n this.randomStringFactory = null\n }\n\n /**\n * Repeat the given string.\n *\n * @param { string } string\n * @param { number } times\n *\n * @return { string }\n */\n static repeat (string: string, times: number = 1): string {\n return string.repeat(times)\n }\n\n /**\n * Replace a given value in the string sequentially with an array.\n *\n * @param { string[] } replace\n * @param { string } subject\n * @param { string } search\n *\n * @return { string }\n */\n static replaceArray (search: string, replace: string[], subject: string): string {\n const segments: string[] = subject.split(search)\n\n let result: string = segments.shift()!\n\n segments.forEach((segment: string): string => result += Str.toStringOr(replace.shift() ?? search, search) + segment)\n\n return result\n }\n\n /**\n * Convert the given value to a string or return the given fallback on failure.\n *\n * @param { * } value\n * @param { string } fallback\n *\n * @return { string }\n */\n static toStringOr (value: any, fallback: string): string {\n try {\n const result: string = String(value)\n\n if (result === 'undefined' || result === 'null') {\n return fallback\n }\n\n return result\n } catch {\n return fallback\n }\n }\n\n /**\n * Replace the given value in the given string.\n *\n * @param { string | string[] } search\n * @param { string } replace\n * @param { string } subject\n * @param { boolean } caseSensitive\n *\n * @return { string }\n */\n static replace (search: string | string[], replace: string, subject: string, caseSensitive: boolean = true): string {\n search = Array.isArray(search) ? search : [search]\n\n search.forEach((term: string | RegExp): void => {\n if (!caseSensitive) {\n term = new RegExp(term, 'gi')\n }\n\n subject = subject.replaceAll(term, replace)\n })\n\n return subject\n }\n\n /**\n * Replace the first occurrence of a given value in the string.\n *\n * @param { string } search\n * @param { string } replace\n * @param { string } subject\n *\n * @return { string }\n */\n static replaceFirst (search: string, replace: string, subject: string): string {\n if (search === '') {\n return subject\n }\n\n const position: number = subject.indexOf(search)\n\n if (position !== undefined) {\n return subject.replace(search, replace)\n }\n\n return subject\n }\n\n /**\n * Replace the first occurrence of the given value if it appears at the start of the string.\n *\n * @param { string } search\n * @param { string } replace\n * @param { string } subject\n *\n * @return { string }\n */\n static replaceStart (search: string, replace: string, subject: string): string {\n if (search === '') {\n return subject\n }\n\n if (this.startsWith(subject, search)) {\n return this.replaceFirst(search, replace, subject)\n }\n\n return subject\n }\n\n /**\n * Replace the last occurrence of a given value in the string.\n *\n * @param { string } search\n * @param { string } replace\n * @param { string } subject\n *\n * @return { string }\n */\n static replaceLast (search: string, replace: string, subject: string): string {\n if (search === '') {\n return subject\n }\n\n const position: number = subject.lastIndexOf(search)\n\n if (position !== 0) {\n return subject.substring(0, position) + replace + subject.substring(position + search.length)\n }\n\n return subject\n }\n\n /**\n * Replace the last occurrence of a given value if it appears at the end of the string.\n *\n * @param { string } search\n * @param { string } replace\n * @param { string } subject\n *\n * @return { string }\n */\n static replaceEnd (search: string, replace: string, subject: string): string {\n if (search === '') {\n return subject\n }\n\n if (this.endsWith(subject, search)) {\n return this.replaceLast(search, replace, subject)\n }\n\n return subject\n }\n\n /**\n * Replace the patterns matching the given regular expression.\n *\n * @param { string } pattern\n * @param { string | function } replace\n * @param { string } subject\n *\n * @return { string }\n */\n static replaceMatches (pattern: string, replace: string | Function, subject: string): string {\n const body: string = RegExpString.make(/^\\/(.*)\\/\\w*$/, pattern)\n const flags: string = RegExpString.make(/^\\/.*\\/(\\w*)$/, pattern)\n const expression: RegExp = new RegExp(body, flags + (flags.indexOf('g') !== -1 ? '' : 'g'))\n\n if (replace instanceof Function) {\n subject = subject.replace(expression, (matched: string): string => matched)\n }\n\n return subject.replace(expression, (replace as string))\n }\n\n /**\n * Remove any occurrence of the given string in the subject.\n *\n * @param { string } search\n * @param { string } subject\n * @param { boolean } caseSensitive\n *\n * @return { string }\n */\n static remove (search: string, subject: string, caseSensitive: boolean = true): string {\n return subject.replace(new RegExp(search, caseSensitive ? 'g' : 'gi'), '')\n }\n\n /**\n * Reverse the given string.\n *\n * @param { string } value\n *\n * @return { string }\n */\n static reverse (value: string): string {\n return value.split('').reverse().join('')\n }\n\n /**\n * Begin a string with a single instance of a given value.\n *\n * @param { string } value\n * @param { string } prefix\n *\n * @return { string }\n */\n static start (value: string, prefix: string): string {\n const quoted: string = preg_quote(prefix, '/')\n\n return prefix + value.replace(new RegExp(`^(?:${quoted})+`, 'u'), '')\n }\n\n /**\n * Substitute placeholders { key } using object with dot notation.\n * \n * @param str \n * @param data \n * @param def \n * @returns \n */\n static substitute (\n str: string,\n data: Record<string, unknown> = {},\n def?: string\n ): string | undefined {\n if (!str || !data) return undefined\n const regex = /{\\s*([a-zA-Z0-9_.]+)\\s*}/g\n const flattened = dot(data)\n return str.replace(regex, (_, key: string) => {\n const value = flattened[key]\n return value !== undefined ? String(value) : def ?? ''\n })\n }\n\n /**\n * Convert the given string to upper-case.\n *\n * @param { string } value\n *\n * @return { string }\n */\n static upper (value: string): string {\n return value.toUpperCase()\n }\n\n /**\n * Convert the given string to title case.\n *\n * @param { string } value\n *\n * @return { string }\n */\n static title (value: string): string {\n return value.split(/[^A-Za-z]/)\n .map((word: string): string => this.ucfirst(word[0] + word.substring(1).toLowerCase()))\n .join(' ')\n }\n\n /**\n * Convert the given string to title case for each word.\n *\n * @param { string } value\n *\n * @return { string }\n */\n static headline (value: string): string {\n let parts: string[] = value.split(' ')\n\n parts = parts.length > 1\n ? parts.map((part: string): string => this.title(part))\n : this.ucsplit(parts.join('_')).map((part: string): string => this.title(part))\n\n const collapsed: string = this.replace(['-', '_', ' '], '_', parts.join('_'))\n\n return collapsed.split('_').join(' ').trim()\n }\n\n /**\n * Convert the given string to APA-style title case.\n *\n * @see https://apastyle.apa.org/style-grammar-guidelines/capitalization/title-case\n *\n * @param { string } value\n *\n * @return { string }\n */\n static apa (value: string): string {\n if (value === '') {\n return value\n }\n\n const minorWords: string[] = [\n 'and', 'as', 'but', 'for', 'if', 'nor', 'or', 'so', 'yet', 'a', 'an',\n 'the', 'at', 'by', 'for', 'in', 'of', 'off', 'on', 'per', 'to', 'up', 'via',\n ]\n\n const endPunctuation: string[] = ['.', '!', '?', ':', '—', ',']\n\n const words: string[] = value.split(/\\s+/).filter(Boolean)\n\n words[0] = (words[0] as string).charAt(0).toUpperCase() + (words[0] as string).slice(1).toLowerCase()\n\n for (let i: number = 0; i < words.length; i++) {\n const lowercaseWord: string = (words[i] as string).toLowerCase()\n\n if (lowercaseWord.includes('-')) {\n let hyphenatedWords: string[] = lowercaseWord.split('-')\n\n hyphenatedWords = hyphenatedWords.map((part: string): string =>\n (minorWords.includes(part) && part.length <= 3) ? part : this.ucfirst(part)\n )\n\n words[i] = hyphenatedWords.join('-')\n } else if (minorWords.includes(lowercaseWord) &&\n lowercaseWord.length <= 3 &&\n !(i === 0 || endPunctuation.includes((words[i - 1] as string).slice(-1)))) {\n words[i] = lowercaseWord\n } else {\n words[i] = this.ucfirst(lowercaseWord)\n }\n }\n\n return words.join(' ')\n }\n\n /**\n * Get the singular form of an English word.\n *\n * @param { string } value\n *\n * @return { string }\n */\n static singular (value: string): string {\n // List of rules for singular words.\n const singular: { [key: string]: string } = {\n // Special cases\n '^(.*)(menu)s$': '$1$2',\n '^tights$': 'tights',\n '^shorts$': 'shorts',\n '^glasses$': 'glasses',\n '^pants$': 'pants',\n\n // -us -> -i (second declension nouns)\n '(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|viri?)i$': '$1us',\n '(vir)i$': '$1us',\n\n // -a -> -um/on (neuter nouns)\n '([ti])a$': '$1um',\n '([ti])a(?<!regatta)$': '$1um',\n '(tax)a$': '$1on',\n '(c)riteria$': '$1riterion',\n\n // -ices -> -ex/ix\n '(matr)ices$': '$1ix',\n '(vert|ind)ices$': '$1ex',\n\n // -oes -> -o\n '(buffal|her|potat|tomat|volcan)oes$': '$1o',\n\n // -ouses -> -ouse\n '(h|bl)ouses$': '$1ouse',\n 'ouses$': 'ouse',\n\n // -ies -> -y\n '([^aeiouy]|qu)ies$': '$1y',\n\n // -ves -> -f/fe\n '([lr])ves$': '$1f',\n '([^fo])ves$': '$1fe',\n '(shea|loa|lea|thie)ves$': '$1f',\n '(li|wi|kni)ves$': '$1fe',\n\n // -es -> -is\n '(analys|ax|cris|test|thes)es$': '$1is',\n '(cris|ax|test)es$': '$1is',\n\n // -es exceptions\n '(alias|status|bus)es$': '$1',\n '(shoe|slave)s$': '$1',\n '(corpse)s$': '$1',\n '(drive|dive|hive|olive|tive)s$': '$1',\n\n // -xes\n '([ftw]ax)es': '$1',\n\n // -ices -> -ouse\n '([m|l])ice$': '$1ouse',\n\n // -es -> -e\n '(o)es$': '$1',\n '(x|ch|ss|sh)es$': '$1',\n\n // -zes -> -ze\n '(quiz)zes$': '$1',\n\n // -en -> - (oxen -> ox)\n '^(ox)en$': '$1',\n\n // -people -> -person\n '(p)eople$': '$1erson',\n\n // Irregular plurals\n '(m)en$': '$1an',\n '(c)hildren$': '$1hild',\n '(f)eet$': '$1oot',\n '(m)ice$': '$1ouse',\n '(t)eeth$': '$1ooth',\n '(g)eese$': '$1oose',\n\n // -news\n '(n)ews$': '$1ews',\n\n // -eau\n 'eaus$': 'eau',\n\n // -ses -> -sis\n '(^analy)ses$': '$1sis',\n '((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$': '$1$2sis',\n\n // -movies\n '(m)ovies$': '$1ovie',\n\n // -series\n '(s)eries$': '$1eries',\n\n // -us\n '([^a])uses$': '$1us',\n '(us)es$': '$1',\n\n // -status\n '(s)tatus(es)?$': '$1tatus',\n\n // -campus\n '(c)ampus$': '$1ampus',\n\n // General case\n 's$': ''\n }\n\n // List of words that change irregularly.\n const irregular: { [key: string]: string } = {\n // A\n 'abuses': 'abuse',\n 'alumnae': 'alumna',\n 'alumni': 'alumnus',\n 'analyses': 'analysis',\n 'appendices': 'appendix',\n 'atlases': 'atlas',\n 'avalanches': 'avalanche',\n 'axes': 'axis', // Also covers 'axe'\n\n // B\n 'bacilli': 'bacillus',\n 'bacteria': 'bacterium',\n 'bases': 'basis',\n 'beaux': 'beau',\n 'beefs': 'beef',\n 'blouses': 'blouse',\n 'brothers': 'brother',\n 'brownies': 'brownie',\n 'bureaux': 'bureau',\n\n // C\n 'caches': 'cache',\n 'cacti': 'cactus',\n 'cafes': 'cafe',\n 'calves': 'calf',\n 'canvases': 'canvas',\n 'caves': 'cave',\n 'chateaux': 'chateau',\n 'children': 'child',\n 'cookies': 'cookie',\n 'corpuses': 'corpus',\n 'cows': 'cow',\n 'crises': 'crisis',\n 'criteria': 'criterion',\n 'curricula': 'curriculum',\n 'curves': 'curve',\n\n // D\n 'deer': 'deer',\n 'demos': 'demo',\n 'diagnoses': 'diagnosis',\n 'dominoes': 'domino',\n\n // E\n 'echoes': 'echo',\n 'elves': 'elf',\n 'ellipses': 'ellipsis',\n 'emphases': 'emphasis',\n 'epochs': 'epoch',\n\n // F\n 'fish': 'fish',\n 'foci': 'focus',\n 'foes': 'foe',\n 'feet': 'foot',\n 'formulae': 'formula',\n 'fungi': 'fungus',\n\n // G\n 'ganglions': 'ganglion',\n 'gases': 'gas',\n 'genies': 'genie',\n 'genera': 'genus',\n 'geese': 'goose',\n 'graffiti': 'graffito',\n 'graves': 'grave',\n\n // H\n 'halves': 'half',\n 'hippopotami': 'hippopotamus',\n 'hoaxes': 'hoax',\n 'hoofs': 'hoof', // Also acceptable: 'hooves'\n 'humans': 'human',\n\n // I\n 'irises': 'iris',\n\n // K\n 'knives': 'knife',\n\n // L\n 'larvae': 'larva',\n 'leaves': 'leaf',\n 'lenses': 'lens',\n 'lives': 'life',\n 'loaves': 'loaf',\n\n // M\n 'men': 'man',\n 'matrices': 'matrix',\n 'means': 'means',\n 'media': 'medium',\n 'memoranda': 'memorandum',\n 'monies': 'money',\n 'mongooses': 'mongoose',\n 'mice': 'mouse',\n 'mottoes': 'motto',\n 'moves': 'move',\n 'mythoi': 'mythos',\n\n // N\n 'nebulae': 'nebula',\n 'neuroses': 'neurosis',\n 'niches': 'niche',\n 'niveaux': 'niveau',\n 'nuclei': 'nucleus',\n 'numina': 'numen',\n\n // O\n 'oases': 'oasis',\n 'occiputs': 'occiput',\n 'octopuses': 'octopus',\n 'offspring': 'offspring',\n 'opuses': 'opus',\n 'oxen': 'ox',\n\n // P\n 'parentheses': 'parenthesis',\n 'passersby': 'passerby',\n 'penises': 'penis',\n 'people': 'person',\n 'phenomena': 'phenomenon',\n 'plateaux': 'plateau',\n\n // R\n 'radii': 'radius',\n 'runners-up': 'runner-up',\n\n // S\n 'safes': 'safe',\n 'saves': 'save',\n 'scarves': 'scarf',\n 'selves': 'self',\n 'series': 'series',\n 'sexes': 'sex',\n 'sheep': 'sheep',\n 'shelves': 'shelf',\n 'sieves': 'sieve',\n 'soliloquies': 'soliloquy',\n 'sons-in-law': 'son-in-law',\n 'species': 'species',\n 'stadiums': 'stadium',\n 'stimuli': 'stimulus',\n 'strata': 'stratum',\n 'swine': 'swine',\n 'syllabi': 'syllabus',\n 'syntheses': 'synthesis',\n\n // T\n 'testes': 'testis',\n 'theses': 'thesis',\n 'thieves': 'thief',\n 'teeth': 'tooth',\n 'tornadoes': 'tornado',\n 'trilbys': 'trilby',\n 'turfs': 'turf', // Also acceptable: 'turves'\n\n // V\n 'valves': 'valve',\n 'volcanoes': 'volcano',\n\n // W\n 'waves': 'wave',\n 'wives': 'wife',\n 'wolves': 'wolf',\n\n // Z\n 'zombies': 'zombie'\n }\n\n // List of words that do not change.\n const uncountable: string[] = [\n // A\n 'advice',\n 'aircraft',\n 'amoyese',\n 'art',\n 'audio',\n\n // B\n 'baggage',\n 'bison',\n 'borghese',\n 'bream',\n 'breeches',\n 'britches',\n 'buffalo',\n 'butter',\n\n // C\n 'cantus',\n 'carp',\n 'cattle',\n 'chassis',\n 'clippers',\n 'clothing',\n 'coal',\n 'cod',\n 'coitus',\n 'compensation',\n 'congoese',\n 'contretemps',\n 'coreopsis',\n 'corps',\n 'cotton',\n\n // D\n 'data',\n 'debris',\n 'deer',\n 'diabetes',\n 'djinn',\n\n // E\n 'education',\n 'eland',\n 'elk',\n 'emoji',\n 'equipment',\n 'evidence',\n\n // F\n 'faroese',\n 'feedback',\n 'fish',\n 'flounder',\n 'flour',\n 'foochowese',\n 'food',\n 'furniture',\n\n // G\n 'gallows',\n 'genevese',\n 'genoese',\n 'gilbertese',\n 'gold',\n\n // H\n 'headquarters',\n 'herpes',\n 'hijinks',\n 'homework',\n 'hovercraft',\n 'hottentotese',\n\n // I\n 'impatience',\n 'information',\n 'innings',\n\n // J\n 'jackanapes',\n 'jeans',\n 'jedi',\n\n // K\n 'kin',\n 'kiplingese',\n 'knowledge',\n 'kongoese',\n\n // L\n 'leather',\n 'love',\n 'lucchese',\n 'luggage',\n\n // M\n 'mackerel',\n 'Maltese',\n 'management',\n 'metadata',\n 'mews',\n 'money',\n 'moose',\n 'mumps',\n 'music',\n\n // N\n 'nankingese',\n 'news',\n 'nexus',\n 'niasese',\n 'nutrition',\n\n // O\n 'oil',\n 'offspring',\n\n // P\n 'patience',\n 'pekingese',\n 'piedmontese',\n 'pike',\n 'pincers',\n 'pistoiese',\n 'plankton',\n 'pliers',\n 'pokemon',\n 'police',\n 'polish',\n 'portuguese',\n 'proceedings',\n 'progress',\n\n // Q\n // (none yet)\n\n // R\n 'rabies',\n 'rain',\n 'research',\n 'rhinoceros',\n 'rice',\n\n // S\n 'salmon',\n 'sand',\n 'sarawakese',\n 'scissors',\n 'sea[- ]bass',\n 'series',\n 'shavese',\n 'shears',\n 'sheep',\n 'shrimp',\n 'siemens',\n 'silk',\n 'sms',\n 'soap',\n 'social media',\n 'spacecraft',\n 'spam',\n 'species',\n 'staff',\n 'sugar',\n 'swine',\n\n // T\n 'talent',\n 'toothpaste',\n 'traffic',\n 'travel',\n 'trousers',\n 'trout',\n 'tuna',\n\n // U\n 'us',\n\n // V\n 'vermontese',\n 'vinegar',\n\n // W\n 'weather',\n 'wenchowese',\n 'wheat',\n 'whiting',\n 'wildebeest',\n 'wood',\n 'wool',\n\n // Y\n 'yengeese',\n 'you'\n ]\n\n if (uncountable.indexOf(value.toLowerCase()) >= 0) {\n return matchCase(value, value)\n }\n\n for (const word in irregular) {\n const pattern: RegExp = new RegExp(`${word}$`, 'i')\n\n if (pattern.test(value)) {\n return matchCase(value.replace(pattern, (irregular[word] as string)), value)\n }\n }\n\n for (const word in singular) {\n const pattern: RegExp = new RegExp(word, 'i')\n\n if (pattern.test(value)) {\n return matchCase(value.replace(pattern, (singular[word] as string)), value)\n }\n }\n\n return matchCase(value, value)\n }\n\n /**\n * Get the singular form of an English word.\n *\n * @param { string } value\n * \n * @alias singular\n *\n * @return { string }\n */\n static singularize (value: string): string {\n return this.singular(value)\n }\n\n /**\n * Generate a URL friendly \"slug\" from a given string.\n *\n * @param { string } title\n * @param { string } separator\n * @param { object } dictionary\n *\n * @return { string }\n */\n static slug (title: string, separator: string = '-', dictionary: { [key: string]: string } = { '@': 'at' }): string {\n const flip: string = separator === '-' ? '_' : '-'\n\n title = title.replace(`![${preg_quote(flip)}]+!u`, separator)\n\n for (const value in dictionary) {\n dictionary[value] = separator + dictionary[value] + separator\n }\n\n for (const value in dictionary) {\n title = title.replaceAll(value, (dictionary[value] as string))\n }\n\n title = this.lower(title).replace(`![^${preg_quote(separator)}pLpNs]+!u`, '')\n\n return title.replaceAll(/\\s|!/g, separator).replace(new RegExp('\\\\' + separator + '+', 'g'), separator)\n }\n\n /**\n * Generate a URL friendly \"slug\" from a given string.\n *\n * @param { string } separator\n * @param { string } title\n * @param { object } dictionary\n * \n * @alias singular\n *\n * @return { string }\n */\n static slugify (title: string, separator: string = '-', dictionary: { [key: string]: string } = { '@': 'at' }): string {\n return this.slug(title, separator, dictionary)\n }\n\n /**\n * Convert a string to snake case.\n *\n * @param { string } value\n * @param { string } delimiter\n *\n * @return { string }\n */\n static snake (value: string, delimiter: string = '_'): string {\n value = ucwords(value).replace(new RegExp(/\\s+/, 'u'), '')\n\n value = this.lower(value.replace(new RegExp(/(.)(?=[A-Z])/, 'ug'), `$1${delimiter}`))\n\n return value\n }\n\n /**\n * Uppercase the first character of each word in a string\n *\n * @param { string } string The input string.\n * @param { string } separators The optional separators contains the word separator characters.\n \n * @return { string } String the modified string.\n */\n static capitalize (string: string, separators: string = ' \\t\\r\\n\\f\\v'): string {\n return ucwords(string, separators)\n }\n\n /**\n * Uppercase the first character of each word in a string\n *\n * @param { string } string The input string.\n * @param { string } separators The optional separators contains the word separator characters.\n \n * @return { string } String the modified string.\n */\n static ucwords (string: string, separators: string = ' \\t\\r\\n\\f\\v'): string {\n return ucwords(string, separators)\n }\n\n /**\n * Remove all whitespace from both ends of a string.\n *\n * @param { string } value\n * @param { string | null } characters\n *\n * @return { string }\n */\n static trim (value: string, characters: string | null = null): string {\n if (characters === null) {\n return value.trim()\n }\n\n if (characters === '') {\n return value\n }\n\n if (characters === ' ') {\n return value.replaceAll(' ', '')\n }\n\n characters = characters.split('').join('|')\n\n const regex: RegExp = new RegExp(`${characters}+`, 'g')\n\n return value.replace(regex, '') ?? value\n }\n\n /**\n * Remove all whitespace from the beginning of a string.\n *\n * @param { string } value\n * @param { string | null } characters\n *\n * @return { string }\n */\n static ltrim (value: string, characters: string | null = null): string {\n if (characters === null) {\n return value.trimStart()\n }\n\n if (characters === '') {\n return value\n }\n\n if (characters === ' ') {\n return this.replaceStart(' ', '', value)\n }\n\n characters.split('').forEach((character: string): string => value = this.replaceStart(character, '', value))\n\n return value\n }\n\n /**\n * Remove all whitespace from the end of a string.\n *\n * @param { string } value\n * @param { string | null } characters\n *\n * @return { string }\n */\n static rtrim (value: string, characters: string | null = null): string {\n if (characters === null) {\n return value.trimEnd()\n }\n\n if (characters === '') {\n return value\n }\n\n if (characters === ' ') {\n return this.replaceEnd(' ', '', value)\n }\n\n characters.split('').forEach((character: string): string => value = this.replaceEnd(character, '', value))\n\n return value\n }\n\n /**\n * Remove all \"extra\" blank space from the given string.\n *\n * @param { string } value\n *\n * @return { string }\n */\n static squish (value: string): string {\n return value.replace(/\\s\\s+/g, ' ').trim()\n }\n\n /**\n * Determine if a given string starts with a given substring.\n *\n * @param { string } haystack\n * @param { string | string[] } needles\n *\n * @return { boolean }\n */\n static startsWith (haystack: string, needles: string | string[]): boolean {\n let result: boolean = false\n\n needles = Array.isArray(needles) ? needles : [needles]\n\n needles.forEach((needle: string): void => {\n if (needle !== '' && haystack.startsWith(needle)) {\n result = true\n }\n })\n\n return result\n }\n\n /**\n * Determine if a given string doesn't start with a given substring.\n *\n * @param { string } haystack\n * @param { string | string[] } needles\n *\n * @return { boolean }\n */\n static doesntStartWith (haystack: string, needles: string | string[]): boolean {\n return !this.startsWith(haystack, needles)\n }\n\n /**\n * Convert a value to studly caps case.\n *\n * @param { string } value\n *\n * @return { string }\n */\n static studly (value: string): string {\n const words: string[] = this.replace(['-', '_'], ' ', value).split(' ')\n\n const studlyWords: string[] = words.map((word: string): string => this.ucfirst(word))\n\n return studlyWords.join('')\n }\n\n /**\n * Convert a value to Pascal case.\n *\n * @param { string } value\n *\n * @return { string }\n */\n static pascal (value: string): string {\n return this.studly(value)\n }\n\n /**\n * Returns the portion of the string specified by the start and length parameters.\n *\n * @param { string } string\n * @param { number } start\n * @param { number | null } length\n *\n * @return { string }\n */\n static substr (string: string, start: number, length: number | null = null): string {\n string = string.replace(/<[^>]+>/g, '')\n\n if (start < 0) {\n start = string.length + start\n\n if (start < 0) {\n start = 0\n }\n }\n\n if (length !== null && length < 0) {\n return ''\n }\n\n if (length === 0 || length === null) {\n return string.substring(start, length ?? string.length)\n }\n\n return string.substring(start, start + length)\n }\n\n /**\n * Returns the number of substring occurrences.\n *\n * @param { string } haystack\n * @param { string } needle\n * @param { number } offset\n * @param { number | null } length\n *\n * @return { number }\n */\n static substrCount (haystack: string, needle: string, offset: number = 0, length: number | null = null): number {\n if (length) {\n return haystack.substring(offset).substring(0, length).split(needle).length - 1\n }\n\n return haystack.substring(offset).split(needle).length - 1\n }\n\n /**\n * Replace text within a portion of a string.\n *\n * @param { string } string\n * @param { string } replace\n * @param { number } offset\n * @param { number | null } length\n *\n * @return { string }\n */\n static substrReplace (string: string, replace: string, offset: number = 0, length: number | null = null): string {\n if (length !== null) {\n return string.substring(0, offset) + replace + string.substring(offset)\n }\n\n return string.substring(0, offset) + replace\n }\n\n /**\n * Swap multiple keywords in a string with other keywords.\n *\n * @param { object } map\n * @param { string } subject\n *\n * @return { string }\n */\n static swap (map: Record<string, string>, subject: string): string {\n for (const value in map) {\n subject = subject.replace(value, (map[value] as string))\n }\n\n return subject\n }\n\n /**\n * Take the first or last {limit} characters of a string.\n *\n * @param { string } string\n * @param { number } limit\n *\n * @return { string }\n */\n static take (string: string, limit: number): string {\n if (limit < 0) {\n return this.substr(string, limit)\n }\n\n return this.substr(string, 0, limit)\n }\n\n /**\n * Convert the given string to Base64 encoding.\n *\n * @param { string } string\n *\n * @return { string }\n */\n static toBase64 (string: string): string {\n return btoa(string)\n }\n\n /**\n * Decode the given Base64 encoded string.\n *\n * @param { string } string\n *\n * @return { string }\n */\n static fromBase64 (string: string): string {\n return atob(string)\n }\n\n /**\n * Checks if a string is numeric\n * \n * @param string \n * @returns \n */\n static isNumber (string: string): boolean {\n return !isNaN(Number(string)) && string.trim() !== ''\n }\n\n /**\n * Checks if a string is an integer\n * \n * @param string \n * @returns \n */\n static isInteger (string: string): boolean {\n return Number.isInteger(Number(string)) && string.trim() !== ''\n }\n\n /**\n * ROT-N cipher.\n * \n * @param string \n * @param n \n * @returns \n */\n static rot (string: string, n: number = 13): string {\n return string.replace(/[a-zA-Z]/g, (char: string) => {\n const code = char.charCodeAt(0)\n const start = char >= 'a' ? 'a'.charCodeAt(0) : 'A'.charCodeAt(0)\n const end = char >= 'a' ? 'z'.charCodeAt(0) : 'Z'.charCodeAt(0)\n let next = code + n\n while (next < start) next += 26\n while (next > end) next -= 26\n return String.fromCharCode(next)\n })\n }\n\n /**\n * Replace trailing punctuation with new format.\n * \n * @param string \n * @param newFormat \n * @returns \n */\n static replacePunctuation (string: string, newFormat: string): string {\n return string.replace(/[.,;:!?]*$/, '') + newFormat\n }\n\n /**\n * Array/object driven text replacement.\n * \n * @param string \n * @param replacements \n * @returns \n */\n static translate (string: string, replacements: Record<string, string> | Array<[string, string]>): string {\n let result = string\n if (Array.isArray(replacements)) {\n for (const [from, to] of replacements) result = result.replace(new RegExp(from, 'g'), to)\n } else {\n for (const [from, to] of Object.entries(replacements)) result = result.replace(new RegExp(from, 'g'), to)\n }\n return result\n }\n\n /**\n * Strip slashes recursively.\n * \n * @param string \n * @returns \n */\n static ss (string: string): string {\n return string.replace(/\\\\(.)/g, '$1')\n }\n\n /**\n * First and last N lines.\n * \n * @param string \n * @param amount \n * @returns \n */\n static firstLines (string: string, amount: number = 1): string {\n return string.split('\\n').slice(0, amount).join('\\n')\n }\n\n /**\n * Last and first N lines.\n * \n * @param string \n * @param amount \n * @returns \n */\n static lastLines (string: string, amount: number = 1): string {\n return string.split('\\n').slice(-amount).join('\\n')\n }\n\n /**\n * Make a string's first character lowercase.\n *\n * @param { string } string\n *\n * @return { string }\n */\n static lcfirst (string: string): string {\n return this.lower(this.substr(string, 0, 1)) + this.substr(string, 1, string.length)\n }\n\n /**\n * Make a string's first character uppercase.\n *\n * @param { string } string\n *\n * @return { string }\n */\n static ucfirst (string: string): string {\n return this.upper(this.substr(string, 0, 1)) + this.substr(string, 1, string.length)\n }\n\n /**\n * Split a string into pieces by uppercase characters.\n *\n * @param { string } string\n *\n * @return { string[] }\n */\n static ucsplit (string: string): string[] {\n return string.split(new RegExp(/(?=\\p{Lu})/u))\n }\n\n /**\n * Get the number of words a string contains.\n *\n * @param { string } string\n *\n * @return { number }\n */\n static wordCount (string: string): number {\n return string.split(/\\s+/).length\n }\n\n /**\n * Wrap a string to a given number of characters.\n *\n * @param { string } string\n * @param { number } characters\n * @param { string } breakStr\n * @param { boolean } cutLongWords\n *\n * @returns { string }\n */\n static wordWrap (string: string, characters: number = 75, breakStr: string = '\\n', cutLongWords: boolean = false): string {\n const breakWithSpace: string = cutLongWords ? breakStr + '\\u00ad' : breakStr\n const regex: RegExp = new RegExp(`.{1,${characters}}`, 'g')\n const result: string = string.replace(regex, (substr: string): string => substr.trim() + breakWithSpace)\n\n return this.replaceLast(breakStr, '', result)\n }\n\n /**\n * Generate a UUID (version 4).\n *\n * @return { string }\n */\n static uuid (): string {\n if (this.uuidFactory !== null) {\n return this.uuidFactory()\n }\n\n let time: number = parseInt((Math.random() * Number.MAX_SAFE_INTEGER + 1).toString().substring(0, 13))\n\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (character: string): string {\n const randomChar: number = (time + Math.random() * 16) % 16 | 0\n time = Math.floor(time / 16)\n\n return (character === 'x' ? randomChar : (randomChar & 0x3 | 0x8)).toString(16)\n })\n }\n\n /**\n * Generate a UUID (version 7).\n *\n * @return { string }\n */\n static uuid7 (time: Date | null = null): string {\n if (this.uuidFactory !== null) {\n return this.uuidFactory()\n }\n\n const values = new Uint32Array(3)\n\n crypto.getRandomValues(values)\n\n const timestamp: number = time ? time.getTime() : Date.now()\n\n if (timestamp < 0 || timestamp > 281474976710655) {\n throw new RangeError('Timestamp must be a 48-bit positive integer')\n }\n\n const [r1, r2, r3] = values\n\n const randomA: number = (r1 as number) & 0xfff\n const randomBHi: number = (r2 as number) & 0x3fffffff\n const randomBLo: number = r3 as number\n\n const bytes = new Uint8Array(16)\n\n bytes[0] = timestamp / 2 ** 40\n bytes[1] = timestamp / 2 ** 32\n bytes[2] = timestamp / 2 ** 24\n bytes[3] = timestamp / 2 ** 16\n bytes[4] = timestamp / 2 ** 8\n bytes[5] = timestamp\n bytes[6] = 0x70 | (randomA >>> 8)\n bytes[7] = randomA\n bytes[8] = 0x80 | (randomBHi >>> 24)\n bytes[9] = randomBHi >>> 16\n bytes[10] = randomBHi >>> 8\n bytes[11] = randomBHi\n bytes[12] = randomBLo >>> 24\n bytes[13] = randomBLo >>> 16\n bytes[14] = randomBLo >>> 8\n bytes[15] = randomBLo\n\n const digits = '0123456789abcdef'\n\n let result: string = ''\n\n for (let i: number = 0; i < 16; i++) {\n result += digits.charAt(bytes[i]! >>> 4)\n result += digits.charAt(bytes[i]! & 0xf)\n\n if (i === 3 || i === 5 || i === 7 || i === 9) {\n result += '-'\n }\n }\n\n return result\n }\n\n /**\n * Generate a time-ordered UUID (version 4).\n *\n * @return { string }\n */\n static orderedUuid (): string {\n if (this.uuidFactory !== null) {\n return this.uuidFactory()\n }\n\n let time: number = new Date().getTime()\n\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (character: string): string {\n const randomChar: number = (time + Math.random() * 16) % 16 | 0\n time = Math.floor(time / 16)\n\n return (character === 'x' ? randomChar : (randomChar & 0x3 | 0x8)).toString(16)\n })\n }\n\n /**\n * Set the callable that will be used to generate UUIDs.\n *\n * @param { Function | null } factory\n *\n * @return { void }\n */\n static createUuidsUsing (factory: Function | null = null): void {\n this.uuidFactory = factory\n }\n\n /**\n * Set the sequence that will be used to generate random strings.\n *\n * @param { (string | undefined)[] } sequence\n * @param { Function | null } whenMissing\n *\n * @return { void }\n */\n static createUuidsUsingSequence (sequence: (string | undefined)[], whenMissing: Function | null = null): void {\n let next: number = 0\n\n whenMissing ??= (): string => {\n const factoryCache: Function | null = this.uuidFactory\n\n this.uuidFactory = null\n\n const uuid: string = this.uuid()\n\n this.uuidFactory = factoryCache\n\n next++\n\n return uuid\n }\n\n this.createUuidsUsing(() => {\n if (sequence[next] !== undefined) {\n return sequence[next++]\n }\n\n return whenMissing()\n })\n }\n\n /**\n * Always return the same UUID when generating new UUIDs.\n *\n * @param { Function | null } callback\n *\n * @return { string }\n */\n static freezeUuids (callback: Function | null = null): string {\n const uuid: string = this.uuid()\n\n this.createUuidsUsing((): string => uuid)\n\n if (callback !== null) {\n try {\n callback(uuid)\n } finally {\n this.createUuidsNormally()\n }\n }\n\n return uuid\n }\n\n /**\n * Indicate that UUIDs should be created normally and not using a custom factory.\n *\n * @return { void }\n */\n static createUuidsNormally (): void {\n this.uuidFactory = null\n }\n\n /**\n * Generate a ULID.\n *\n * @return { string }\n */\n static ulid (): string {\n if (this.ulidFactory !== null) {\n return this.ulidFactory()\n }\n\n const encoding: string = '0123456789ABCDEFGHJKMNPQRSTVWXYZ'\n const encodingLength: number = encoding.length\n const timeLength: number = 10\n const randomLength: number = 16\n\n /**\n * Generate random Encoding Time.\n *\n * @return { string }\n */\n function generateEncodedTime (): string {\n let encodedTime: string = ''\n let now: number = new Date().getTime()\n\n for (let length: number = timeLength; length > 0; length--) {\n const mod: number = now % encodingLength\n encodedTime = encoding.charAt(mod) + encodedTime\n now = (now - mod) / encodingLength\n }\n\n return encodedTime\n }\n\n /**\n * Generate random Number.\n *\n * @return { number }\n */\n function generateRandomNumber (): number {\n const buffer: Uint8Array = new Uint8Array(1)\n\n crypto.getRandomValues(buffer)\n\n return (buffer[0] as number) / 0xff\n }\n\n /**\n * Generate random String.\n *\n * @return { string }\n */\n function generateRandomString (): string {\n let string: string = ''\n\n for (let length: number = randomLength; length > 0; length--) {\n let randomNumber: number = Math.floor(generateRandomNumber() * encodingLength)\n\n if (randomNumber === encodingLength) {\n randomNumber = encodingLength - 1\n }\n\n string += encoding.charAt(randomNumber)\n }\n\n return string\n }\n\n return generateEncodedTime() + generateRandomString()\n }\n\n /**\n * Set the callable that will be used to generate ULIDs.\n *\n * @param { Function | null } factory\n *\n * @return { void }\n */\n static createUlidsUsing (factory: Function | null = null): void {\n this.ulidFactory = factory\n }\n\n /**\n * Set the sequence that will be used to generate ULIDs.\n *\n * @param { (string | undefined)[] } sequence\n * @param { Function | null } whenMissing\n *\n * @return { void }\n */\n static createUlidsUsingSequence (sequence: (string | undefined)[], whenMissing: Function | null = null): void {\n let next: number = 0\n\n whenMissing ??= (): string => {\n const factoryCache: Function | null = this.ulidFactory\n\n this.ulidFactory = null\n\n const ulid: string = this.ulid()\n\n this.ulidFactory = factoryCache\n\n next++\n\n return ulid\n }\n\n this.createUlidsUsing(() => {\n if (sequence[next] !== undefined) {\n return sequence[next++]\n }\n\n return whenMissing()\n })\n }\n\n /**\n * Always return the same UUID when generating new UUIDs.\n *\n * @param { Function | null } callback\n *\n * @return { string }\n */\n static freezeUlids (callback: Function | null = null): string {\n const ulid: string = this.ulid()\n\n this.createUlidsUsing(() => ulid)\n\n if (callback !== null) {\n try {\n callback(ulid)\n } finally {\n this.createUlidsNormally()\n }\n }\n\n return ulid\n }\n\n /**\n * Indicate that ULIDs should be created normally and not using a custom factory.\n *\n * @return { void }\n */\n static createUlidsNormally (): void {\n this.ulidFactory = null\n }\n}\n\nexport class Stringable {\n /**\n * The underlying string value.\n *\n * @private\n *\n * @type { string }\n */\n readonly #value: string\n\n /**\n * Create a new instance of the class.\n *\n * @param { string } value\n */\n constructor(value: string = '') {\n this.#value = value\n }\n\n /**\n * Return the remainder of a string after the first occurrence of a given value.\n *\n * @param { string } search\n *\n * @return { Stringable }\n */\n after (search: string): Stringable {\n return new Stringable(Str.after(this.#value, search))\n }\n\n /**\n * Return the remainder of a string after the last occurrence of a given value.\n *\n * @param { string } search\n *\n * @return { Stringable }\n */\n afterLast (search: string): Stringable {\n return new Stringable(Str.afterLast(this.#value, search))\n }\n\n /**\n * Append the given values to the string.\n *\n * @param { string | string[] } values\n *\n * @return { Stringable }\n */\n append (...values: string[]): Stringable {\n return new Stringable(this.#value + values.join(''))\n }\n\n /**\n * Append a new line to the string.\n *\n * @param { number } count\n *\n * @return { Stringable }\n */\n newLine (count: number = 1): Stringable {\n return this.append('\\n'.repeat(count))\n }\n\n /**\n * Transliterate a UTF-8 value to ASCII.\n *\n * @return { Stringable }\n */\n ascii (): Stringable {\n return new Stringable(Str.ascii(this.#value))\n }\n\n /**\n * Get the trailing name component of the path.\n *\n * @param { string } suffix\n *\n * @return { Stringable }\n */\n basename (suffix: string = ''): Stringable {\n let basename: string = this.#value\n\n if (this.#value.split('/')[0] !== this.#value) {\n basename = (this.#value.split('/').pop() as string)\n }\n\n if (this.#value.split('\\\\')[0] !== this.#value) {\n basename = (this.#value.split('\\\\').pop() as string)\n }\n\n if (suffix !== '') {\n basename = basename.replace(suffix, '')\n }\n\n return new Stringable(basename)\n }\n\n /**\n * Get the character at the specified index.\n *\n * @param { number } index\n *\n * @return { string | false }\n */\n charAt (index: number): string | false {\n return Str.charAt(this.#value, index)\n }\n\n /**\n * Remove the given string if it exists at the start of the current string.\n *\n * @param { string | string[] } needle\n *\n * @return { Stringable }\n */\n chopStart (needle: string | string[]): Stringable {\n return new Stringable(Str.chopStart(this.#value, needle))\n }\n\n /**\n * Remove the given string if it exists at the end of the current string.\n *\n * @param { string | string[] } needle\n *\n * @return { Stringable }\n */\n chopEnd (needle: string | string[]): Stringable {\n return new Stringable(Str.chopEnd(this.#value, needle))\n }\n\n /**\n * Get the basename of the class path.\n *\n * @return { Stringable }\n */\n classBasename (): Stringable {\n return this.basename()\n }\n\n /**\n * Get the portion of a string before the first occurrence of a given value.\n *\n * @param { string } search\n *\n * @return { Stringable }\n */\n before (search: string): Stringable {\n return new Stringable(Str.before(this.#value, search))\n }\n\n /**\n * Get the portion of a string before the last occurrence of a given value.\n *\n * @param { string } search\n *\n * @return { Stringable }\n */\n beforeLast (search: string): Stringable {\n return new Stringable(Str.beforeLast(this.#value, search))\n }\n\n /**\n * Get the portion of a string between two given values.\n *\n * @param { string } from\n * @param { string } to\n *\n * @return { Stringable }\n */\n between (from: string, to: string): Stringable {\n return new Stringable(Str.between(this.#value, from, to))\n }\n\n /**\n * Get the smallest possible portion of a string between two given values.\n *\n * @param { string } from\n * @param { string } to\n *\n * @return { Stringable }\n */\n betweenFirst (from: string, to: string): Stringable {\n return new Stringable(Str.betweenFirst(this.#value, from, to))\n }\n\n /**\n * Convert a value to camel case.\n *\n * @return { Stringable }\n */\n camel (): Stringable {\n return new Stringable(Str.camel(this.#value))\n }\n\n /**\n * Determine if a given string contains a given substring.\n *\n * @param { string | string[] } needles\n * @param { boolean } ignoreCase\n *\n * @return { boolean }\n */\n contains (needles: string | string[], ignoreCase: boolean = false): boolean {\n return Str.contains(this.#value, needles, ignoreCase)\n }\n\n /**\n * Determine if a given string contains all array values.\n *\n * @param { string[] } needles\n * @param { boolean } ignoreCase\n *\n * @return { boolean }\n */\n containsAll (needles: string[], ignoreCase: boolean = false): boolean {\n return Str.containsAll(this.#value, needles, ignoreCase)\n }\n\n /**\n * Determine if a given string doesn't contain a given substring.\n *\n * @param { string | string[] } needles\n * @param { boolean } ignoreCase\n *\n * @return { boolean }\n */\n doesntContain (needles: string | string[], ignoreCase: boolean = false): boolean {\n return !this.contains(needles, ignoreCase)\n }\n\n /**\n * Convert the case of a string.\n *\n * @param { Mode | number } mode\n *\n * @return { Stringable }\n */\n convertCase (mode: Mode | number = Mode.MB_CASE_FOLD): Stringable {\n return new Stringable(Str.convertCase(this.#value, mode))\n }\n\n /**\n * Replace consecutive instances of a given character with a single character in the given string.\n *\n * @param { string | string[] } characters\n *\n * @return { string }\n */\n deduplicate (characters: string | string[] = ' '): Stringable {\n return new Stringable(Str.deduplicate(this.#value, characters))\n }\n\n /**\n * Get the parent directory's path.\n *\n * @param { number } levels\n *\n * @return { Stringable }\n */\n dirname (levels: number = 1): Stringable {\n let dirname: string = this.#value\n let parts: string[] = []\n let isValidDirname: boolean = false\n let hasValidLevels: boolean = false\n\n if (this.#value.split('/')[0] !== this.#value) {\n parts = this.#value.split('/')\n dirname = parts.slice(0, parts.length - levels).join('/')\n isValidDirname = true\n hasValidLevels = parts.length <= levels + 1\n }\n\n if (this.#value.split('\\\\')[0] !== this.#value) {\n parts = this.#value.split('\\\\')\n dirname = parts.slice(0, parts.length - levels).join('\\\\')\n isValidDirname = true\n hasValidLevels = parts.length <= levels + 1\n }\n\n if (!isValidDirname) {\n dirname = '.'\n }\n\n if (isValidDirname && hasValidLevels) {\n dirname = '\\\\'\n }\n\n return new Stringable(dirname)\n }\n\n /**\n * Determine if a given string ends with a given substring.\n *\n * @param { string | string[] } needles\n *\n * @return { boolean }\n */\n endsWith (needles: string | string[]): boolean {\n return Str.endsWith(this.#value, needles)\n }\n\n /**\n * Determine if a given string doesn't end with a given substring.\n *\n * @param { string | string[] } needles\n *\n * @return { boolean }\n */\n doesntEndWith (needles: string | string[]): boolean {\n return !this.endsWith(needles)\n }\n\n /**\n * Returns all the characters except the last.\n * \n * @returns \n */\n chop () {\n return new Stringable(Str.chop(this.#value))\n }\n\n /**\n * Escape string for JSON encoding (returns string without quotes). \n * \n * @param string \n * @returns \n */\n esc (): Stringable {\n return new Stringable(Str.esc(this.#value))\n }\n\n /**\n * Determine if the string is an exact match with the given value.\n *\n * @param { Stringable | string } value\n *\n * @return { boolean }\n */\n exactly (value: Stringable | string): boolean {\n if (value instanceof Stringable) {\n value = value.toString()\n }\n\n return this.#value === value\n }\n\n /**\n * Extracts an excerpt from text that matches the first instance of a phrase.\n *\n * @param { string } phrase\n * @param { ExcerptOptions } options\n *\n * @return { string | null }\n */\n excerpt (phrase: string = '', options: ExcerptOptions = {}): string | null {\n return Str.excerpt(this.#value, phrase, options)\n }\n\n /**\n * Explode the string into an array.\n *\n * @param { string } delimiter\n * @param { number } limit\n *\n * @return { string[] }\n */\n explode (delimiter: string, limit: number = 0): string[] {\n return Str.explode(this.#value, delimiter, limit)\n }\n\n /**\n * Split a string using a regular expression or by length.\n *\n * @param { string } pattern\n * @param { number } limit\n *\n * @return { string[] }\n */\n split (pattern: string, limit: number = -1): string[] {\n const body: string = RegExpString.make(/^\\/(.*)\\/\\w*$/, pattern)\n const flags: string = RegExpString.make(/^\\/.*\\/(\\w*)$/, pattern)\n const expression: RegExp = new RegExp(body, flags + (flags.indexOf('g') !== -1 ? '' : 'g'))\n\n let segments: string[] = this.#value.split(expression)\n\n if (limit !== -1) {\n const position: number = limit - 1 >= segments.length\n ? segments.length - 1\n : limit - 1\n\n segments = [...segments.slice(0, position), segments.splice(position).join('')]\n }\n\n return segments.map((segment: string): string => segment.trim()) ?? []\n }\n\n /**\n * Cap a string with a single instance of a given value.\n *\n * @param { string } cap\n *\n * @return { Stringable }\n */\n finish (cap: string): Stringable {\n return new Stringable(Str.finish(this.#value, cap))\n }\n\n /**\n * Determine if a given string matches a given pattern.\n *\n * @param { string | string[] } pattern\n * @param { boolean } ignoreCase\n *\n * @return { boolean }\n */\n is (pattern: string | string[], ignoreCase: boolean = false): boolean {\n return Str.is(pattern, this.#value, ignoreCase)\n }\n\n /**\n * Determine if a given string is 7-bit ASCII.\n *\n * @return { boolean }\n */\n isAscii (): boolean {\n return Str.isAscii(this.#value)\n }\n\n /**\n * Determine if a given string is valid JSON.\n *\n * @return { boolean }\n */\n isJson (): boolean {\n return Str.isJson(this.#value)\n }\n\n /**\n * Determine if a given value is a valid URL.\n *\n * @return { boolean }\n */\n isUrl (): boolean {\n return Str.isUrl(this.#value)\n }\n\n /**\n * Determine if a given string is a valid UUID.\n *\n * @return { boolean }\n */\n isUuid (): boolean {\n return Str.isUuid(this.#value)\n }\n\n /**\n * Determine if a given string is a valid ULID.\n *\n * @return { boolean }\n */\n isUlid (): boolean {\n return Str.isUlid(this.#value)\n }\n\n /**\n * Determine if the given string is empty.\n *\n * @return { boolean }\n */\n isEmpty (): boolean {\n return this.#value.trim() === ''\n }\n\n /**\n * Determine if the given string is not empty.\n *\n * @return { boolean }\n */\n isNotEmpty (): boolean {\n return !this.isEmpty()\n }\n\n /**\n * Convert a string to kebab case.\n *\n * @return { Stringable }\n */\n kebab (): Stringable {\n return new Stringable(Str.kebab(this.#value))\n }\n\n /**\n * Return the length of the given string.\n *\n * @return { number }\n */\n length (): number {\n return Str.length(this.#value)\n }\n\n /**\n * Limit the number of characters in a string.\n *\n * @param { number } limit\n * @param { string } end\n * @param { boolean } preserveWords\n *\n * @return { Stringable }\n */\n limit (limit: number = 100, end: string = '...', preserveWords: boolean = false): Stringable {\n return new Stringable(Str.limit(this.#value, limit, end, preserveWords))\n }\n\n /**\n * Get substring by start/stop indexes.\n * \n * @param start \n * @param stop \n * @returns \n */\n sub (start: number, stop: number): Stringable {\n return new Stringable(Str.sub(this.#value, start, stop))\n }\n\n /**\n * Limit the number of characters in a string.\n *\n * @param { number } limit\n * @param { string } end\n * @param { boolean } preserveWords\n * \n * @alias limit\n *\n * @return { Stringable }\n */\n truncate (\n limit: number = 100, end: string = '...', preserveWords: boolean = false\n ): Stringable {\n return new Stringable(Str.limit(this.#value, limit, end, preserveWords))\n }\n\n /**\n * Convert the given string to lower-case.\n *\n * @return { Stringable }\n */\n lower (): Stringable {\n return new Stringable(Str.lower(this.#value))\n }\n\n /**\n * Masks a portion of a string with a repeated character.\n *\n * @param { string } character\n * @param { number } index\n * @param { number | null }length\n *\n * @return { Stringable }\n */\n mask (character: string, index: number, length: number | null = null): Stringable {\n return new Stringable(Str.mask(this.#value, character, index, length))\n }\n\n /**\n * Get the string matching the given pattern.\n *\n * @param { string } pattern\n *\n * @return { Stringable }\n */\n match (pattern: string): Stringable {\n return new Stringable(Str.match(pattern, this.#value))\n }\n\n /**\n * Determine if a given string matches a given pattern.\n *\n * @param { string | string[] } pattern\n *\n * @return { boolean }\n */\n isMatch (...pattern: string[]): boolean {\n return Str.isMatch(pattern, this.#value)\n }\n\n /**\n * Get the string matching the given pattern.\n *\n * @param { string } pattern\n *\n * @return { string[] }\n */\n matchAll (pattern: string): string[] {\n return Str.matchAll(pattern, this.#value)\n }\n\n /**\n * Determine if the string matches the given pattern.\n *\n * @param { string } pattern\n *\n * @return { boolean }\n */\n test (pattern: string): boolean {\n return this.match(pattern).isNotEmpty()\n }\n\n /**\n * Remove all non-numeric characters from a string.\n *\n * @return { Stringable }\n */\n numbers (): Stringable {\n return new Stringable(Str.numbers(this.#value))\n }\n\n /**\n * Pad both sides of the string with another.\n *\n * @param { number } length\n * @param { string } pad\n *\n * @return { Stringable }\n */\n padBoth (length: number, pad: string = ' '): Stringable {\n return new Stringable(Str.padBoth(this.#value, length, pad))\n }\n\n /**\n * Pad the left side of the string with another.\n *\n * @param { number } length\n * @param { string } pad\n *\n * @return { Stringable }\n */\n padLeft (length: number, pad: string = ' '): Stringable {\n return new Stringable(Str.padLeft(this.#value, length, pad))\n }\n\n /**\n * Pad the right side of the string with another.\n *\n * @param { number } length\n * @param { string } pad\n *\n * @return { Stringable }\n */\n padRight (length: number, pad: string = ' '): Stringable {\n return new Stringable(Str.padRight(this.#value, length, pad))\n }\n\n /**\n * Call the given callback and return a new string.\n *\n * @param { keyof string | ((instance: this) => any) } callback\n *\n * @return { Stringable }\n */\n pipe (callback: keyof string | ((instance: this) => any)): Stringable {\n if (typeof callback === 'string') {\n if ((this.#value as any)[callback] instanceof Function) {\n return new Stringable((this.#value as any)[callback]())\n }\n }\n\n return new Stringable((callback as (instance: this) => any)(this).toString())\n }\n\n /**\n * Get the plural form of an English word.\n *\n * @param { number } count\n *\n * @return { Stringable }\n */\n plural (count: number = 2): Stringable {\n return new Stringable(Str.plural(this.#value, count))\n }\n\n /**\n * Pluralize the last word of an English, studly caps case string.\n *\n * @param { number } count\n *\n * @return { Stringable }\n */\n pluralStudly (count: number = 2): Stringable {\n return new Stringable(Str.pluralStudly(this.#value, count))\n }\n\n /**\n * Pluralize the last word of an English, Pascal case string.\n *\n * @param { number } count\n *\n * @return { Stringable }\n */\n pluralPascal (count: number = 2): Stringable {\n return new Stringable(Str.pluralPascal(this.#value, count))\n }\n\n /**\n * Find the multibyte safe position of the first occurrence of the given substring.\n *\n * @param { string } needle\n * @param { number } offset\n *\n * @return { number | false }\n */\n position (needle: string, offset: number = 0): number | false {\n return Str.position(this.#value, needle, offset)\n }\n\n /**\n * Prepend the given values to the string.\n *\n * @param { string | string[] } values\n *\n * @return { Stringable }\n */\n prepend (...values: string[]): Stringable {\n return new Stringable(values.join('') + this.#value)\n }\n\n /**\n * Remove any occurrence of the given string in the subject.\n *\n * @param { string } search\n * @param { boolean } caseSensitive\n *\n * @return { Stringable }\n */\n remove (search: string, caseSensitive: boolean = true): Stringable {\n return new Stringable(Str.remove(search, this.#value, caseSensitive))\n }\n\n /**\n * Reverse the string.\n *\n * @return { Stringable }\n */\n reverse (): Stringable {\n return new Stringable(Str.reverse(this.#value))\n }\n\n /**\n * Substitute placeholders { key } using object with dot notation.\n * \n * @param data \n * @param def \n * @returns \n */\n substitute (data: Record<string, unknown> = {}, def?: string): Stringable {\n return new Stringable(Str.substitute(this.#value, data, def))\n }\n\n /**\n * Repeat the string.\n *\n * @param { number } times\n *\n * @return { Stringable }\n */\n repeat (times: number): Stringable {\n return new Stringable(Str.repeat(this.#value, times))\n }\n\n /**\n * Replace the given value in the given string.\n *\n * @param { string | string[] } search\n * @param { string } replace\n * @param { boolean } caseSensitive\n *\n * @return { Stringable }\n */\n replace (search: string | string[], replace: string, caseSensitive: boolean = true): Stringable {\n return new Stringable(Str.replace(search, replace, this.#value, caseSensitive))\n }\n\n /**\n * Replace a given value in the string sequentially with an array.\n *\n * @param { string } search\n * @param { string[] } replace\n *\n * @return { Stringable }\n */\n replaceArray (search: string, replace: string[]): Stringable {\n return new Stringable(Str.replaceArray(search, replace, this.#value))\n }\n\n /**\n * Replace the first occurrence of a given value in the string.\n *\n * @param { string } search\n * @param { string } replace\n *\n * @return { Stringable }\n */\n replaceFirst (search: string, replace: string): Stringable {\n return new Stringable(Str.replaceFirst(search, replace, this.#value))\n }\n\n /**\n * Replace the first occurrence of the given value if it appears at the start of the string.\n *\n * @param { string } search\n * @param { string } replace\n *\n * @return { Stringable }\n */\n replaceStart (search: string, replace: string): Stringable {\n return new Stringable(Str.replaceStart(search, replace, this.#value))\n }\n\n /**\n * Replace the last occurrence of a given value in the string.\n *\n * @param { string } search\n * @param { string } replace\n *\n * @return { Stringable }\n */\n replaceLast (search: string, replace: string): Stringable {\n return new Stringable(Str.replaceLast(search, replace, this.#value))\n }\n\n /**\n * Replace the last occurrence of a given value if it appears at the end of the string.\n *\n * @param { string } search\n * @param { string } replace\n *\n * @return { Stringable }\n */\n replaceEnd (search: string, replace: string): Stringable {\n return new Stringable(Str.replaceEnd(search, replace, this.#value))\n }\n\n /**\n * Replace the patterns matching the given regular expression.\n *\n * @param { string } pattern\n * @param { string | function } replace\n *\n * @return { Stringable }\n */\n replaceMatches (pattern: string, replace: string | Function): Stringable {\n const body: string = RegExpString.make(/^\\/(.*)\\/\\w*$/, pattern)\n const flags: string = RegExpString.make(/^\\/.*\\/(\\w*)$/, pattern)\n const expression: RegExp = new RegExp(body, flags + (flags.indexOf('g') !== -1 ? '' : 'g'))\n\n if (replace instanceof Function) {\n this.#value.replace(expression, (matched: string): string => matched)\n }\n\n return new Stringable(this.#value.replace(expression, (replace as string)))\n }\n\n /**\n * Remove all \"extra\" blank space from the given string.\n *\n * @return { Stringable }\n */\n squish (): Stringable {\n return new Stringable(Str.squish(this.#value))\n }\n\n /**\n * Begin a string with a single instance of a given value.\n *\n * @param { string } prefix\n *\n * @return { Stringable }\n */\n start (prefix: string): Stringable {\n return new Stringable(Str.start(this.#value, prefix))\n }\n\n /**\n * Convert the given string to upper-case.\n *\n * @return { Stringable }\n */\n upper (): Stringable {\n return new Stringable(Str.upper(this.#value))\n }\n\n /**\n * Convert the given string to title case.\n *\n * @return { Stringable }\n */\n title (): Stringable {\n return new Stringable(Str.title(this.#value))\n }\n\n /**\n * Convert the given string to title case for each word.\n *\n * @return { Stringable }\n */\n headline (): Stringable {\n return new Stringable(Str.headline(this.#value))\n }\n\n /**\n * Convert the given string to APA-style title case.\n *\n * @see https://apastyle.apa.org/style-grammar-guidelines/capitalization/title-case\n *\n * @return { Stringable }\n */\n apa (): Stringable {\n return new Stringable(Str.apa(this.#value))\n }\n\n /**\n * Get the singular form of an English word.\n *\n * @return { Stringable }\n */\n singular (): Stringable {\n return new Stringable(Str.singular(this.#value))\n }\n\n /**\n * Generate a URL friendly \"slug\" from a given string.\n *\n * @param { string } separator\n * @param { object } dictionary\n *\n * @return { Stringable }\n */\n slug (separator: string = '-', dictionary: { [key: string]: string } = { '@': 'at' }): Stringable {\n return new Stringable(Str.slug(this.#value, separator, dictionary))\n }\n\n /**\n * Convert a string to snake case.\n *\n * @param { string } delimiter\n *\n * @return { Stringable }\n */\n snake (delimiter: string = '_'): Stringable {\n return new Stringable(Str.snake(this.#value, delimiter))\n }\n\n /**\n * Determine if a given string starts with a given substring.\n *\n * @param { string | string[] } needles\n *\n * @return { boolean }\n */\n startsWith (needles: string | string[]): boolean {\n return Str.startsWith(this.#value, needles)\n }\n\n /**\n * Determine if a given string doesn't start with a given substring.\n *\n * @param { string | string[] } needles\n *\n * @return { boolean }\n */\n doesntStartWith (needles: string | string[]): boolean {\n return Str.doesntStartWith(this.#value, needles)\n }\n\n /**\n * Convert a value to studly caps case.\n *\n * @return { Stringable }\n */\n studly (): Stringable {\n return new Stringable(Str.studly(this.#value))\n }\n\n /**\n * Convert a value to Pascal case.\n *\n * @return { Stringable }\n */\n pascal (): Stringable {\n return new Stringable(Str.pascal(this.#value))\n }\n\n /**\n * Returns the portion of the string specified by the start and length parameters.\n *\n * @param { number } start\n * @param { number | null } length\n *\n * @return { Stringable }\n */\n substr (start: number, length: number | null = null): Stringable {\n return new Stringable(Str.substr(this.#value, start, length))\n }\n\n /**\n * Returns the number of substring occurrences.\n *\n * @param { string } needle\n * @param { number } offset\n * @param { number | null } length\n *\n * @return { number }\n */\n substrCount (needle: string, offset: number = 0, length: number | null = null): number {\n return Str.substrCount(this.#value, needle, offset, length)\n }\n\n /**\n * Replace text within a portion of a string.\n *\n * @param { string } replace\n * @param { number } offset\n * @param { number | null } length\n *\n * @return { Stringable }\n */\n substrReplace (replace: string, offset: number = 0, length: number | null = null): Stringable {\n return new Stringable(Str.substrReplace(this.#value, replace, offset, length))\n }\n\n /**\n * Swap multiple keywords in a string with other keywords.\n *\n * @param { Record<string, string> } map\n *\n * @return { Stringable }\n */\n swap (map: Record<string, string>): Stringable {\n return new Stringable(Str.swap(map, this.#value))\n }\n\n /**\n * Take the first or last {limit} characters.\n *\n * @param { number } limit\n *\n * @return { Stringable }\n */\n take (limit: number): Stringable {\n if (limit < 0) {\n return this.substr(limit)\n }\n\n return this.substr(0, limit)\n }\n\n /**\n * Call the given Closure with this instance then return the instance.\n *\n * @param { ((instance: this) => any) } callback\n *\n * @return { Stringable }\n */\n tap (callback: ((instance: this) => any)): this {\n callback(this)\n\n return this\n }\n\n /**\n * Trim the string of the given characters.\n *\n * @param { string | null } characters\n *\n * @return { Stringable }\n */\n trim (characters: string | null = null): Stringable {\n return new Stringable(Str.trim(this.#value, characters))\n }\n\n /**\n * Left trim the string of the given characters.\n *\n * @param { string | string[]|null } characters\n *\n * @return { Stringable }\n */\n ltrim (characters: string | null = null): Stringable {\n return new Stringable(Str.ltrim(this.#value, characters))\n }\n\n /**\n * Right trim the string of the given characters.\n *\n * @param { string | string[]|null } characters\n *\n * @return { Stringable }\n */\n rtrim (characters: string | null = null): Stringable {\n return new Stringable(Str.rtrim(this.#value, characters))\n }\n\n /**\n * Make a string's first character lowercase.\n *\n * @return { Stringable }\n */\n lcfirst (): Stringable {\n return new Stringable(Str.lcfirst(this.#value))\n }\n\n /**\n * Make a string's first character uppercase.\n *\n * @return { Stringable }\n */\n ucfirst (): Stringable {\n return new Stringable(Str.ucfirst(this.#value))\n }\n\n /**\n * Split a string by uppercase characters.\n *\n * @return { string[] }\n */\n ucsplit (): string[] {\n return Str.ucsplit(this.#value)\n }\n\n /**\n * Apply the callback if the given \"value\" is (or resolves to) truthy.\n *\n * @param { Value<this> } value\n * @param { Callback<this> } callback\n * @param { Fallback<this> } fallback\n *\n * @return { Stringable }\n */\n when (value: Value<this>, callback: Callback<this>, fallback: Fallback<this> = null): this {\n value = value instanceof Function ? value(this) : value\n\n if (value) {\n return callback(this, value) ?? this\n } else if (fallback) {\n return fallback(this, value) ?? this\n }\n\n return this\n }\n\n /**\n * Apply the callback if the given \"value\" is (or resolves to) falsy.\n *\n * @param { Value<this> } value\n * @param { Callback<this> } callback\n * @param { Fallback<this> } fallback\n *\n * @return { this }\n */\n unless (value: Value<this>, callback: Callback<this>, fallback: Fallback<this> = null): this {\n value = value instanceof Function ? value(this) : value\n\n if (!value) {\n return callback(this, value) ?? this\n } else if (fallback) {\n return fallback(this, value) ?? this\n }\n\n return this\n }\n\n /**\n * Execute the given callback if the string contains a given substring.\n *\n * @param { string | string[] } needles\n * @param { Callback<this> } callback\n * @param { Fallback<this> } fallback\n *\n * @return { this }\n */\n whenContains (needles: string | string[], callback: Callback<this>, fallback: Fallback<this> = null): this {\n return this.when(this.contains(needles), callback, fallback)\n }\n\n /**\n * Execute the given callback if the string contains all array values.\n *\n * @param { string[] } needles\n * @param { Callback<this> } callback\n * @param { Fallback<this> } fallback\n *\n * @return { this }\n */\n whenContainsAll (needles: string[], callback: Callback<this>, fallback: Fallback<this> = null): this {\n return this.when(this.containsAll(needles), callback, fallback)\n }\n\n /**\n * Execute the given callback if the string is empty.\n *\n * @param { Callback<this> } callback\n * @param { Fallback<this> } fallback\n *\n * @return { this }\n */\n whenEmpty (callback: Callback<this>, fallback: Fallback<this> = null): this {\n return this.when(this.isEmpty(), callback, fallback)\n }\n\n /**\n * Execute the given callback if the string is not empty.\n *\n * @param { Callback<this> } callback\n * @param { Fallback<this> } fallback\n *\n * @return { this }\n */\n whenNotEmpty (callback: Callback<this>, fallback: Fallback<this> = null): this {\n return this.when(this.isNotEmpty(), callback, fallback)\n }\n\n /**\n * Execute the given callback if the string ends with a given substring.\n *\n * @param { string | string[] } needles\n * @param { Callback<this> } callback\n * @param { Fallback<this> } fallback\n *\n * @return { this }\n */\n whenEndsWith (needles: string | string[], callback: Callback<this>, fallback: Fallback<this> = null): this {\n return this.when(this.endsWith(needles), callback, fallback)\n }\n\n /**\n * Execute the given callback if the string doesn't end with a given substring.\n *\n * @param { string | string[] } needles\n * @param { Callback<this> } callback\n * @param { Fallback<this> } fallback\n *\n * @return { this }\n */\n whenDoesntEndWith (needles: string | string[], callback: Callback<this>, fallback: Fallback<this> = null): this {\n return this.when(this.doesntEndWith(needles), callback, fallback)\n }\n\n /**\n * Execute the given callback if the string is an exact match with the given value.\n *\n * @param { string } value\n * @param { Callback<this> } callback\n * @param { Fallback<this> } fallback\n *\n * @return { this }\n */\n whenExactly (value: string, callback: Callback<this>, fallback: Fallback<this> = null): this {\n return this.when(this.exactly(value), callback, fallback)\n }\n\n /**\n * Execute the given callback if the string is not an exact match with the given value.\n *\n * @param { string } value\n * @param { Callback<this> } callback\n * @param { Fallback<this> } fallback\n *\n * @return { this }\n */\n whenNotExactly (value: string, callback: Callback<this>, fallback: Fallback<this> = null): this {\n return this.when(!this.exactly(value), callback, fallback)\n }\n\n /**\n * Execute the given callback if the string matches a given pattern.\n *\n * @param { string | string[] } pattern\n * @param { Callback<this> } callback\n * @param { Fallback<this> } fallback\n *\n * @return { this }\n */\n whenIs (pattern: string | string[], callback: Callback<this>, fallback: Fallback<this> = null): this {\n return this.when(this.is(pattern), callback, fallback)\n }\n\n /**\n * Execute the given callback if the string is 7-bit ASCII.\n *\n * @param { Callback<this> } callback\n * @param { Fallback<this> } fallback\n *\n * @return { this }\n */\n whenIsAscii (callback: Callback<this>, fallback: Fallback<this> = null): this {\n return this.when(this.isAscii(), callback, fallback)\n }\n\n /**\n * Execute the given callback if the string is a valid UUID.\n *\n * @param { Callback<this> } callback\n * @param { Fallback<this> } fallback\n *\n * @return { this }\n */\n whenIsUuid (callback: Callback<this>, fallback: Fallback<this> = null): this {\n return this.when(this.isUuid(), callback, fallback)\n }\n\n /**\n * Execute the given callback if the string is a valid ULID.\n *\n * @param { Callback<this> } callback\n * @param { Fallback<this> } fallback\n *\n * @return { this }\n */\n whenIsUlid (callback: Callback<this>, fallback: Fallback<this> = null): this {\n return this.when(this.isUlid(), callback, fallback)\n }\n\n /**\n * Execute the given callback if the string starts with a given substring.\n *\n * @param { string | string[] } needles\n * @param { Callback<this> } callback\n * @param { Fallback<this> } fallback\n *\n * @return { this }\n */\n whenStartsWith (needles: string | string[], callback: Callback<this>, fallback: Fallback<this> = null): this {\n return this.when(this.startsWith(needles), callback, fallback)\n }\n\n /**\n * Execute the given callback if the string doesn't start with a given substring.\n *\n * @param { string | string[] } needles\n * @param { Callback<this> } callback\n * @param { Fallback<this> } fallback\n *\n * @return { this }\n */\n whenDoesntStartWith (needles: string | string[], callback: Callback<this>, fallback: Fallback<this> = null): this {\n return this.when(this.doesntStartWith(needles), callback, fallback)\n }\n\n /**\n * Execute the given callback if the string matches the given pattern.\n *\n * @param { string } pattern\n * @param { Callback<this> } callback\n * @param { Fallback<this> } fallback\n *\n * @return { this }\n */\n whenTest (pattern: string, callback: Callback<this>, fallback: Fallback<this> = null): this {\n return this.when(this.test(pattern), callback, fallback)\n }\n\n /**\n * Limit the number of words in a string.\n *\n * @param { number } words\n * @param { string } end\n *\n * @return { Stringable }\n */\n words (words: number = 100, end: string = '...'): Stringable {\n return new Stringable(Str.words(this.#value, words, end))\n }\n\n /**\n * Get the number of words a string contains.\n *\n * @return { number }\n */\n wordCount (): number {\n return Str.wordCount(this.#value)\n }\n\n /**\n * Wrap a string to a given number of characters.\n *\n * @param { number } characters\n * @param { string } breakStr\n * @param { boolean } cutLongWords\n *\n * @returns { this }\n */\n wordWrap (characters: number = 75, breakStr: string = '\\n', cutLongWords: boolean = false): Stringable {\n return new Stringable(Str.wordWrap(this.#value, characters, breakStr, cutLongWords))\n }\n\n /**\n * Wrap the string with the given strings.\n *\n * @param { string } before\n * @param { string | null } after\n *\n * @return { Stringable }\n */\n wrap (before: string, after: string | null = null): Stringable {\n return new Stringable(Str.wrap(this.#value, before, after))\n }\n\n /**\n * Unwrap the string with the given strings.\n *\n * @param { string } before\n * @param { string | null } after\n *\n * @return { Stringable }\n */\n unwrap (before: string, after: string | null = null): Stringable {\n return new Stringable(Str.unwrap(this.#value, before, after))\n }\n\n /**\n * Convert the string into a `HtmlString` instance.\n *\n * @return { HtmlStringType }\n */\n toHtmlString (): HtmlStringType {\n return new HtmlString(this.#value).toHtml()\n }\n\n /**\n * Convert the string to Base64 encoding.\n *\n * @return { Stringable }\n */\n toBase64 (): Stringable {\n return new Stringable(Str.toBase64(this.#value))\n }\n\n /**\n * Decode the Base64 encoded string.\n *\n * @return { Stringable }\n */\n fromBase64 (): Stringable {\n return new Stringable(Str.fromBase64(this.#value))\n }\n\n /**\n * Checks if a string is numeric\n * \n * @return { boolean }\n */\n isNumber (): boolean {\n return Str.isNumber(this.#value)\n }\n\n /**\n * Checks if a string is an integer\n * \n * @return { boolean }\n */\n isInteger (): boolean {\n return Str.isInteger(this.#value)\n }\n\n /**\n * ROT-N cipher.\n * \n * @param n \n * @returns \n */\n rot (n: number = 13): Stringable {\n return new Stringable(Str.rot(this.#value, n))\n }\n\n /**\n * Replace trailing punctuation with new format.\n * \n * @param newFormat \n * @returns \n */\n replacePunctuation (newFormat: string): Stringable {\n return new Stringable(Str.replacePunctuation(this.#value, newFormat))\n }\n\n /**\n * Array/object driven text replacement.\n * \n * @param replacements \n * @returns \n */\n translate (replacements: Record<string, string> | Array<[string, string]>): Stringable {\n return new Stringable(Str.translate(this.#value, replacements))\n }\n\n /**\n * Strip slashes recursively.\n * \n * @returns \n */\n ss (): Stringable {\n return new Stringable(Str.ss(this.#value))\n }\n\n /**\n * First and last N lines.\n * \n * @param amount \n * @returns \n */\n firstLines (amount: number = 1): Stringable {\n return new Stringable(Str.firstLines(this.#value, amount))\n }\n\n /**\n * Last and first N lines.\n * \n * @param amount \n * @returns \n */\n lastLines (amount: number = 1): Stringable {\n return new Stringable(Str.lastLines(this.#value, amount))\n }\n\n /**\n * Dump the string.\n *\n * @return { void }\n */\n dump (): void {\n console.log(this.#value)\n }\n\n /**\n * Dump the string and end the script.\n *\n * @return { never }\n */\n dd (): never {\n this.dump()\n\n throw new Error('dd()')\n }\n\n /**\n * Get the underlying string value.\n *\n * @return { string }\n */\n value (): string {\n return this.toString()\n }\n\n /**\n * Get the raw string value.\n *\n * @return { string }\n */\n toString (): string {\n return this.#value\n }\n\n /**\n * Get the underlying string value as an integer.\n *\n * @param { number } base\n *\n * @return { number }\n */\n toInteger (base: number = 10): number {\n const value: number = parseInt(this.#value, base)\n\n return isNaN(value) || !isFinite(value) ? 0 : value\n }\n\n /**\n * Get the underlying string value as a float.\n *\n * @return { number }\n */\n toFloat (): number {\n return !isNaN(parseFloat(this.#value)) ? parseFloat(this.#value) : 0\n }\n\n /**\n * Get the underlying string value as a boolean.\n *\n * Returns true when value is \"1\", \"true\", \"on\", and \"yes\". Otherwise, returns false.\n *\n * @return { boolean }\n */\n toBoolean (): boolean {\n switch (this.#value) {\n case '1':\n case 'true':\n case 'on':\n case 'yes':\n return true\n default:\n return false\n }\n }\n\n /**\n * Get the underlying string value as a formatted Date string.\n *\n * @param { string | null } format\n * @param { string | null } tz\n */\n toDate (format: string | null = null, tz: string | null = null): string {\n if (new Date(this.#value).toString() === 'Invalid Date') {\n return 'Invalid Date'\n }\n\n if (format === null) {\n return new Date(this.#value).toLocaleDateString('en-us', {\n year: 'numeric',\n month: 'numeric',\n day: 'numeric',\n hour: 'numeric',\n minute: 'numeric',\n second: 'numeric',\n hour12: false,\n timeZone: tz ?? undefined,\n })\n }\n\n let date: string = ''\n\n const now: Date = new Date(new Date(this.#value).toLocaleString('en-US', {\n year: 'numeric',\n month: 'numeric',\n day: 'numeric',\n hour: 'numeric',\n minute: 'numeric',\n second: 'numeric',\n fractionalSecondDigits: 3,\n hour12: false,\n timeZone: tz ?? undefined,\n }))\n\n const month: number = now.getMonth()\n const dayOfTheWeek: number = now.getDay()\n const dayOfTheMonth: number = now.getDate()\n const year: number = now.getFullYear()\n const hours: number = now.getHours()\n const minutes: number = now.getMinutes()\n const seconds: number = now.getSeconds()\n const milliseconds: number = now.getMilliseconds()\n\n const elements: RegExpMatchArray | null = format.match(/\\\\?.|./g)\n\n for (const element of elements!) {\n switch (element) {\n // Day of the month, 2 digits with leading zeros (e.g., 01 to 31)\n case 'd':\n date += Str.padLeft(dayOfTheMonth.toString(), 2, '0')\n\n break\n\n // A textual representation of a day, three letters (e.g., Mon through Sun)\n case 'D':\n date += now.toLocaleString('en-US', { weekday: 'short' })\n\n break\n\n // Day of the month without leading zeros (e.g., 1 to 31)\n case 'j':\n date += dayOfTheMonth\n\n break\n\n // A full textual representation of the day of the week (e.g., Sunday through Saturday)\n case 'l':\n date += now.toLocaleString('en-US', { weekday: 'long' })\n\n break\n\n // ISO 8601 numeric representation of the day of the week (e.g., 1 (for Monday) through 7 (for Sunday))\n case 'N':\n date += dayOfTheWeek !== 0 ? dayOfTheWeek : 0\n\n break\n\n // English ordinal suffix for the day of the month, 2 characters (e.g., st, nd, rd or th)\n case 'S': {\n const suffix: { [key: number]: string } = {\n 1: 'st',\n 2: 'nd',\n 3: 'rd',\n 21: 'st',\n 22: 'nd',\n 23: 'rd',\n 31: 'st'\n }\n date += suffix[dayOfTheMonth] ?? 'th'\n\n break\n }\n // Numeric representation of the day of the week (e.g., 0 (for Sunday) through 6 (for Saturday))\n case 'w':\n date += dayOfTheWeek\n\n break\n\n // Numeric representation of the day of the week (e.g., The day of the year (starting from 0))\n case 'z': {\n const start: Date = new Date(year, 0, 0)\n const diff: number = ((now as unknown as number) - (start as unknown as number)) + ((start.getTimezoneOffset() - now.getTimezoneOffset()) * 60 * 1000)\n const day: number = 86400000\n const currentDay: number = Math.floor(diff / day)\n\n date += currentDay\n\n break\n }\n // ISO 8601 week number of year, weeks starting on Monday (e.g., 42 (the 42nd week in the year))\n case 'W': {\n const parsedDate: Date = new Date(Date.UTC(year, month, dayOfTheMonth))\n const weekDay: number = parsedDate.getUTCDay() || 7\n\n parsedDate.setUTCDate(parsedDate.getUTCDate() + 4 - weekDay)\n\n const yearStart: Date = new Date(Date.UTC(parsedDate.getUTCFullYear(), 0, 1))\n const weekNumber: number = Math.ceil(((((parsedDate as unknown as number) - (yearStart as unknown as number)) / 86400000) + 1) / 7)\n\n date += Str.padLeft((weekNumber.toString()), 2, '0')\n\n break\n }\n // A full textual representation of a month, such as January or March (e.g., January through December)\n case 'F':\n date += now.toLocaleString('en-US', { month: 'long' })\n\n break\n\n // Numeric representation of a month, with leading zeros (e.g., 01 through 12)\n case 'm': {\n const currentMonth: number = month + 1\n\n date += Str.padLeft(currentMonth.toString(), 2, '0')\n\n break\n }\n // A short textual representation of a month, three letters (e.g., Jan through Dec)\n case 'M':\n date += now.toLocaleString('en-US', { month: 'short' })\n\n break\n\n // Numeric representation of a month, without leading zeros (e.g., 1 through 12)\n case 'n':\n date += month + 1\n\n break\n\n // Number of days in the given month (e.g., 28 through 31)\n case 't':\n date += new Date(year, month + 1, 0).getDate()\n\n break\n\n // Whether it's a leap year (e.g., 1 if it is a leap year, 0 otherwise)\n case 'L':\n date += new Date(year, 1, 29).getMonth() === 1 ? '1' : '0'\n\n break\n\n // ISO 8601 week-numbering year. This has the same value as Y,\n // except that if the ISO week number (W) belongs to the previous or next year,\n // that year is used instead. (e.g., 1999 or 2003)\n case 'o':\n date += now.toISOString().substring(0, 4)\n\n break\n\n // An expanded full numeric representation of a year, at least 4 digits, with - for years BCE, and + for years CE. (e.g., -0055, +0787, +1999, +10191)\n case 'X':\n date += year < 0 ? '-' + year : '+' + year\n\n break\n\n // An expanded full numeric representation if required,\n // or a standard full numeral representation if possible (like Y).\n // At least four digits. Years BCE are prefixed with a -.\n // Years beyond (and including) 10000 are prefixed by a +. (e.g., -0055, 0787, 1999, +10191)\n case 'x':\n date += year < 10000 ? year : '-' + year\n\n break\n\n // A full numeric representation of a year, at least 4 digits, with - for years BCE. (e.g., -0055, 0787, 1999, 2003, 10191)\n case 'Y':\n date += year\n\n break\n\n // A two-digit representation of a year (e.g., 99 or 03)\n case 'y':\n date += year.toString().substring(2)\n\n break\n\n // Lowercase Ante meridiem and Post meridiem (e.g., am or pm)\n case 'a':\n date += hours < 12 ? 'am' : 'pm'\n\n break\n\n // Uppercase Ante meridiem and Post meridiem (e.g., AM or PM)\n case 'A':\n date += hours < 12 ? 'AM' : 'PM'\n\n break\n\n // Swatch Internet time (e.g., 000 through 999)\n case 'B': {\n const hours: number = now.getUTCHours()\n const minutes: number = now.getUTCMinutes()\n const seconds: number = now.getUTCSeconds()\n\n date += Math.floor((((hours + 1) % 24) + minutes / 60 + seconds / 3600) * 1000 / 24)\n\n break\n }\n // 12-hour format of an hour without leading zeros (e.g., 1 through 12)\n case 'g':\n date += hours > 12 ? hours - 12 : hours\n\n break\n\n // 24-hour format of an hour without leading zeros (e.g., 0 through 23)\n case 'G':\n date += hours\n\n break\n\n // 12-hour format of an hour with leading zeros (e.g., 01 through 12)\n case 'h':\n date += Str.padLeft((hours > 12 ? hours - 12 : hours).toString(), 2, '0')\n\n break\n\n // 24-hour format of an hour with leading zeros (e.g., 00 through 23)\n case 'H':\n date += Str.padLeft(hours.toString(), 2, '0')\n\n break\n\n // Minutes with leading zeros (e.g., 00 to 59)\n case 'i':\n date += Str.padLeft(minutes.toString(), 2, '0')\n\n break\n\n // Seconds with leading zeros (e.g., 00 to 59)\n case 's':\n date += Str.padLeft(seconds.toString(), 2, '0')\n\n break\n\n // Microseconds. (e.g., 654321)\n case 'u':\n throw new Error('Microseconds are not supported.')\n\n // Milliseconds. (e.g., 654)\n case 'v': {\n date += Str.padLeft(milliseconds.toString(), 3, '0')\n\n break\n }\n\n // Timezone identifier (e.g., UTC, GMT, Atlantic/Azores)\n case 'e': {\n date += Intl.DateTimeFormat('en-us', { timeZone: tz ?? undefined }).resolvedOptions().timeZone\n\n break\n }\n\n // Whether the date is in daylight saving time (e.g., 1 if Daylight Saving Time, 0 otherwise)\n case 'I': {\n const january: number = new Date(year, 0, 1).getTimezoneOffset()\n const july: number = new Date(year, 6, 1).getTimezoneOffset()\n\n date += Math.max(january, july) !== now.getTimezoneOffset() ? '1' : '0'\n\n break\n }\n // Difference to Greenwich time (GMT) without colon between hours and minutes (e.g., +0200)\n case 'O': {\n const timeZoneData: string = now.toLocaleDateString('en-us', {\n timeZoneName: 'longOffset',\n timeZone: tz ?? undefined,\n })\n .split(', ')\n .pop()!\n .trim()\n\n date += timeZoneData.length !== 3 ? timeZoneData.substring(3).replace(':', '') : '+0000'\n\n break\n }\n\n // Difference to Greenwich time (GMT) with colon between hours and minutes (e.g., +02:00)\n case 'P': {\n const timeZoneData: string = now.toLocaleDateString('en-us', {\n timeZoneName: 'longOffset',\n timeZone: tz ?? undefined,\n })\n .split(', ')\n .pop()!\n .trim()\n\n date += timeZoneData.length !== 3 ? timeZoneData.substring(3) : '+00:00'\n\n break\n }\n\n // The same as P, but returns Z instead of +00:00 (e.g., +02:00)\n case 'p': {\n const timeZoneData: string = now.toLocaleDateString('en-us', {\n timeZoneName: 'longOffset',\n timeZone: tz ?? undefined,\n })\n .split(', ')\n .pop()!\n .trim()\n\n date += timeZoneData === 'GMT' ? 'Z' : timeZoneData.substring(3)\n\n break\n }\n\n // Timezone abbreviation, if known; otherwise the GMT offset (e.g., EST, MDT, +05)\n case 'T': {\n const timeZoneData: string = now.toLocaleDateString('en-us', {\n timeZoneName: 'short',\n timeZone: tz ?? undefined,\n })\n .split(', ')\n .pop()!\n .trim()\n\n date += tz ?? timeZoneData.replace('GMT', 'UTC').split(/[+-]/)[0]\n\n break\n }\n\n // Timezone offset in seconds.\n // The offset for timezones west of UTC is always negative,\n // and for those east of UTC is always positive. (e.g., -43200 through 50400)\n case 'Z': {\n const timezone: string = now.toLocaleDateString('en-us', {\n timeZoneName: 'longOffset',\n timeZone: tz ?? undefined\n })\n const symbol: RegExpMatchArray | null = timezone.match(/[+-]/)\n const data: string[] = timezone.split(/[+-]/)\n\n const sign: string = symbol ? symbol.pop()! : '+'\n const offset: string = data.length === 2 ? (data[1] as string) : '0:00'\n\n const hours: number = parseInt(offset.split(':')[0] as string)\n const minutes: number = parseInt(offset.split(':')[1] as string)\n\n const offsetInSeconds: number = hours * 3600 + minutes * 60\n\n date += `${sign}${offsetInSeconds}`\n\n break\n }\n\n // ISO 8601 date (e.g., 2004-02-12T15:19:21+00:00)\n case 'c': {\n date += `${this.toDate('Y-m-d\\\\TH:i:sP')}`\n\n break\n }\n // RFC 2822/RFC 5322 formatted date (e.g., Thu, 21 Dec 2000 16:01:07 +0200)\n case 'r': {\n date += new Stringable(this.#value).toDate('D, d M Y H:i:s O', tz)\n\n break\n }\n\n // Seconds since the Unix Epoch (e.g., January 1, 1970 00:00:00 GMT)\n case 'U': {\n date += Math.floor(now.getTime() / 1000)\n\n break\n }\n\n default:\n date += element.length >= 2 && element.indexOf('\\\\') > -1 ? element.replace('\\\\', '') : element\n }\n }\n\n return date\n }\n}\n\nexport class HtmlString {\n /**\n * The HTML string.\n *\n * @type { string }\n */\n private readonly html: string\n\n /**\n * Create a new HTML string instance.\n *\n * @param { string } html\n *\n * @return void\n */\n constructor(html: string = '') {\n this.html = html\n }\n\n /**\n * Get the HTML string.\n *\n * @return { HtmlStringType }\n */\n toHtml (): HtmlStringType {\n const pattern: RegExp = /(?!<!DOCTYPE)<([^\\s>]+)(\\s|>)+/\n const tag: RegExpExecArray | null = RegExp(pattern).exec(this.html)\n\n if (tag === null) {\n return this.html\n }\n\n const DOM: HTMLElement = document.createElement(tag[1] as string)\n\n DOM.innerHTML = this.html\n\n return tag[1] === 'html' ? DOM : DOM.firstChild as HtmlStringType\n }\n\n /**\n * Determine if the given HTML string is empty.\n *\n * @return { boolean }\n */\n isEmpty (): boolean {\n return this.html === ''\n }\n\n /**\n * Determine if the given HTML string is not empty.\n *\n * @return { boolean }\n */\n isNotEmpty (): boolean {\n return !this.isEmpty()\n }\n\n /**\n * Get the HTML string.\n *\n * @return { string }\n */\n toString (): string {\n const html: HtmlStringType = this.toHtml()\n\n if (html instanceof HTMLElement) {\n return html.outerHTML\n }\n\n if (html instanceof Node) {\n return html.textContent as string\n }\n\n return html\n }\n}\n\nclass RegExpString {\n /**\n * Build the Regular Expression string from the given parameter.\n *\n * @param { RegExp } pattern\n * @param { string } string\n *\n * @return { string }\n */\n static make (pattern: RegExp, string: string): string {\n if (string === '') {\n throw new Error('Empty regular expression.')\n }\n\n if (!string.startsWith('/')) {\n throw new Error('Delimiter must not be alphanumeric, backslash, or NUL.')\n }\n\n if (string.startsWith('/') && string.length === 1 || !string.endsWith('/')) {\n throw new Error('No ending delimiter \\'/\\'.')\n }\n\n const expression: RegExpExecArray | null = new RegExp(pattern).exec(string)\n\n return expression ? expression[1]! : ''\n }\n}\n\n/**\n * Get a new Stringable object from the given string.\n *\n * @param { string } string\n *\n * @return Stringable\n */\nexport function str (string: string = ''): Stringable {\n return Str.of(string)\n}\n\n/**\n * Quote regular expression characters.\n *\n * @param { string } string The input string.\n * @param { string | null } delimiter If the optional delimiter is specified, it will also be escaped.\n * This is useful for escaping the delimiter that is required by the PCRE functions.\n * The / is the most commonly used delimiter.\n *\n * @return { string } The quoted (escaped) string.\n */\nfunction preg_quote (string: string, delimiter: string | null = null): string {\n const characters: (string | null)[] = [\n '-', '.', '\\\\', '+', '*', '?', '[', '^', ']',\n '$', '(', ')', '{', '}', '=', '!', '<', '>',\n '|', ':', delimiter\n ]\n\n const escaped: string = characters.filter(Boolean).map((character: string | null): string => `\\\\${character}`).join('')\n\n return string.replace(new RegExp(`[${escaped}]`, 'g'), '\\\\$&')\n}\n\n/**\n * Uppercase the first character of each word in a string\n *\n * @param { string } string The input string.\n * @param { string } separators The optional separators contains the word separator characters.\n\n * @return { string } String the modified string.\n */\nfunction ucwords (string: string, separators: string = ' \\t\\r\\n\\f\\v'): string {\n return string.split(separators).map((word: string): string => word[0]?.toUpperCase() + word.substring(1)).join(' ')\n}\n\n/**\n * Attempt to match the case on two strings.\n *\n * @param { string} value\n * @param { string } comparison\n *\n * @return { string }\n */\nfunction matchCase (value: string, comparison: string): string {\n const cases: ((value: string) => string)[] = [\n (value: string): string => value.toLowerCase(),\n (value: string): string => value.toUpperCase(),\n (value: string): string => value.charAt(0).toUpperCase() + value.slice(1),\n (value: string): string => value.replace(/\\b\\w/g, (char: string): string => char.toUpperCase())\n ]\n\n for (const matcher of cases) {\n if (matcher(comparison) === comparison) {\n return matcher(value)\n }\n }\n\n return value\n}\n\n","import * as Crypto from './Helpers/Crypto'\nimport * as DumpDie from './Helpers/DumpDie'\nimport * as Number from './Helpers/Number'\nimport * as SimpleObj from './Helpers/Obj'\n\nimport { Arr } from './Helpers/Arr'\nimport { DateTime } from './Helpers/Time'\nimport { Obj } from './Helpers/Obj'\nimport { Str } from './Helpers/Str'\n\ntype CollapseStatics<T extends Record<string, any>> = {\n [K in keyof T]: T[K]\n}\n\n\ntype Omitables =\n | 'start' | 'take' | 'reverse' | 'chunk' | 'find' | 'pop' | 'end' | 'shift' | 'push' | 'at' | 'prototype'\n | 'concat' | 'join' | 'slice' | 'sort' | 'splice' | 'includes' | 'indexOf' | 'lastIndexOf' | 'findIndex'\n | 'every' | 'some' | 'forEach' | 'map' | 'filter' | 'reduce' | 'unshift' | 'flat' | 'flatMap' | 'keys'\n | 'fill' | 'copyWithin' | 'entries' | 'values' | 'reduceRight' | 'length' | 'of' | '_isObject' | '_clone'\n | 'crossJoin' | 'divide' | 'wrap' | 'except' | 'hasAny' | 'isList' | 'keyBy' | 'mapWithKeys' | 'only' | 'pluck'\n | 'pull' | 'shuffle' | 'sortDesc' | 'sortRecursive' | 'sortRecursiveDesc' | 'where' | 'whereNotNull' | 'head'\n | 'string' | 'boolean' | 'array' | 'float' | 'from' | 'hasAll' | 'integer' | 'mapSpread' | 'partition'\n | 'reject' | 'select' | 'sole' | 'alternate' | 'combine' | 'isEmpty' | 'isNotEmpty' | 'range'\n | typeof Symbol.unscopables | typeof Symbol.iterator\n\ntype TakeTime = Pick<typeof DateTime,\n | 'now' | 'format' | 'fromTimestamp' | 'randomTime' | 'firstDayOfMonth' | 'lastDayOfMonth' | 'parse'\n>\n\ntype TakeString = Pick<typeof Str,\n | 'after' | 'afterLast' | 'apa' | 'ascii' | 'before' | 'beforeLast' | 'between' | 'betweenFirst' | 'capitalize'\n | 'plural' | 'singular' | 'title'\n>\n\n/**\n * Global helpers interface that mirrors Laravel's helpers\n * and provides convenient access to all utility functions\n */\nexport interface GlobalHelpers extends\n Omit<CollapseStatics<typeof Arr>, Omitables | 'random' | 'dot'>,\n Omit<CollapseStatics<TakeString>, Omitables | 'random' | 'uuid'>,\n Omit<CollapseStatics<TakeTime>, Omitables>,\n Omit<CollapseStatics<typeof SimpleObj>, Omitables | 'Obj'>,\n Omit<CollapseStatics<typeof Crypto>, Omitables>,\n Omit<CollapseStatics<typeof Number>, Omitables>,\n Omit<CollapseStatics<typeof DumpDie>, Omitables> {\n // Array helpers\n Arr: typeof Arr\n // String helpers\n Str: typeof Str\n // Object helpers\n Obj: typeof Obj\n // Crypto helpers\n Crypto: typeof Crypto\n // Number helpers\n Number: typeof Number\n // Debug helpers\n DumpDie: typeof DumpDie\n // Date Time helpers\n DateTime: typeof DateTime\n}\n\n/**\n * Bootstrap the global helpers into the global scope.\n * This enables optional global access to all helper functions.\n * \n * Example usage:\n * ```typescript\n * import { loadHelpers } from '@h3ravel/support'\n * \n * // Make helpers globally available\n * loadHelpers()\n * \n * // Now you can use:\n * Arr.chunk([1, 2, 3, 4], 2)\n * // or directly:\n * chunk([1, 2, 3, 4], 2)\n * Str.capitalize('hello world')\n * // or directly:\n * capitalize('hello world')\n * ```\n * \n * @param target - The target object to attach helpers to (default: globalThis)\n */\nexport function loadHelpers (target: any = globalThis): void {\n const globalHelpers: GlobalHelpers = {\n // Re-export helpers as modules\n Arr,\n Crypto,\n Number,\n Obj,\n Str,\n DateTime,\n DumpDie: DumpDie,\n\n // String helpers\n apa: Str.apa,\n title: Str.title,\n ascii: Str.ascii,\n after: Str.after,\n afterLast: Str.afterLast,\n before: Str.before,\n beforeLast: Str.beforeLast,\n between: Str.between,\n betweenFirst: Str.betweenFirst,\n plural: Str.plural,\n singular: Str.singular,\n capitalize: Str.capitalize,\n\n // Array helpers\n collapse: Arr.collapse,\n forget: Arr.forget,\n first: Arr.first,\n last: Arr.last,\n prepend: Arr.prepend,\n flatten: Arr.flatten,\n\n // Object helpers\n dot: SimpleObj.dot,\n undot: SimpleObj.undot,\n extractProperties: SimpleObj.extractProperties,\n getValue: SimpleObj.getValue,\n modObj: SimpleObj.modObj,\n safeDot: SimpleObj.safeDot,\n setNested: SimpleObj.setNested,\n toCssClasses: SimpleObj.toCssClasses,\n slugifyKeys: SimpleObj.slugifyKeys,\n toCssStyles: SimpleObj.toCssStyles,\n data_get: SimpleObj.data_get,\n data_set: SimpleObj.data_set,\n data_fill: SimpleObj.data_fill,\n data_forget: SimpleObj.data_forget,\n\n // Crypto helpers\n uuid: Crypto.uuid,\n random: Crypto.random,\n randomSecure: Crypto.randomSecure,\n hash: Crypto.hash,\n hmac: Crypto.hmac,\n base64Encode: Crypto.base64Encode,\n base64Decode: Crypto.base64Decode,\n xor: Crypto.xor,\n randomColor: Crypto.randomColor,\n randomPassword: Crypto.randomPassword,\n secureToken: Crypto.secureToken,\n checksum: Crypto.checksum,\n verifyChecksum: Crypto.verifyChecksum,\n caesarCipher: Crypto.caesarCipher,\n\n // Time helpers\n now: DateTime.now,\n format: DateTime.format,\n fromTimestamp: DateTime.fromTimestamp,\n parse: DateTime.parse,\n randomTime: DateTime.randomTime,\n firstDayOfMonth: DateTime.firstDayOfMonth,\n lastDayOfMonth: DateTime.lastDayOfMonth,\n\n // Number helpers\n abbreviate: Number.abbreviate,\n humanize: Number.humanize,\n toBytes: Number.toBytes,\n toHumanTime: Number.toHumanTime,\n\n // Debug helpers\n dump: DumpDie.dump,\n dd: DumpDie.dd,\n }\n\n // Attach helpers to target\n Object.assign(target, globalHelpers)\n}\n\n/**\n * Clean up global helpers by removing them from the global scope.\n * This function removes all global helper attachments.\n * \n * @param target - The target object to clean up (default: globalThis)\n */\nexport function cleanHelpers (target: any = globalThis): void {\n const helpersToRemove = [\n // Array helpers\n 'Arr', 'chunk', 'collapse', 'alternate', 'combine', 'each', 'keys', 'find',\n 'forget', 'first', 'last', 'isEmpty', 'isNotEmpty', 'pop', 'prepend', 'take',\n 'reverse', 'shift', 'range', 'where', 'skip', 'flatten',\n\n // String helpers\n 'Str', 'after', 'afterLast', 'apa', 'ascii', 'before', 'beforeLast', 'between', 'betweenFirst', 'capitalize',\n 'plural', 'singular', 'title',\n\n // Object helpers\n 'Obj', 'dot', 'extractProperties', 'getValue', 'modObj', 'safeDot', 'setNested', 'slugifyKeys',\n 'toCssClasses', 'undot', 'toCssStyles', 'data_get', 'data_set', 'data_fill', 'data_forget',\n\n // Crypto helpers\n 'Crypto', 'uuid', 'random', 'randomSecure', 'hash', 'hmac', 'base64Encode',\n 'base64Decode', 'xor', 'randomColor', 'randomPassword', 'secureToken',\n 'checksum', 'verifyChecksum', 'caesarCipher',\n\n // Time helpers\n 'Time', 'now', 'format', 'fromTimestamp', 'add', 'randomTime', 'firstDayOfMonth',\n 'lastDayOfMonth', 'isLeapYear',\n\n // Number helpers\n 'Number', 'abbreviate', 'humanize', 'toBytes', 'toHumanTime',\n\n // Debug helpers\n 'dump', 'dd'\n ]\n\n helpersToRemove.forEach(helper => {\n if (helper in target) {\n delete target[helper]\n }\n })\n}\n\n// Also export as default bootstrap function for convenience\nexport default loadHelpers\n"],"mappings":"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GACV,cAAc;GACd,WAAW;GAGX,UAAU;GACV,aAAa;GAGb,QAAQ;GACR,QAAQ;GACR,SAAS;GACT,QAAQ;GACR,UAAU;GACV,OAAO;GACP,SAAS;GACT,SAAS;GACT,SAAS;GACT,aAAa;GACb,cAAc;GACd,WAAW;GACX,WAAW;GACX,YAAY;GACZ,WAAW;GACX,SAAS;GACT,YAAY;GACZ,aAAa;GAGb,UAAU;GACV,UAAU;GACV,SAAS;GACT,SAAS;GACT,WAAW;GACX,UAAU;GACV,QAAQ;GAGR,SAAS;GACT,WAAW;GAGX,QAAQ;GACR,QAAQ;GACR,QAAQ;GAGR,UAAU;GACb;AAyMD,MAtM8B;GAE1B;GACA;GACA;GACA;GACA;GAGA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GAGA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GAGA;GACA;GACA;GACA;GACA;GAGA;GACA;GACA;GACA;GACA;GACA;GAGA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GAGA;GACA;GACA;GACA;GACA;GAGA;GACA;GACA;GACA;GACA;GACA;GAGA;GACA;GACA;GAGA;GACA;GACA;GAGA;GACA;GACA;GACA;GAGA;GACA;GACA;GACA;GAGA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GAGA;GACA;GACA;GACA;GACA;GAGA;GACA;GAGA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GAMA;GACA;GACA;GACA;GACA;GAGA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GAGA;GACA;GACA;GACA;GACA;GACA;GACA;GAGA;GAGA;GACA;GAGA;GACA;GACA;GACA;GACA;GACA;GACA;GAGA;GACA;GACH,CAEe,QAAQ,MAAM,aAAa,CAAC,IAAI,EAC5C,QAAO,UAAU,OAAO,MAAM;AAGlC,OAAK,MAAM,QAAQ,WAAW;GAC1B,MAAMC,UAAkB,IAAI,OAAO,GAAG,KAAK,IAAI,IAAI;AAEnD,OAAI,QAAQ,KAAK,MAAM,CACnB,QAAO,UAAU,MAAM,QAAQ,SAAU,UAAU,MAAiB,EAAE,MAAM;;AAIpF,OAAK,MAAM,QAAQ,QAAQ;GACvB,MAAMA,UAAkB,IAAI,OAAO,MAAM,IAAI;AAE7C,OAAI,QAAQ,KAAK,MAAM,CACnB,QAAO,UAAU,MAAM,QAAQ,SAAU,OAAO,MAAiB,EAAE,MAAM;;AAIjF,SAAO,UAAU,OAAO,MAAM;;;;;;;;;;;;CAalC,OAAO,aAAa,OAAe,QAA2B,MAAc;AACxE,SAAO,KAAK,OAAO,OAAO,MAAM;;;;;;;;;;CAWpC,OAAO,aAAc,OAAe,QAA2B,GAAW;EACtE,MAAMC,QAAkB,MAAM,MAAM,eAAe;EAEnD,MAAMC,WAAoB,MAAM,KAAK;AAErC,SAAO,MAAM,KAAK,GAAG,GAAG,KAAK,QAAQ,KAAK,OAAO,UAAU,MAAM,CAAC;;;;;;;;;;CAWtE,OAAO,aAAc,OAAe,QAA2B,GAAW;AACtE,SAAO,KAAK,aAAa,OAAO,MAAM;;;;;;;;;;;;;CAc1C,OAAO,SAAU,SAAiB,IAAI,UAAmB,MAAM,UAAmB,MAAM,UAAmB,MAAM,SAAkB,OAAe;EAC9I,MAAMC,WAAqB,EAAE;EAC7B,IAAIC,aAAuB,EAAE;AAE7B,SAAO,SAAS,SAAS,QAAQ;AAC7B,OAAI,QACA,cAAa,WAAW,OAAO;IAC3B;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAClD;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAClD;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAClD;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAClD;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IACtC,CAAC;AAGN,OAAI,QACA,cAAa,WAAW,OAAO;IAC3B;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAChD,CAAC;AAGN,OAAI,QACA,cAAa,WAAW,OAAO;IAC3B;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAClD;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAAK;IAAM;IAAK;IAAK;IACnD;IAAK;IAAK;IAAK;IAClB,CAAC;AAGN,OAAI,OACA,cAAa,WAAW,OAAO,CAAC,IAAI,CAAC;AAGzC,YAAS,KAAM,WAAW,KAAK,MAAM,KAAK,QAAQ,GAAG,WAAW,OAAO,EAAa;;AAGxF,SAAO,SAAS,KAAK,GAAG;;;;;;;;;;;CAY5B,OAAO,SAAU,UAAkB,QAAgB,SAAiB,GAAmB;EACnF,MAAMpC,WAAmB,SAAS,QAAQ,QAAQ,KAAK,IAAI,QAAQ,EAAE,CAAC;AAEtE,SAAO,aAAa,KAAK,WAAW;;;;;;;;;CAUxC,OAAO,OAAQ,SAAiB,IAAY;AACxC,MAAI,KAAK,wBAAwB,KAC7B,QAAO,KAAK,oBAAoB,OAAO;EAG3C,MAAMqC,WAAmB,KAAK,KAAM,SAAU,EAAE,GAAG;EAEnD,MAAMC,QAAgB,OAAO,gBAAgB,IAAI,WAAW,SAAS,CAAC,CAAC,KAAK,GAAG;EAE/E,IAAIC,SAAiB,KAAK,MAAM;AAEhC;GAAC;GAAK;GAAK;GAAI,CAAC,SAAS,cAA8B,SAAS,OAAO,QAAQ,WAAW,GAAG,CAAC;AAE9F,SAAO,OAAO,UAAU,GAAG,OAAO;;;;;;;;;CAUtC,OAAO,yBAA0B,UAA+C,MAAY;AACxF,OAAK,sBAAsB;;;;;;;;;;CAW/B,OAAO,iCAAkC,UAAkC,cAA+B,MAAY;EAClH,IAAIC,OAAe;AAEnB,mBAAiB,WAA2B;GACxC,MAAMC,eAAgC,KAAK;AAE3C,QAAK,sBAAsB;GAE3B,MAAMC,eAAuB,KAAK,OAAO,OAAO;AAEhD,QAAK,sBAAsB;AAE3B;AAEA,UAAO;;AAGX,OAAK,0BAA0B,WAAwB;AACnD,OAAI,SAAS,UAAU,OACnB,QAAO,SAAS;AAGpB,UAAO,YAAY,OAAO;IAC5B;;;;;;;CAQN,OAAO,8BAAqC;AACxC,OAAK,sBAAsB;;;;;;;;;;CAW/B,OAAO,OAAQ,QAAgB,QAAgB,GAAW;AACtD,SAAO,OAAO,OAAO,MAAM;;;;;;;;;;;CAY/B,OAAO,aAAc,QAAgB,SAAmB,SAAyB;EAC7E,MAAMC,WAAqB,QAAQ,MAAM,OAAO;EAEhD,IAAI1C,SAAiB,SAAS,OAAO;AAErC,WAAS,SAAS,YAA4B,UAAU,IAAI,WAAW,QAAQ,OAAO,IAAI,QAAQ,OAAO,GAAG,QAAQ;AAEpH,SAAO;;;;;;;;;;CAWX,OAAO,WAAY,OAAY,UAA0B;AACrD,MAAI;GACA,MAAMA,SAAiB,OAAO,MAAM;AAEpC,OAAI,WAAW,eAAe,WAAW,OACrC,QAAO;AAGX,UAAO;UACH;AACJ,UAAO;;;;;;;;;;;;;CAcf,OAAO,QAAS,QAA2B,SAAiB,SAAiB,gBAAyB,MAAc;AAChH,WAAS,MAAM,QAAQ,OAAO,GAAG,SAAS,CAAC,OAAO;AAElD,SAAO,SAAS,SAAgC;AAC5C,OAAI,CAAC,cACD,QAAO,IAAI,OAAO,MAAM,KAAK;AAGjC,aAAU,QAAQ,WAAW,MAAM,QAAQ;IAC7C;AAEF,SAAO;;;;;;;;;;;CAYX,OAAO,aAAc,QAAgB,SAAiB,SAAyB;AAC3E,MAAI,WAAW,GACX,QAAO;AAKX,MAFyB,QAAQ,QAAQ,OAAO,KAE/B,OACb,QAAO,QAAQ,QAAQ,QAAQ,QAAQ;AAG3C,SAAO;;;;;;;;;;;CAYX,OAAO,aAAc,QAAgB,SAAiB,SAAyB;AAC3E,MAAI,WAAW,GACX,QAAO;AAGX,MAAI,KAAK,WAAW,SAAS,OAAO,CAChC,QAAO,KAAK,aAAa,QAAQ,SAAS,QAAQ;AAGtD,SAAO;;;;;;;;;;;CAYX,OAAO,YAAa,QAAgB,SAAiB,SAAyB;AAC1E,MAAI,WAAW,GACX,QAAO;EAGX,MAAMD,WAAmB,QAAQ,YAAY,OAAO;AAEpD,MAAI,aAAa,EACb,QAAO,QAAQ,UAAU,GAAG,SAAS,GAAG,UAAU,QAAQ,UAAU,WAAW,OAAO,OAAO;AAGjG,SAAO;;;;;;;;;;;CAYX,OAAO,WAAY,QAAgB,SAAiB,SAAyB;AACzE,MAAI,WAAW,GACX,QAAO;AAGX,MAAI,KAAK,SAAS,SAAS,OAAO,CAC9B,QAAO,KAAK,YAAY,QAAQ,SAAS,QAAQ;AAGrD,SAAO;;;;;;;;;;;CAYX,OAAO,eAAgB,SAAiB,SAA4B,SAAyB;EACzF,MAAMsB,OAAe,aAAa,KAAK,iBAAiB,QAAQ;EAChE,MAAMC,QAAgB,aAAa,KAAK,iBAAiB,QAAQ;EACjE,MAAMC,aAAqB,IAAI,OAAO,MAAM,SAAS,MAAM,QAAQ,IAAI,KAAK,KAAK,KAAK,KAAK;AAE3F,MAAI,mBAAmB,SACnB,WAAU,QAAQ,QAAQ,aAAa,YAA4B,QAAQ;AAG/E,SAAO,QAAQ,QAAQ,YAAa,QAAmB;;;;;;;;;;;CAY3D,OAAO,OAAQ,QAAgB,SAAiB,gBAAyB,MAAc;AACnF,SAAO,QAAQ,QAAQ,IAAI,OAAO,QAAQ,gBAAgB,MAAM,KAAK,EAAE,GAAG;;;;;;;;;CAU9E,OAAO,QAAS,OAAuB;AACnC,SAAO,MAAM,MAAM,GAAG,CAAC,SAAS,CAAC,KAAK,GAAG;;;;;;;;;;CAW7C,OAAO,MAAO,OAAe,QAAwB;EACjD,MAAMoB,SAAiB,WAAW,QAAQ,IAAI;AAE9C,SAAO,SAAS,MAAM,QAAQ,IAAI,OAAO,OAAO,OAAO,KAAK,IAAI,EAAE,GAAG;;;;;;;;;;CAWzE,OAAO,WACH,OACA,OAAgC,EAAE,EAClC,KACkB;AAClB,MAAI,CAACC,SAAO,CAAC,KAAM,QAAO;EAC1B,MAAM,QAAQ;EACd,MAAM,YAAY,IAAI,KAAK;AAC3B,SAAOA,MAAI,QAAQ,QAAQ,GAAG,QAAgB;GAC1C,MAAM,QAAQ,UAAU;AACxB,UAAO,UAAU,SAAY,OAAO,MAAM,GAAG,OAAO;IACtD;;;;;;;;;CAUN,OAAO,MAAO,OAAuB;AACjC,SAAO,MAAM,aAAa;;;;;;;;;CAU9B,OAAO,MAAO,OAAuB;AACjC,SAAO,MAAM,MAAM,YAAY,CAC1B,KAAK,SAAyB,KAAK,QAAQ,KAAK,KAAK,KAAK,UAAU,EAAE,CAAC,aAAa,CAAC,CAAC,CACtF,KAAK,IAAI;;;;;;;;;CAUlB,OAAO,SAAU,OAAuB;EACpC,IAAIZ,QAAkB,MAAM,MAAM,IAAI;AAEtC,UAAQ,MAAM,SAAS,IACjB,MAAM,KAAK,SAAyB,KAAK,MAAM,KAAK,CAAC,GACrD,KAAK,QAAQ,MAAM,KAAK,IAAI,CAAC,CAAC,KAAK,SAAyB,KAAK,MAAM,KAAK,CAAC;AAInF,SAF0B,KAAK,QAAQ;GAAC;GAAK;GAAK;GAAI,EAAE,KAAK,MAAM,KAAK,IAAI,CAAC,CAE5D,MAAM,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM;;;;;;;;;;;CAYhD,OAAO,IAAK,OAAuB;AAC/B,MAAI,UAAU,GACV,QAAO;EAGX,MAAMa,aAAuB;GACzB;GAAO;GAAM;GAAO;GAAO;GAAM;GAAO;GAAM;GAAM;GAAO;GAAK;GAChE;GAAO;GAAM;GAAM;GAAO;GAAM;GAAM;GAAO;GAAM;GAAO;GAAM;GAAM;GACzE;EAED,MAAMC,iBAA2B;GAAC;GAAK;GAAK;GAAK;GAAK;GAAK;GAAI;EAE/D,MAAMC,QAAkB,MAAM,MAAM,MAAM,CAAC,OAAO,QAAQ;AAE1D,QAAM,KAAM,MAAM,GAAc,OAAO,EAAE,CAAC,aAAa,GAAI,MAAM,GAAc,MAAM,EAAE,CAAC,aAAa;AAErG,OAAK,IAAIC,IAAY,GAAG,IAAI,MAAM,QAAQ,KAAK;GAC3C,MAAMC,gBAAyB,MAAM,GAAc,aAAa;AAEhE,OAAI,cAAc,SAAS,IAAI,EAAE;IAC7B,IAAIC,kBAA4B,cAAc,MAAM,IAAI;AAExD,sBAAkB,gBAAgB,KAAK,SAClC,WAAW,SAAS,KAAK,IAAI,KAAK,UAAU,IAAK,OAAO,KAAK,QAAQ,KAAK,CAC9E;AAED,UAAM,KAAK,gBAAgB,KAAK,IAAI;cAC7B,WAAW,SAAS,cAAc,IACzC,cAAc,UAAU,KACxB,EAAE,MAAM,KAAK,eAAe,SAAU,MAAM,IAAI,GAAc,MAAM,GAAG,CAAC,EACxE,OAAM,KAAK;OAEX,OAAM,KAAK,KAAK,QAAQ,cAAc;;AAI9C,SAAO,MAAM,KAAK,IAAI;;;;;;;;;CAU1B,OAAO,SAAU,OAAuB;EAEpC,MAAMC,WAAsC;GAExC,iBAAiB;GACjB,YAAY;GACZ,YAAY;GACZ,aAAa;GACb,WAAW;GAGX,wEAAwE;GACxE,WAAW;GAGX,YAAY;GACZ,wBAAwB;GACxB,WAAW;GACX,eAAe;GAGf,eAAe;GACf,mBAAmB;GAGnB,uCAAuC;GAGvC,gBAAgB;GAChB,UAAU;GAGV,sBAAsB;GAGtB,cAAc;GACd,eAAe;GACf,2BAA2B;GAC3B,mBAAmB;GAGnB,iCAAiC;GACjC,qBAAqB;GAGrB,yBAAyB;GACzB,kBAAkB;GAClB,cAAc;GACd,kCAAkC;GAGlC,eAAe;GAGf,eAAe;GAGf,UAAU;GACV,mBAAmB;GAGnB,cAAc;GAGd,YAAY;GAGZ,aAAa;GAGb,UAAU;GACV,eAAe;GACf,WAAW;GACX,WAAW;GACX,YAAY;GACZ,YAAY;GAGZ,WAAW;GAGX,SAAS;GAGT,gBAAgB;GAChB,iEAAiE;GAGjE,aAAa;GAGb,aAAa;GAGb,eAAe;GACf,WAAW;GAGX,kBAAkB;GAGlB,aAAa;GAGb,MAAM;GACT;EAGD,MAAMrB,YAAuC;GAEzC,UAAU;GACV,WAAW;GACX,UAAU;GACV,YAAY;GACZ,cAAc;GACd,WAAW;GACX,cAAc;GACd,QAAQ;GAGR,WAAW;GACX,YAAY;GACZ,SAAS;GACT,SAAS;GACT,SAAS;GACT,WAAW;GACX,YAAY;GACZ,YAAY;GACZ,WAAW;GAGX,UAAU;GACV,SAAS;GACT,SAAS;GACT,UAAU;GACV,YAAY;GACZ,SAAS;GACT,YAAY;GACZ,YAAY;GACZ,WAAW;GACX,YAAY;GACZ,QAAQ;GACR,UAAU;GACV,YAAY;GACZ,aAAa;GACb,UAAU;GAGV,QAAQ;GACR,SAAS;GACT,aAAa;GACb,YAAY;GAGZ,UAAU;GACV,SAAS;GACT,YAAY;GACZ,YAAY;GACZ,UAAU;GAGV,QAAQ;GACR,QAAQ;GACR,QAAQ;GACR,QAAQ;GACR,YAAY;GACZ,SAAS;GAGT,aAAa;GACb,SAAS;GACT,UAAU;GACV,UAAU;GACV,SAAS;GACT,YAAY;GACZ,UAAU;GAGV,UAAU;GACV,eAAe;GACf,UAAU;GACV,SAAS;GACT,UAAU;GAGV,UAAU;GAGV,UAAU;GAGV,UAAU;GACV,UAAU;GACV,UAAU;GACV,SAAS;GACT,UAAU;GAGV,OAAO;GACP,YAAY;GACZ,SAAS;GACT,SAAS;GACT,aAAa;GACb,UAAU;GACV,aAAa;GACb,QAAQ;GACR,WAAW;GACX,SAAS;GACT,UAAU;GAGV,WAAW;GACX,YAAY;GACZ,UAAU;GACV,WAAW;GACX,UAAU;GACV,UAAU;GAGV,SAAS;GACT,YAAY;GACZ,aAAa;GACb,aAAa;GACb,UAAU;GACV,QAAQ;GAGR,eAAe;GACf,aAAa;GACb,WAAW;GACX,UAAU;GACV,aAAa;GACb,YAAY;GAGZ,SAAS;GACT,cAAc;GAGd,SAAS;GACT,SAAS;GACT,WAAW;GACX,UAAU;GACV,UAAU;GACV,SAAS;GACT,SAAS;GACT,WAAW;GACX,UAAU;GACV,eAAe;GACf,eAAe;GACf,WAAW;GACX,YAAY;GACZ,WAAW;GACX,UAAU;GACV,SAAS;GACT,WAAW;GACX,aAAa;GAGb,UAAU;GACV,UAAU;GACV,WAAW;GACX,SAAS;GACT,aAAa;GACb,WAAW;GACX,SAAS;GAGT,UAAU;GACV,aAAa;GAGb,SAAS;GACT,SAAS;GACT,UAAU;GAGV,WAAW;GACd;AAyMD,MAtM8B;GAE1B;GACA;GACA;GACA;GACA;GAGA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GAGA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GAGA;GACA;GACA;GACA;GACA;GAGA;GACA;GACA;GACA;GACA;GACA;GAGA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GAGA;GACA;GACA;GACA;GACA;GAGA;GACA;GACA;GACA;GACA;GACA;GAGA;GACA;GACA;GAGA;GACA;GACA;GAGA;GACA;GACA;GACA;GAGA;GACA;GACA;GACA;GAGA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GAGA;GACA;GACA;GACA;GACA;GAGA;GACA;GAGA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GAMA;GACA;GACA;GACA;GACA;GAGA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GAGA;GACA;GACA;GACA;GACA;GACA;GACA;GAGA;GAGA;GACA;GAGA;GACA;GACA;GACA;GACA;GACA;GACA;GAGA;GACA;GACH,CAEe,QAAQ,MAAM,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"}
|