UNPKG

@react-hive/honey-utils

Version:

A lightweight TypeScript utility library providing a collection of helper functions for common programming tasks

1 lines 77.4 kB
{"version":3,"file":"index.cjs","mappings":"mBACA,IAAIA,EAAsB,CCA1BA,EAAwB,CAACC,EAASC,KACjC,IAAI,IAAIC,KAAOD,EACXF,EAAoBI,EAAEF,EAAYC,KAASH,EAAoBI,EAAEH,EAASE,IAC5EE,OAAOC,eAAeL,EAASE,EAAK,CAAEI,YAAY,EAAMC,IAAKN,EAAWC,MCJ3EH,EAAwB,CAACS,EAAKC,IAAUL,OAAOM,UAAUC,eAAeC,KAAKJ,EAAKC,GCClFV,EAAyBC,IACH,oBAAXa,QAA0BA,OAAOC,aAC1CV,OAAOC,eAAeL,EAASa,OAAOC,YAAa,CAAEC,MAAO,WAE7DX,OAAOC,eAAeL,EAAS,aAAc,CAAEe,OAAO,M,KCLhD,SAASC,EAAOC,EAAgBC,GACrC,IAAKD,EACH,MAAM,IAAIE,MAAMD,EAEpB,C,2mDASO,MAAME,EAAUL,GAA4C,OAAVA,EAS5CM,EAASN,GACpBA,QASWO,EAAgBP,GAC3BA,QASWQ,EAAeR,QAAiDS,IAAVT,EAStDU,EAAYV,GAAqD,iBAAVA,EASvDW,EAAUX,GAAsD,kBAAVA,EAStDY,EAAYZ,GAAqD,iBAAVA,EASvDa,EAAiBb,GAC5BY,EAASZ,KAAWK,EAAOL,IAAwC,IAA9BX,OAAOyB,KAAKd,GAAOe,OAS7CC,EAAUhB,GAAkCA,aAAiBiB,KAS7DC,EAAUlB,GAAkCA,aAAiBmB,KAS7DC,EAAWpB,GAAmCA,aAAiBI,MAS/DiB,EAAerB,GAC1BgB,EAAOhB,KAAWsB,MAAMtB,EAAMuB,WASnBC,EAAYxB,GAAoCA,aAAiByB,OASjEC,EAAS1B,GAAmDA,aAAiB2B,IAS7EC,EAAS5B,GAA0CA,aAAiB6B,IASpEC,EAAY9B,GAAqD,iBAAVA,EAgCvD+B,EAAkB/B,GAC7BU,EAASV,IAAUgC,SAAShC,GASjBiC,EAAajC,GACxBU,EAASV,IAAUkC,OAAOD,UAAUjC,GAsCzBmC,EAAanC,GACxB+B,EAAe/B,KAAWkC,OAAOD,UAAUjC,GCjOhCoC,EAAWpC,GAAuCqC,MAAMD,QAAQpC,GAShEsC,EAAgBtC,GAAgCoC,EAAQpC,IAA2B,IAAjBA,EAAMe,OAyBxEwB,EAAcC,GAA8BA,EAAMC,OAAOC,SAmBzDC,EAAaH,GAAoB,IAAI,IAAIX,IAAIW,IAqB7CI,EAAQ,CAAIJ,EAAYK,KACnC5C,EAAO4C,EAAO,EAAG,qCAEVR,MAAMS,KAAK,CAAE/B,OAAQgC,KAAKC,KAAKR,EAAMzB,OAAS8B,IAAS,CAACI,EAAGC,IAChEV,EAAMW,MAAMD,EAAQL,GAAOK,EAAQ,GAAKL,KAmB/BO,EAAe,IAAOC,KACjC,GAAsB,IAAlBA,EAAOtC,OACT,MAAO,GAGT,GAAsB,IAAlBsC,EAAOtC,OACT,MAAO,IAAIsC,EAAO,IAGpB,MAAOC,KAAUC,GAAQF,EAGzB,OAFoBV,EAAOW,GAERb,OAAOe,GAAQD,EAAKE,MAAMjB,GAASA,EAAMkB,SAASF,MAmB1DG,EAAa,CAAInB,EAAYoB,IACxCpB,EAAMC,OAAOe,IAASI,EAAQF,SAASF,IA6C5BK,EACX,IAAIC,IACHC,GACCD,EAAIE,OAAO,CAACC,EAAMC,IAAOA,EAAGD,GAAOF,GA4C1BI,EACX,IAAIL,IACHC,GACCD,EAAIM,YAAY,CAACH,EAAMC,IAAOA,EAAGD,GAAOF,GCvO/BM,EAAO,OASPC,EAActE,GAAoC,mBAAVA,EAoBxCuE,EACcL,GACzB,IAAIM,KACDN,KAAMM,GAcEC,EAAmB,CAC9BC,KACGF,IAC0B,mBAAVE,EAAwBA,KAAuCF,GAAQE,EA2B/EC,EAASC,GACpB,IAAIC,QAAQC,GAAWC,WAAWD,EAASF,IAwBhCI,EAAUC,MACrBC,EACAC,EACAC,EAAe,yBAIf,IACE,aAAaP,QAAQQ,KAAK,CACxBH,EACAP,EAAMQ,GAAWG,KAAK,IAAMT,QAAQU,OAAO,IAAInF,MAAMgF,MAEzD,C,QAIA,GA0EWI,EAAQ,CACnBC,GACEC,cAAc,EAAGd,UAAU,IAAKe,WAAU,EAAMC,WAA0B,CAAC,IAEtEX,SAAUT,KACf,IAAIqB,EAEJ,IAAK,IAAIC,EAAU,EAAGA,GAAWJ,EAAaI,IAC5C,IACE,aAAaL,KAAQjB,EACvB,CAAE,MAAOuB,GAGP,GAFAF,EAAYE,EAERD,EAAUJ,EAAa,CACzBE,IAAUE,EAASC,GAEnB,MAAMC,EAAYL,EAAUf,EAAU,IAAMkB,EAAU,GAAKlB,QACrDD,EAAMqB,EACd,CACF,CAGF,MAAMH,GAsBGI,EAA2C/B,IACtD,IACIgC,EADAC,GAAS,EAGb,OAAO,YAAwB3B,GAM7B,OALK2B,IACHA,GAAS,EACTD,EAAShC,EAAGkC,MAAMC,KAAM7B,IAGnB0B,CACT,GC3OWI,EAA0BtG,GACrCsE,EAAYtE,GAAsBsF,MAwBvBiB,EAAgBtB,MAC3BzC,EACA0B,KAEA,MAAMsC,EAAoB,GAE1B,IAAK,IAAIC,EAAI,EAAGA,EAAIjE,EAAMzB,OAAQ0F,IAChCD,EAAQE,WAAWxC,EAAG1B,EAAMiE,GAAIA,EAAGjE,IAGrC,OAAOgE,GAsBIG,EAAc1B,MACzBzC,EACA0B,IACsBW,QAAQ+B,IAAIpE,EAAMqE,IAAI3C,IA0BjC4C,EAAmB7B,MAC9BzC,EACAuE,KAEA,MAAMP,EAAkB,GAExB,IAAK,IAAIC,EAAI,EAAGA,EAAIjE,EAAMzB,OAAQ0F,IAAK,CACrC,MAAMjD,EAAOhB,EAAMiE,SAETM,EAAUvD,EAAMiD,EAAGjE,IAC3BgE,EAAQE,KAAKlD,EAEjB,CAEA,OAAOgD,GA+BIQ,EAAiB/B,MAC5BzC,EACAuE,KAEA,MAAMP,QAAgBG,EAAYnE,EAAOyC,MAAOzB,EAAMN,EAAOV,YACpDuE,EAAUvD,EAAMN,EAAOV,IAAUgB,GAG1C,OAAOjB,EAAQiE,IAWJS,EAAYhC,MACvBzC,EACAuE,KAEA,IAAK,IAAIN,EAAI,EAAGA,EAAIjE,EAAMzB,OAAQ0F,IAChC,SAAUM,EAAUvE,EAAMiE,GAAIA,EAAGjE,GAC/B,OAAO,EAIX,OAAO,GAWI0E,EAAajC,MACxBzC,EACAuE,KAEA,IAAK,IAAIN,EAAI,EAAGA,EAAIjE,EAAMzB,OAAQ0F,IAChC,UAAYM,EAAUvE,EAAMiE,GAAIA,EAAGjE,GACjC,OAAO,EAIX,OAAO,GAeI2E,EAAclC,MACzBzC,EACA0B,EACAkD,KAEA,IAAIC,EAAcD,EAElB,IAAK,IAAIX,EAAI,EAAGA,EAAIjE,EAAMzB,OAAQ0F,IAChCY,QAAoBnD,EAAGmD,EAAa7E,EAAMiE,GAAIA,EAAGjE,GAGnD,OAAO6E,GAWIC,EAAYrC,MACvBzC,EACAuE,KAEA,IAAK,IAAIN,EAAI,EAAGA,EAAIjE,EAAMzB,OAAQ0F,IAChC,SAAUM,EAAUvE,EAAMiE,GAAIA,EAAGjE,GAC/B,OAAOA,EAAMiE,GAIjB,OAAO,MCxOIc,EAAYvH,GAAqD,iBAAVA,EAcvDwH,EAAsBxH,GACvB,KAAVA,GAAgBM,EAAMN,GAmBXyH,EAAe/C,GAC1BA,EAAMgD,QAAQ,qBAAsB,SAASC,cAqBlCC,EAAmBlD,IAE9B,MAAMmD,EAAYnD,EAAMoD,OAAO,GACzBC,EAAerD,EAAMvB,MAAM,GAQjC,OAL2B0E,EAAUF,cAGfI,EAAaL,QAAQ,SAAUM,GAAU,IAAIA,EAAOL,kBAuB/DM,EAAgBvD,GAAkBA,EAAMgD,QAAQ,qBAAsB,SAStEQ,EAAwBxD,GAA4BA,EAAMyD,MAAM,KAAK1F,OAAOC,SA0B5E0F,GAAc1D,IACzB,IAAI2D,EAAO,KAEX,IAAK,IAAI5B,EAAI,EAAGA,EAAI/B,EAAM3D,OAAQ0F,IAChC4B,EAAe,GAAPA,EAAa3D,EAAM4D,WAAW7B,GAGxC,OAAQ4B,IAAS,GAAGE,SAAS,KCjIlBC,GAA6B,CACxCC,EACAC,EACAC,EACAC,KAEA,MAAMC,EAASF,EAAOF,EAChBK,EAASF,EAAOF,EAEtB,OAAO3F,KAAKgG,MAAMF,EAAQC,IAWfE,GAAuB,CAACC,EAAkBC,IACrDnG,KAAKoG,IAAIF,EAAWC,GAUTE,GAAsB,CAACpJ,EAAeqJ,IAChDrJ,EAAQqJ,EAAc,ICtCZC,GAAsB,CAAC,QAAS,SAAU,WAAY,SAAU,KA0BhEC,GAAiBC,IAC5B,MAGMC,EAHiBC,OAAOC,iBAAiBH,GACTI,iBAAiB,aAEpBC,MAAM,oBACzC,IAAKJ,EACH,MAAO,CACLK,WAAY,EACZC,WAAY,EACZC,OAAQ,EACRC,OAAQ,EACRC,MAAO,EACPC,MAAO,GAIX,MAAOH,EAAQG,EAAOD,EAAOD,EAAQH,EAAYC,GAAcN,EAAY,GACxEtB,MAAM,MACNtB,IAAIuD,YAEP,MAAO,CACLN,aACAC,aACAC,SACAC,SACAC,QACAC,UAWSE,GAAaC,GAAqB,IAAInJ,KAAK,CAACmJ,GAAO,CAAEC,KAAMD,EAAKC,OAahEC,GAA8B,CAACC,EAAqBC,IAC9C3H,KAAK4H,IACpB,EACA5H,KAAK6H,IAAIH,EAAWI,MAAOH,EAAWG,OAAS9H,KAAK4H,IAAIF,EAAWK,KAAMJ,EAAWI,OAGrE/H,KAAK4H,IACpB,EACA5H,KAAK6H,IAAIH,EAAWM,OAAQL,EAAWK,QAAUhI,KAAK4H,IAAIF,EAAWO,IAAKN,EAAWM,OAIpEN,EAAWO,MAAQP,EAAWQ,QActCC,GAAwB3B,GACnC,IAAI4B,QAAQ5B,EAAQ6B,WAAY7B,EAAQ8B,UAAW9B,EAAQ+B,YAAa/B,EAAQgC,cAcrEC,GAAuBjC,GACd,MAApBA,EAAQkC,QAYGC,GAAgCnC,GACC,SAA5CA,EAAQoC,aAAa,mBAoBVC,GAA0BrC,IACrC,IAAKA,EACH,OAAO,EAIT,MAAMsC,EAAQpC,OAAOC,iBAAiBH,GACtC,GAAyB,WAArBsC,EAAMC,YAA6C,SAAlBD,EAAME,QACzC,OAAO,EAGT,GAAI,aAAcxC,GAAWA,EAAQyC,SACnC,OAAO,EAIT,MAAMC,EAAW1C,EAAQoC,aAAa,YACtC,MAAiB,OAAbM,IAIA5C,GAAoB5F,SAAS8F,EAAQkC,UACnCD,GAAoBjC,IACE,KAAjBA,EAAQ2C,OAMfR,GAA6BnC,IAIb,OAAb0C,IAcIE,GAA4BC,GACvChK,MAAMS,KAAKuJ,EAAUC,iBAA8B,MAAM7J,OAAOoJ,IA0DrDU,GAA2B,CACtCC,EACAH,EAAmC,MACjCI,QAAO,EAAMC,gBAAkD,CAAC,KAElE,MAAMC,EAAgBC,SAASD,cACzBE,EAAQR,GAAaM,GAAeG,cAE1C,IAAKH,IAAkBE,EACrB,OAGF,MAAME,EAAoBX,GAAyBS,GACnD,GAAiC,IAA7BE,EAAkBhM,OACpB,OAGF,MAAMiM,EAAeD,EAAkBE,QAAQN,GAC/C,IAAsB,IAAlBK,EACF,OAGF,IAAIE,EAEAR,EACFQ,EAAYR,EAAaM,EAAcR,EAAWO,GAEhC,SAAdP,GACFU,EAAYF,EAAe,EAEvBE,GAAaH,EAAkBhM,SACjCmM,EAAYT,EAAO,EAAI,QAGzBS,EAAYF,EAAe,EAEvBE,EAAY,IACdA,EAAYT,EAAOM,EAAkBhM,OAAS,EAAI,OAKtC,OAAdmM,GAIJH,EAAkBG,IAAYC,SAUnBC,GAAgB5D,GAC3BA,EAAQ6D,YAAc7D,EAAQ+B,YAYnB+B,GAAqB9D,GAChCzG,KAAK4H,IAAI,EAAGnB,EAAQ6D,YAAc7D,EAAQ+B,aAS/BgC,GAAgB/D,GAC3BA,EAAQgE,aAAehE,EAAQgC,aAYpBiC,GAAsBjE,GACjCzG,KAAK4H,IAAI,EAAGnB,EAAQgE,aAAehE,EAAQgC,cAyChCkC,GAAwB,EACnCC,eACAC,gBACAC,gBACAC,kBAEA,GAAIH,GAAgB,EAClB,OAAO,EAGT,MAGMI,EAFgBF,EAAgBC,EAAc,EAD5BF,EAAgB,EAKxC,OAAQ7K,KAAK4H,IAAI,EAAG5H,KAAK6H,IAAImD,EAAcJ,KAiChCK,GAA2B,CACtCC,EACAC,GACEC,OAAO,QAA4C,CAAC,KAEtD,IAAIrE,EAAa,EACbC,EAAa,EAEJ,MAAToE,GAAyB,SAATA,IAClBrE,EAAa4D,GAAsB,CACjCC,aAAcL,GAAkBW,GAChCL,cAAeK,EAAiB1C,YAChCsC,cAAeK,EAAgB7C,WAC/ByC,YAAaI,EAAgB3C,eAIpB,MAAT4C,GAAyB,SAATA,IAClBpE,EAAa2D,GAAsB,CACjCC,aAAcF,GAAmBQ,GACjCL,cAAeK,EAAiBzC,aAChCqC,cAAeK,EAAgB5C,UAC/BwC,YAAaI,EAAgB1C,gBAIjCyC,EAAiBnC,MAAMsC,UAAY,aAAatE,QAAiBC,QActDsE,GAAyB,KACpC,GAAsB,oBAAX3E,SAA2BA,OAAO4E,aAC3C,OAAO,EAGT,IAEE,OADA5E,OAAO4E,aAAaC,QAAQ,yBACrB,CACT,CAAE,MACA,OAAO,CACT,GA+BWC,GAA8B,KAEzC,IADiBH,KAEf,MAAO,CACLI,UAAU,EACVC,UAAU,GAId,IACE,MAAMvP,EAAM,iBAKZ,OAHAuK,OAAO4E,aAAaK,QAAQxP,EAAK,KACjCuK,OAAO4E,aAAaM,WAAWzP,GAExB,CACLsP,UAAU,EACVC,UAAU,EAEd,CAAE,MAEF,CAEA,MAAO,CACLD,UAAU,EACVC,UAAU,IAwCDG,GAAe,CAC1BC,GACEC,WAAUC,UAAgC,CAAC,KAG7C,GAAIxO,EAAYoM,UACd,OAGF,MAAMqC,EAAOrC,SAASsC,cAAc,KACpC,IAAIC,EAA2B,KAE/B,IACE,MAAMhD,EAAO5E,EAASuH,GAAQA,EAAQK,EAAYC,IAAIC,gBAAgBP,GACtEG,EAAK9C,KAAOA,EAER4C,IACFE,EAAKK,SAAWP,GAGdC,IACFC,EAAKD,OAASA,GAIhBpC,SAAS2C,KAAKC,YAAYP,GAC1BA,EAAKQ,OACP,C,QACER,EAAKS,SAEDP,GAEFpK,WAAW,KACT9E,EAAOkP,EAAW,iCAElBC,IAAIO,gBAAgBR,IACnB,EAEP,GCzmBWS,GAAU5P,GAAkCA,aAAiB6P,KAiB7DC,GAAiBf,IAC5B,MAAMgB,EAAehB,EAASiB,YAAY,KAG1C,OAAID,GAAgB,GAAKA,IAAiBhB,EAAShO,OAAS,EACnD,CAACgO,EAAU,IAGb,CAACA,EAAS5L,MAAM,EAAG4M,GAAehB,EAAS5L,MAAM4M,EAAe,GAAGpI,gBAU/DsI,GAAmBC,IAC9B,IAAKA,EACH,MAAO,GAGT,MAAMC,EAAgB,GAEtB,IAAK,IAAI1J,EAAI,EAAGA,EAAIyJ,EAASnP,OAAQ0F,IACnC0J,EAAMzJ,KAAKwJ,EAASzJ,IAGtB,OAAO0J,GAsBIC,GAAa,CAAC9F,EAAYyE,IACrC,IAAIc,KAAK,CAACvF,GAAOyE,EAAU,CACzBxE,KAAMD,EAAKC,OA2DF8F,GAA8BpL,MACzCqL,GAEEC,YAAY,CACV,YACA,YACA,cACA,cACA,kBACA,WACA,aACA,aAE0B,CAAC,KAE/B,MAAMC,EAAe,IAAI3O,IAAI0O,GACvBE,OAjE+BxL,OACrCqL,IAEA,MAAMI,EAAkBJ,EAAeK,eAEjCC,EAAU3L,SACd,IAAIJ,QAAQ,CAACC,EAASS,KACpBmL,EAAgBG,YAAY5L,MAAMwL,IAChC,GAAKA,EAAQ1P,OAKb,IACE,MAAM+P,QAAoBF,IAE1B9L,EAAQ,IAAI2L,KAAYK,GAC1B,CAAE,MAAO/K,GACPR,EAAOQ,EACT,MAVEjB,EAAQ,KAWTS,KAGP,OAAOqL,KA0CeG,CAA+BT,GAkBrD,aAhB2B3J,EAAY8J,EAASxL,MAAM+L,GAChDA,EAAMC,YACDZ,GAA4BW,EAAmC,CACpET,cAEQC,EAAaU,IAAIF,EAAMG,MAQ5B,GAHE,OAJY,IAAItM,QAAc,CAACC,EAASS,KAC5CyL,EAA8BlC,KAAKhK,EAASS,QAS/B6L,QAsBTC,GAA4BpM,MACvCqM,EACAC,EAA4C,CAAC,KAE7C,MAAMC,EAAQF,GAAcE,MAC5B,IAAKA,EACH,MAAO,GAGT,MAAMC,EAA2B,GAEjC,IAAK,IAAIC,EAAY,EAAGA,EAAYF,EAAMzQ,OAAQ2Q,IAAa,CAC7D,MAAMlO,EAAOgO,EAAME,GAInB,GAAI,qBAAsBlO,EAAM,CAE9B,MAAMwN,EAAQxN,EAAKmO,qBAEnB,GAAIX,GAAOC,YAAa,CACtBQ,EAAM/K,KAAK2J,GAA4BW,EAAmCO,IAE1E,QACF,CAEA,GAAIP,GAAOpB,OAAQ,CACjB6B,EAAM/K,KACJ,IAAI7B,QAAgB,CAACC,EAASS,IAC3ByL,EAA8BlC,KAAKA,GAAQhK,EAAQ,CAACgK,IAAQvJ,KAIjE,QACF,CACF,CAGA,MAAMuJ,EAAOtL,EAAKoO,YACd9C,GACF2C,EAAM/K,KAAK7B,QAAQC,QAAQ,CAACgK,IAEhC,CAEA,aAAcjK,QAAQ+B,IAAI6K,IAAQL,QC5NvBS,GAAkCpS,GAC7CJ,OAAOoR,QAAQhR,GAAKuE,OAAO,CAACkC,GAAS/G,EAAKa,WAC1BS,IAAVT,IACFkG,EAAO/G,GAAOa,GAETkG,GACN,CAAC,G","sources":["webpack://@react-hive/honey-utils/webpack/bootstrap","webpack://@react-hive/honey-utils/webpack/runtime/define property getters","webpack://@react-hive/honey-utils/webpack/runtime/hasOwnProperty shorthand","webpack://@react-hive/honey-utils/webpack/runtime/make namespace object","webpack://@react-hive/honey-utils/./src/guards.ts","webpack://@react-hive/honey-utils/./src/array.ts","webpack://@react-hive/honey-utils/./src/function.ts","webpack://@react-hive/honey-utils/./src/async.ts","webpack://@react-hive/honey-utils/./src/string.ts","webpack://@react-hive/honey-utils/./src/math.ts","webpack://@react-hive/honey-utils/./src/dom.ts","webpack://@react-hive/honey-utils/./src/file.ts","webpack://@react-hive/honey-utils/./src/object.ts"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","export function assert(condition: any, message: string): asserts condition {\n if (!condition) {\n throw new Error(message);\n }\n}\n\n/**\n * Checks if a value is null.\n *\n * @param value - The value to check.\n *\n * @returns `true` if the value is null; otherwise, `false`.\n */\nexport const isNull = (value: unknown): value is null => value === null;\n\n/**\n * Checks if a value is null or undefined.\n *\n * @param value - The value to check.\n *\n * @returns `true` if the value is `null` or `undefined`, otherwise `false`.\n */\nexport const isNil = (value: unknown): value is null | undefined =>\n value === undefined || value === null;\n\n/**\n * Checks if a value is neither `null` nor `undefined`.\n *\n * @param value - The value to check.\n *\n * @returns `true` if the value is defined (not `null` or `undefined`); otherwise, `false`.\n */\nexport const isDefined = <T>(value: T): value is NonNullable<T> =>\n value !== null && value !== undefined;\n\n/**\n * Checks if a value is undefined.\n *\n * @param value - The value to check.\n *\n * @returns `true` if the value is undefined; otherwise, `false`.\n */\nexport const isUndefined = (value: unknown): value is undefined => value === undefined;\n\n/**\n * Checks if a value is a number.\n *\n * @param value - The value to check.\n *\n * @returns `true` if the value is a number; otherwise, `false`.\n */\nexport const isNumber = (value: unknown): value is number => typeof value === 'number';\n\n/**\n * Checks if a value is a boolean.\n *\n * @param value - The value to check.\n *\n * @returns `true` if the value is a boolean; otherwise, `false`.\n */\nexport const isBool = (value: unknown): value is boolean => typeof value === 'boolean';\n\n/**\n * Checks if a value is an object.\n *\n * @param value - The value to check.\n *\n * @returns `true` if the value is an object; otherwise, `false`.\n */\nexport const isObject = (value: unknown): value is object => typeof value === 'object';\n\n/**\n * Checks if a value is an empty object (no own enumerable properties).\n *\n * @param value - The value to check.\n *\n * @returns `true` if the value is an empty object; otherwise, `false`.\n */\nexport const isEmptyObject = (value: unknown): value is Record<string, never> =>\n isObject(value) && !isNull(value) && Object.keys(value).length === 0;\n\n/**\n * Checks if a value is a Date object.\n *\n * @param value - The value to check.\n *\n * @returns `true` if the value is a Date object; otherwise, `false`.\n */\nexport const isDate = (value: unknown): value is Date => value instanceof Date;\n\n/**\n * Checks if a value is a `Blob`.\n *\n * @param value - The value to check.\n *\n * @returns `true` if the value is a Blob object; otherwise, `false`.\n */\nexport const isBlob = (value: unknown): value is Blob => value instanceof Blob;\n\n/**\n * Checks if a value is an `Error` object.\n *\n * @param value - The value to check.\n *\n * @returns `true` if the value is an Error instance; otherwise, `false`.\n */\nexport const isError = (value: unknown): value is Error => value instanceof Error;\n\n/**\n * Checks if a value is a valid Date object (not Invalid Date).\n *\n * @param value - The value to check.\n *\n * @returns `true` if the value is a valid Date object; otherwise, `false`.\n */\nexport const isValidDate = (value: unknown): value is Date =>\n isDate(value) && !isNaN(value.getTime());\n\n/**\n * Checks if a value is a RegExp object.\n *\n * @param value - The value to check.\n *\n * @returns `true` if the value is a RegExp object; otherwise, `false`.\n */\nexport const isRegExp = (value: unknown): value is RegExp => value instanceof RegExp;\n\n/**\n * Checks if a value is a Map.\n *\n * @param value - The value to check.\n *\n * @returns `true` if the value is a Map; otherwise, `false`.\n */\nexport const isMap = (value: unknown): value is Map<unknown, unknown> => value instanceof Map;\n\n/**\n * Checks if a value is a Set.\n *\n * @param value - The value to check.\n *\n * @returns `true` if the value is a Set; otherwise, `false`.\n */\nexport const isSet = (value: unknown): value is Set<unknown> => value instanceof Set;\n\n/**\n * Checks if a value is a Symbol.\n *\n * @param value - The value to check.\n *\n * @returns `true` if the value is a Symbol; otherwise, `false`.\n */\nexport const isSymbol = (value: unknown): value is symbol => typeof value === 'symbol';\n\n/**\n * Checks if a value is a finite number.\n *\n * A finite number is a number that is not `NaN`, `Infinity`, or `-Infinity`.\n *\n * @param value - The value to check.\n *\n * @returns `true` if the value is a finite number; otherwise, `false`.\n *\n * @example\n * ```ts\n * isFiniteNumber(10); // true\n * isFiniteNumber(3.14); // true\n * isFiniteNumber(-5); // true\n * ```\n *\n * @example\n * ```ts\n * isFiniteNumber(NaN); // false\n * isFiniteNumber(Infinity); // false\n * isFiniteNumber(-Infinity); // false\n * ```\n *\n * @example\n * ```ts\n * isFiniteNumber('10'); // false\n * isFiniteNumber(null); // false\n * isFiniteNumber(undefined); // false\n * ```\n */\nexport const isFiniteNumber = (value: unknown): value is number =>\n isNumber(value) && isFinite(value);\n\n/**\n * Checks if a value is an integer.\n *\n * @param value - The value to check.\n *\n * @returns `true` if the value is an integer; otherwise, `false`.\n */\nexport const isInteger = (value: unknown): value is number =>\n isNumber(value) && Number.isInteger(value);\n\n/**\n * Checks if a value is a decimal number (finite and non-integer).\n *\n * A decimal number is a finite number that has a fractional part (i.e. not an integer).\n *\n * @param value - The value to check.\n *\n * @returns `true` if the value is a decimal number; otherwise, `false`.\n *\n * @example\n * ```ts\n * isDecimal(1.5); // true\n * isDecimal(-0.25); // true\n * isDecimal(0.1); // true\n * ```\n *\n * @example\n * ```ts\n * isDecimal(1); // false\n * isDecimal(0); // false\n * isDecimal(-10); // false\n * ```\n *\n * @example\n * ```ts\n * isDecimal(NaN); // false\n * isDecimal(Infinity); // false\n * ```\n *\n * @example\n * ```ts\n * isDecimal('1.5'); // false\n * isDecimal(null); // false\n * isDecimal(undefined); // false\n * ```\n */\nexport const isDecimal = (value: unknown): value is number =>\n isFiniteNumber(value) && !Number.isInteger(value);\n","import { assert } from './guards';\n\n/**\n * Checks if a value is an array.\n *\n * @param value - The value to check.\n *\n * @returns `true` if the value is an array; otherwise, `false`.\n */\nexport const isArray = (value: unknown): value is unknown[] => Array.isArray(value);\n\n/**\n * Checks if a value is an empty array.\n *\n * @param value - The value to check.\n *\n * @returns `true` if the value is an empty array; otherwise, `false`.\n */\nexport const isEmptyArray = (value: unknown): value is [] => isArray(value) && value.length === 0;\n\n/**\n * Represents all falsy values.\n */\ntype Falsy = false | null | undefined | 0 | '';\n\n/**\n * Removes all falsy values from an array.\n *\n * Falsy values include: `false`, `0`, `''` (empty string), `null`, `undefined`, and `NaN`.\n *\n * Useful for cleaning up arrays with optional, nullable, or conditionally included items.\n *\n * @template T - The type of the truthy items.\n *\n * @param array - An array possibly containing falsy values.\n *\n * @returns A new array containing only truthy values of type `T`.\n *\n * @example\n * ```ts\n * compact([0, 1, false, 2, '', 3, null, undefined, NaN]); // [1, 2, 3]\n * ```\n */\nexport const compact = <T>(array: (T | Falsy)[]): T[] => array.filter(Boolean) as T[];\n\n/**\n * Returns a new array with duplicate values removed.\n *\n * Uses Set for efficient duplicate removal while preserving the original order.\n *\n * @template T - The type of the items in the array.\n *\n * @param array - The input array that may contain duplicate values.\n *\n * @returns A new array with only unique values, maintaining the original order.\n *\n * @example\n * ```ts\n * unique([1, 2, 2, 3, 1, 4]); // [1, 2, 3, 4]\n * unique(['a', 'b', 'a', 'c']); // ['a', 'b', 'c']\n * ```\n */\nexport const unique = <T>(array: T[]): T[] => [...new Set(array)];\n\n/**\n * Splits an array into chunks of the specified size.\n *\n * Useful for pagination, batch processing, or creating grid layouts.\n *\n * @template T - The type of the items in the array.\n *\n * @param array - The input array to be chunked.\n * @param size - The size of each chunk. Must be greater than 0.\n *\n * @returns An array of chunks, where each chunk is an array of the specified size\n * (except possibly the last chunk, which may be smaller).\n *\n * @example\n * ```ts\n * chunk([1, 2, 3, 4, 5], 2); // [[1, 2], [3, 4], [5]]\n * chunk(['a', 'b', 'c', 'd'], 3); // [['a', 'b', 'c'], ['d']]\n * ```\n */\nexport const chunk = <T>(array: T[], size: number): T[][] => {\n assert(size > 0, 'Chunk size must be greater than 0');\n\n return Array.from({ length: Math.ceil(array.length / size) }, (_, index) =>\n array.slice(index * size, (index + 1) * size),\n );\n};\n\n/**\n * Returns an array containing elements that exist in all provided arrays.\n *\n * @template T - The type of the items in the arrays.\n *\n * @param arrays - Two or more arrays to find common elements from.\n *\n * @returns A new array containing only the elements that exist in all input arrays.\n *\n * @example\n * ```ts\n * intersection([1, 2, 3], [2, 3, 4]); // [2, 3]\n * intersection(['a', 'b', 'c'], ['b', 'c', 'd'], ['b', 'e']); // ['b']\n * ```\n */\nexport const intersection = <T>(...arrays: T[][]): T[] => {\n if (arrays.length === 0) {\n return [];\n }\n\n if (arrays.length === 1) {\n return [...arrays[0]];\n }\n\n const [first, ...rest] = arrays;\n const uniqueFirst = unique(first);\n\n return uniqueFirst.filter(item => rest.every(array => array.includes(item)));\n};\n\n/**\n * Returns elements from the first array that don't exist in the second array.\n *\n * @template T - The type of the items in the arrays.\n *\n * @param array - The source array.\n * @param exclude - The array containing elements to exclude.\n *\n * @returns A new array with elements from the first array that don't exist in the second array.\n *\n * @example\n * ```ts\n * difference([1, 2, 3, 4], [2, 4]); // [1, 3]\n * difference(['a', 'b', 'c'], ['b']); // ['a', 'c']\n * ```\n */\nexport const difference = <T>(array: T[], exclude: T[]): T[] =>\n array.filter(item => !exclude.includes(item));\n\ntype PipeFn = (arg: unknown) => unknown;\n\ntype Pipe = {\n <A, B>(fn1: (a: A) => B): (a: A) => B;\n <A, B, C>(fn1: (a: A) => B, fn2: (b: B) => C): (a: A) => C;\n <A, B, C, D>(fn1: (a: A) => B, fn2: (b: B) => C, fn3: (c: C) => D): (a: A) => D;\n <A, B, C, D, E>(\n fn1: (a: A) => B,\n fn2: (b: B) => C,\n fn3: (c: C) => D,\n fn4: (d: D) => E,\n ): (a: A) => E;\n <A, B, C, D, E, F>(\n fn1: (a: A) => B,\n fn2: (b: B) => C,\n fn3: (c: C) => D,\n fn4: (d: D) => E,\n fn5: (e: E) => F,\n ): (a: A) => F;\n (...fns: PipeFn[]): (arg: unknown) => unknown;\n};\n\n/**\n * Composes multiple unary functions into a single function, applying them from left to right.\n *\n * Useful for building a data processing pipeline where the output of one function becomes the input of the next.\n *\n * Types are inferred up to 5 chained functions for full type safety. Beyond that, it falls back to the unknown.\n *\n * @param fns - A list of unary functions to compose.\n *\n * @returns A new function that applies all functions from left to right.\n *\n * @example\n * ```ts\n * const add = (x: number) => x + 1;\n * const double = (x: number) => x * 2;\n * const toStr = (x: number) => `Result: ${x}`;\n *\n * const result = pipe(add, double, toStr)(2);\n * // => 'Result: 6'\n * ```\n */\nexport const pipe: Pipe =\n (...fns: PipeFn[]) =>\n (arg: unknown) =>\n fns.reduce((prev, fn) => fn(prev), arg);\n\ntype ComposeFn = (arg: unknown) => unknown;\n\ntype Compose = {\n <A, R>(fn1: (a: A) => R): (a: A) => R;\n <A, B, R>(fn1: (b: B) => R, fn2: (a: A) => B): (a: A) => R;\n <A, B, C, R>(fn1: (c: C) => R, fn2: (b: B) => C, fn3: (a: A) => B): (a: A) => R;\n <A, B, C, D, R>(\n fn1: (d: D) => R,\n fn2: (c: C) => D,\n fn3: (b: B) => C,\n fn4: (a: A) => B,\n ): (a: A) => R;\n <A, B, C, D, E, R>(\n fn1: (e: E) => R,\n fn2: (d: D) => E,\n fn3: (c: C) => D,\n fn4: (b: B) => C,\n fn5: (a: A) => B,\n ): (a: A) => R;\n (...fns: ComposeFn[]): (arg: unknown) => unknown;\n};\n\n/**\n * Composes multiple unary functions into a single function, applying them from **right to left**.\n *\n * Often used for building functional pipelines where the innermost function runs first.\n * Types are inferred up to 5 chained functions for full type safety.\n *\n * @param fns - A list of unary functions to compose.\n *\n * @returns A new function that applies all functions from right to left.\n *\n * @example\n * ```ts\n * const add = (x: number) => x + 1;\n * const double = (x: number) => x * 2;\n * const toStr = (x: number) => `Result: ${x}`;\n *\n * const result = compose(toStr, double, add)(2);\n * // => 'Result: 6'\n * ```\n */\nexport const compose: Compose =\n (...fns: ComposeFn[]) =>\n (arg: unknown) =>\n fns.reduceRight((prev, fn) => fn(prev), arg);\n","import type { Nullable, TimeoutId } from './types';\n\nexport const noop = () => {};\n\n/**\n * Checks if a value is a function.\n *\n * @param value - The value to check.\n *\n * @returns `true` if the value is a function; otherwise, `false`.\n */\nexport const isFunction = (value: unknown) => typeof value === 'function';\n\n/**\n * Creates a function that negates the result of the given predicate function.\n *\n * @template Args - Argument types of the predicate function.\n *\n * @param fn - A function that returns any value.\n *\n * @returns A new function that returns the negated result of the original function.\n *\n * @example\n * ```ts\n * const isEven = (n: number) => n % 2 === 0;\n * const isOdd = not(isEven);\n *\n * console.log(isOdd(2)); // false\n * console.log(isOdd(3)); // true\n * ```\n */\nexport const not =\n <Args extends unknown[]>(fn: (...args: Args) => any): ((...args: Args) => boolean) =>\n (...args: Args) =>\n !fn(...args);\n\n/**\n * Invokes the given input if it is a function, passing the provided arguments.\n * Otherwise, returns the input as-is.\n *\n * @template Args - Tuple of argument types to pass to the function.\n * @template Result - Return type of the function or the value.\n *\n * @param input - A function to invoke with `args`, or a direct value of type `Result`.\n * @param args - Arguments to pass if `input` is a function.\n *\n * @returns The result of invoking the function, or the original value if it's not a function.\n */\nexport const invokeIfFunction = <Args extends unknown[], Result>(\n input: ((...args: Args) => Result) | Result,\n ...args: Args\n): Result => (typeof input === 'function' ? (input as (...args: Args) => Result)(...args) : input);\n\n/**\n * Creates a promise that resolves after the specified delay.\n *\n * Useful for creating artificial delays, implementing timeouts, or spacing operations.\n *\n * @param delayMs - The delay in milliseconds.\n *\n * @returns A promise that resolves after the specified delay.\n *\n * @example\n * ```ts\n * // Wait for 1 second\n * await delay(1000);\n * console.log('This logs after 1 second');\n *\n * // Use with other async operations\n * const fetchWithTimeout = async () => {\n * const timeoutPromise = delay(5000).then(() => {\n * throw new Error('Request timed out');\n * });\n *\n * return Promise.race([fetchData(), timeoutPromise]);\n * }\n * ```\n */\nexport const delay = (delayMs: number): Promise<void> =>\n new Promise(resolve => setTimeout(resolve, delayMs));\n\n/**\n * Wraps a promise with a timeout. If the promise does not settle within the specified time,\n * it will reject with a timeout error.\n *\n * @template T - The type of the promise result.\n *\n * @param promise - The promise to wrap.\n * @param timeoutMs - Timeout duration in milliseconds.\n * @param errorMessage - Optional custom error message.\n *\n * @returns A promise that resolves or rejects with the original promise,\n * or rejects with a timeout error if the duration is exceeded.\n *\n * @example\n * ```ts\n * // Rejects if fetch takes longer than 3 seconds\n * const response = await timeout(fetch('/api/data'), 3000);\n *\n * // With custom message\n * await timeout(fetchData(), 2000, 'Too long');\n * ```\n */\nexport const timeout = async <T>(\n promise: Promise<T>,\n timeoutMs: number,\n errorMessage = 'Operation timed out',\n): Promise<T> => {\n const timeoutId: Nullable<TimeoutId> = null;\n\n try {\n return await Promise.race([\n promise,\n delay(timeoutMs).then(() => Promise.reject(new Error(errorMessage))),\n ]);\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n};\n\ninterface RetryOptions {\n /**\n * Maximum number of retry attempts before failing.\n *\n * @default 3\n */\n maxAttempts?: number;\n /**\n * Delay in milliseconds between retry attempts.\n * If `backoff` is true, this is the base delay for exponential backoff.\n *\n * @default 300\n */\n delayMs?: number;\n /**\n * Whether to use exponential backoff for delays between attempts.\n * When enabled, the delay is multiplied by 2 ^ (`attempt` - 1).\n *\n * @default true\n */\n backoff?: boolean;\n /**\n * Optional callback triggered before each retry attempt.\n *\n * @param attempt - The current attempt number (starting from 1).\n * @param error - The error that caused the retry.\n */\n onRetry?: (attempt: number, error: unknown) => void;\n}\n\n/**\n * Wraps an asynchronous function with retry logic.\n *\n * The returned function will attempt to call the original function up to `maxAttempts` times,\n * with a delay between retries. If all attempts fail, the last encountered error is thrown.\n *\n * Useful for operations that may fail intermittently, such as network requests.\n *\n * @template Task - The type of the async function to wrap.\n * @template TaskResult - The result type of the async function.\n *\n * @param task - The async function to wrap with retry logic.\n * @param options - Configuration options for retry behavior.\n *\n * @returns A function that wraps the original function with retry support.\n *\n * @example\n * ```ts\n * async function fetchData() {\n * const response = await fetch('/api/data');\n *\n * if (!response.ok) {\n * throw new Error('Network error');\n * }\n *\n * return await response.json();\n * }\n *\n * const fetchWithRetry = retry(fetchData, {\n * maxAttempts: 5,\n * delayMs: 500,\n * onRetry: (attempt, error) => {\n * console.warn(`Attempt ${attempt} failed:`, error);\n * }\n * });\n *\n * fetchWithRetry()\n * .then(data => console.log('Success:', data))\n * .catch(error => console.error('Failed after retries:', error));\n * ```\n */\nexport const retry = <Task extends (...args: unknown[]) => Promise<TaskResult>, TaskResult>(\n task: Task,\n { maxAttempts = 3, delayMs = 300, backoff = true, onRetry }: RetryOptions = {},\n): ((...args: Parameters<Task>) => Promise<TaskResult>) => {\n return async (...args: Parameters<Task>): Promise<TaskResult> => {\n let lastError: unknown;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n return await task(...args);\n } catch (e) {\n lastError = e;\n\n if (attempt < maxAttempts) {\n onRetry?.(attempt, e);\n\n const delayTime = backoff ? delayMs * 2 ** (attempt - 1) : delayMs;\n await delay(delayTime);\n }\n }\n }\n\n throw lastError;\n };\n};\n\n/**\n * Wraps a function so that it can only be executed once.\n * The wrapped function remembers (caches) the result of the first invocation\n * and returns that same result for all subsequent calls, regardless of the arguments provided.\n *\n * Common use cases include:\n * - initializing singletons\n * - running setup logic only once\n * - avoiding repeated expensive computations\n *\n * @template T - A function type whose return value should be cached.\n *\n * @param fn - The function to execute at most once.\n *\n * @returns A new function with the same signature as `fn`, but guaranteed to\n * execute `fn` only on the first call and return the cached result\n * thereafter.\n */\nexport const once = <T extends (...args: any[]) => any>(fn: T): T => {\n let called = false;\n let result: ReturnType<T>;\n\n return function (this: any, ...args: Parameters<T>) {\n if (!called) {\n called = true;\n result = fn.apply(this, args);\n }\n\n return result;\n } as T;\n};\n","import type { Nullable } from './types';\nimport { compact } from './array';\nimport { isFunction } from './function';\n\n/**\n * Checks if a value is a Promise.\n *\n * @template T - The type of the value that the Promise resolves to.\n *\n * @param value - The value to check.\n *\n * @returns `true` if the value is a Promise; otherwise, `false`.\n */\nexport const isPromise = <T = unknown>(value: unknown): value is Promise<T> =>\n isFunction((value as Promise<T>)?.then);\n\n/**\n * Asynchronously iterates over an array and executes an async function on each item sequentially,\n * collecting the results.\n *\n * Useful when order or timing matters (e.g., rate limits, UI updates, animations).\n *\n * @param array - The array of items to iterate over.\n * @param fn - An async function to execute for each item. Must return a value.\n *\n * @returns A promise that resolves with an array of results from each function call.\n *\n * @example\n * ```ts\n * const results = await runSequential([1, 2, 3], async (item) => {\n * await delay(100);\n *\n * return item * 2;\n * });\n *\n * console.log(results); // [2, 4, 6]\n * ```\n */\nexport const runSequential = async <Item, Result>(\n array: Item[],\n fn: (item: Item, index: number, array: Item[]) => Promise<Result>,\n): Promise<Result[]> => {\n const results: Result[] = [];\n\n for (let i = 0; i < array.length; i++) {\n results.push(await fn(array[i], i, array));\n }\n\n return results;\n};\n\n/**\n * Executes an asynchronous operation on each element of an array and waits for all promises to resolve.\n *\n * @param array - The array of items to operate on.\n * @param fn - The asynchronous operation to perform on each item.\n *\n * @returns A promise that resolves with an array of results after all operations are completed.\n *\n * @example\n * ```ts\n * const results = await runParallel([1, 2, 3], async (item) => {\n * await delay(100);\n *\n * return item * 2;\n * });\n *\n * console.log(results); // [2, 4, 6]\n * ```\n */\nexport const runParallel = async <Item, Result>(\n array: Item[],\n fn: (item: Item, index: number, array: Item[]) => Promise<Result>,\n): Promise<Result[]> => Promise.all(array.map(fn));\n\n/**\n * Asynchronously filters an array using a predicate function, executing **sequentially**.\n *\n * Useful for rate-limited or stateful async operations where execution order matters.\n *\n * @template Item - The type of the items in the input array.\n *\n * @param array - The array of items to filter.\n * @param predicate - An async function that returns a `boolean` indicating whether to keep each item.\n *\n * @returns A promise that resolves to a new array containing only the items for which the predicate returned `true`.\n *\n * @example\n * ```ts\n * // Sequentially filter even numbers with delay\n * const result = await filterSequential([1, 2, 3, 4], async (num) => {\n * await delay(100);\n *\n * return num % 2 === 0;\n * });\n *\n * console.log(result); // [2, 4]\n * ```\n */\nexport const filterSequential = async <Item>(\n array: Item[],\n predicate: (item: Item, index: number, array: Item[]) => Promise<boolean>,\n): Promise<Item[]> => {\n const results: Item[] = [];\n\n for (let i = 0; i < array.length; i++) {\n const item = array[i];\n\n if (await predicate(item, i, array)) {\n results.push(item);\n }\n }\n\n return results;\n};\n\n/**\n * Asynchronously filters an array based on a provided async predicate function.\n *\n * Each item is passed to the `predicate` function in parallel, and only the items\n * for which the predicate resolves to `true` are included in the final result.\n *\n * Useful for filtering based on asynchronous conditions such as API calls,\n * file system access, or any other delayed operations.\n *\n * @template Item - The type of the items in the input array.\n *\n * @param array - The array of items to filter.\n * @param predicate - An async function that returns a boolean indicating whether to keep each item.\n *\n * @returns A promise that resolves to a new array containing only the items for which the predicate returned `true`.\n *\n * @example\n * ```ts\n * // Filter numbers that are even after a simulated delay\n * const result = await filterParallel([1, 2, 3, 4], async (num) => {\n * await delay(100);\n *\n * return num % 2 === 0;\n * });\n *\n * console.log(result); // [2, 4]\n * ```\n */\nexport const filterParallel = async <Item>(\n array: Item[],\n predicate: (item: Item, index: number, array: Item[]) => Promise<boolean>,\n): Promise<Item[]> => {\n const results = await runParallel(array, async (item, index, array) =>\n (await predicate(item, index, array)) ? item : false,\n );\n\n return compact(results);\n};\n\n/**\n * Asynchronously checks if at least one element in the array satisfies the async condition.\n *\n * @param array - The array of items to check.\n * @param predicate - An async function that returns a boolean.\n *\n * @returns A promise that resolves to true if any item passes the condition.\n */\nexport const someAsync = async <Item>(\n array: Item[],\n predicate: (item: Item, index: number, array: Item[]) => Promise<boolean>,\n): Promise<boolean> => {\n for (let i = 0; i < array.length; i++) {\n if (await predicate(array[i], i, array)) {\n return true;\n }\n }\n\n return false;\n};\n\n/**\n * Asynchronously checks if all elements in the array satisfy the async condition.\n *\n * @param array - The array of items to check.\n * @param predicate - An async function that returns a boolean.\n *\n * @returns A promise that resolves to true if all items pass the condition.\n */\nexport const everyAsync = async <Item>(\n array: Item[],\n predicate: (item: Item, index: number, array: Item[]) => Promise<boolean>,\n): Promise<boolean> => {\n for (let i = 0; i < array.length; i++) {\n if (!(await predicate(array[i], i, array))) {\n return false;\n }\n }\n\n return true;\n};\n\n/**\n * Asynchronously reduces an array to a single accumulated value.\n *\n * @template Item - The type of items in the array.\n * @template Accumulator - The type of the accumulated result.\n *\n * @param array - The array to reduce.\n * @param fn - The async reducer function that processes each item and returns the updated accumulator.\n * @param initialValue - The initial accumulator value.\n *\n * @returns A promise that resolves to the final accumulated result.\n */\nexport const reduceAsync = async <Item, Accumulator>(\n array: Item[],\n fn: (accumulator: Accumulator, item: Item, index: number, array: Item[]) => Promise<Accumulator>,\n initialValue: Accumulator,\n): Promise<Accumulator> => {\n let accumulator = initialValue;\n\n for (let i = 0; i < array.length; i++) {\n accumulator = await fn(accumulator, array[i], i, array);\n }\n\n return accumulator;\n};\n\n/**\n * Asynchronously finds the first element that satisfies the async condition.\n *\n * @param array - The array of items to search.\n * @param predicate - An async function that returns a boolean.\n *\n * @returns A promise that resolves to the found item or null if none match.\n */\nexport const findAsync = async <Item>(\n array: Item[],\n predicate: (item: Item, index: number, array: Item[]) => Promise<boolean>,\n): Promise<Nullable<Item>> => {\n for (let i = 0; i < array.length; i++) {\n if (await predicate(array[i], i, array)) {\n return array[i];\n }\n }\n\n return null;\n};\n","import { isNil } from './guards';\n\n/**\n * Checks if a value is a string.\n *\n * @param value - The value to check.\n *\n * @returns `true` if the value is a string; otherwise, `false`.\n */\nexport const isString = (value: unknown): value is string => typeof value === 'string';\n\n/**\n * Checks whether the provided value is considered \"empty\".\n *\n * A value is considered empty if it is:\n * - `null`\n * - `undefined`\n * - `''`\n *\n * @param value - The value to check.\n *\n * @returns `true` if the value is empty; otherwise, `false`.\n */\nexport const isNilOrEmptyString = (value: unknown): value is null | undefined =>\n value === '' || isNil(value);\n\n/**\n * Converts a string to kebab-case format.\n *\n * This function transforms camelCase or PascalCase strings into kebab-case by inserting\n * hyphens between lowercase and uppercase letters, then converting everything to lowercase.\n *\n * @param input - The string to convert to kebab-case.\n *\n * @returns The kebab-case formatted string.\n *\n * @example\n * ```ts\n * toKebabCase('helloWorld'); // → 'hello-world'\n * toKebabCase('HelloWorld'); // → 'hello-world'\n * toKebabCase('hello123World'); // → 'hello123-world'\n * ```\n */\nexport const toKebabCase = (input: string): string =>\n input.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();\n\n/**\n * Converts a camelCase string to dash-case format.\n *\n * This function transforms camelCase strings into dash-case by inserting\n * hyphens before uppercase letters and converting them to lowercase.\n * The function ensures that no hyphen is added at the start of the output string,\n * even if the input begins with an uppercase letter.\n *\n * @param input - The camelCase string to convert to dash-case.\n *\n * @returns The dash-case formatted string.\n *\n * @example\n * ```ts\n * camelToDashCase('helloWorld'); // → 'hello-world'\n * camelToDashCase('HelloWorld'); // → 'hello-world'\n * camelToDashCase('backgroundColor'); // → 'background-color'\n * ```\n */\nexport const camelToDashCase = (input: string): string => {\n // First handle the first character separately to avoid adding a hyphen at the start\n const firstChar = input.charAt(0);\n const restOfString = input.slice(1);\n\n // Convert the first character to lowercase without adding a hyphen\n const firstCharProcessed = firstChar.toLowerCase();\n\n // Process the rest of the string normally, adding hyphens before uppercase letters\n const restProcessed = restOfString.replace(/[A-Z]/g, letter => `-${letter.toLowerCase()}`);\n\n return firstCharProcessed + restProcessed;\n};\n\n/**\n * Splits a camelCase or PascalCase string into separate words with spaces.\n *\n * This function inserts spaces between lowercase and uppercase letters,\n * making camelCase or PascalCase strings more human-readable without\n * altering their original capitalization.\n *\n * @param input - The camelCase or PascalCase string to split into words.\n *\n * @returns The string with spaces inserted between words.\n *\n * @example\n * ```ts\n * camelToWords('helloWorld'); // → 'hello World'\n * camelToWords('HelloWorld'); // → 'Hello World'\n * camelToWords('userIDNumber'); // → 'user ID Number'\n * ```\n */\nexport const camelToWords = (input: string) => input.replace(/([a-z0-9])([A-Z])/g, '$1 $2');\n\n/**\n * Splits a string into an array of filtered from redundant spaces words.\n *\n * @param input - The input string to be split.\n *\n * @returns An array of words from the input string.\n */\nexport const splitStringIntoWords = (input: string): string[] => input.split(' ').filter(Boolean);\n\n/**\n * Generates a short, consistent hash string from an input string using a DJB2-inspired algorithm.\n *\n * This function uses a variation of the DJB2 algorithm, which is a simple yet effective hashing algorithm\n * based on bitwise XOR (`^`) and multiplication by 33. It produces a non-negative 32-bit integer,\n * which is then converted to a base-36 string (digits + lowercase letters) to produce a compact output.\n *\n * Useful for:\n * - Generating stable class names in CSS-in-JS libraries.\n * - Producing consistent cache keys.\n * - Quick and lightweight hashing needs where cryptographic security is not required.\n *\n * ⚠️ This is not cryptographically secure and should not be used for hashing passwords or sensitive data.\n *\n * @param input - The input string to hash.\n *\n * @returns A short, base-36 encoded hash string.\n *\n * @example\n * ```ts\n * const className = hashString('background-color: red;');\n * // → 'e4k1z0x'\n * ```\n */\nexport const hashString = (input: string): string => {\n let hash = 5381;\n\n for (let i = 0; i < input.length; i++) {\n hash = (hash * 33) ^ input.charCodeAt(i);\n }\n\n return (hash >>> 0).toString(36);\n};\n","/**\n * Calculates the Euclidean distance between two points in 2D space.\n *\n * @param startX - The X coordinate of the starting point.\n * @param startY - The Y coordinate of the starting point.\n * @param endX - The X coordinate of the ending point.\n * @param endY - The Y coordinate of the ending point.\n *\n * @returns The Euclidean distance between the two points.\n */\nexport const calculateEuclideanDistance = (\n startX: number,\n startY: number,\n endX: number,\n endY: number,\n): number => {\n const deltaX = endX - startX;\n const deltaY = endY - startY;\n\n return Math.hypot(deltaX, deltaY);\n};\n\n/**\n * Calculates the moving speed.\n *\n * @param distance - The distance.\n * @param elapsedTime - The time taken to move the distance.\n *\n * @returns The calculated speed, which is the absolute value of delta divided by elapsed time.\n */\nexport const calculateMovingSpeed = (distance: number, elapsedTime: number): number =>\n Math.abs(distance / elapsedTime);\n\n/**\n * Calculates the specified percentage of a given value.\n *\n * @param value - The value to calculate the percentage of.\n * @param percentage - The percentage to calculate.\n *\n * @returns The calculated percentage of the value.\n */\nexport const calculatePercentage = (value: number, percentage: number): number =>\n (value * percentage) / 100;\n","import type { Nullable } from './types';\nimport { assert, isUndefined } from './guards';\nimport { isString } from './string';\n\nexport const FOCUSABLE_HTML_TAGS = ['INPUT', 'SELECT', 'TEXTAREA', 'BUTTON', 'A'];\n\ninterface HTMLElementTransformationValues {\n translateX: number;\n translateY: number;\n scaleX: number;\n scaleY: number;\n skewX: number;\n skewY: number;\n}\n\n/**\n * Extracts transformation values (translate, scale, skew) from the 2D transformation matrix of a given HTML element.\n *\n * Only works with 2D transforms (i.e., `matrix(a, b, c, d, e, f)`).\n *\n * @param element - The element with a CSS transform applied.\n * @returns An object with parsed transformation values.\n *\n * @example\n * ```ts\n * const values = parse2DMatrix(myElement);\n * console.log(values.translateX);\n * console.log(values.scaleX);\n * ```\n */\nexport const parse2DMatrix = (element: HTMLElement): HTMLElementTransformationValues => {\n const computedStyles = window.getComputedStyle(element);\n const transformValue = computedStyles.getPropertyValue('transform');\n\n const matrixMatch = transformValue.match(/^matrix\\((.+)\\)$/);\n if (!matrixMatch) {\n return {\n translateX: 0,\n translateY: 0,\n scaleX: 1,\n scaleY: 1,\n skewX: 0,\n skewY: 0,\n };\n }\n\n const [scaleX, skewY, skewX, scaleY, translateX, translateY] = matrixMatch[1]\n .split(', ')\n .map(parseFloat);\n\n return {\n translateX,\n translateY,\n scaleX,\n scaleY,\n skewX,\n skewY,\n };\n};\n\n/**\n * Creates a clone of a Blob object.\n *\n * @param blob - The Blob object to clone.\n *\n * @returns A new Blob with the same content and type as the original.\n */\nexport const cloneBlob = (blob: Blob): Blob => new Blob([blob], { type: blob.type });\n\n/**\n * Calculates the intersection ratio between two DOM rectangles.\n *\n * The ratio represents the proportion of the `targetRect` that is covered by `sourceRect`.\n * A value of `1` means `sourceRect` completely covers `targetRect`, and `0` means no overlap.\n *\n * @param sourceRect - The rectangle used to measure overlap against the target.\n * @param targetRect - The rectangle whose covered area is measured.\n *\n * @returns A number between `0` and `1` representing the intersection ratio.\n */\nexport const getDOMRectIntersectionRatio = (sourceRect: DOMRect, targetRect: DOMRect): number => {\n const xOverlap = Math.max(\n 0,\n Math.min(sourceRect.right, targetRect.right) - Math.max(sourceRect.left, targetRect.left),\n );\n\n const yOverlap = Math.max(\n 0,\n Math.min(sourceRect.bottom, targetRect.bottom) - Math.max(sourceRect.top, targetRect.top),\n );\n\n const intersectionArea = xOverlap * yOverlap;\n const targetArea = targetRect.width * targetRect.height;\n\n return intersectionArea / targetArea;\n};\n\n/**\n * Returns the bounding DOMRect of an element based on offset and client dimensions.\n *\n * This utility is useful when you need a stable, layout-based rect\n * without triggering a reflow via `getBoundingClientRect()`.\n *\n * @param element - The target HTML element.\n * @returns A `DOMRect` representing the element’s offset position and size.\n */\nexport const getElementOffsetRect = (element: HTMLElement): DOMRect =>\n new DOMRect(element.offsetLeft, element.offsetTop, element.clientWidth, element.clientHeight);\n\n/**\n * Determines whether the given HTMLElement is an HTMLAnchorElement.\n *\n * Acts as a type guard so that TypeScript narrows `element` to\n * `HTMLAnchorElement` when the function returns `true`.\n *\n * An element qualifies as an anchor by having a tag name of `\"A\"`.\n *\n * @param element - The element to test.\n *\n * @returns Whether the element is an anchor element.\n */\nexport const isAnchorHtmlElement = (element: HTMLElement): element is HTMLAnchorElement =>\n element.tagName === 'A';\n\n/**\n * Checks whether an element is explicitly marked as contenteditable.\n *\n * Browsers treat elements with `contenteditable=\"true\"` as focusable,\n * even if they are not normally keyboard-focusable.\n *\n * @param element - The element to inspect.\n *\n * @returns True if `contenteditable=\"true\"` is set.\n */\nexport const isContentEditableHtmlElement = (element: HTMLElement) =>\n element.getAttribute('contenteditable') === 'true';\n\n/**\n * Determines whether an HTMLElement is focusable under standard browser rules.\n *\n * The function checks a combination of factors:\n * - The element must be rendered (not `display: none` or `visibility: hidden`).\n * - Disabled form cont