@fast-china/utils 1.0.37 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (286) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/CONTRIBUTING.md +87 -0
  3. package/README.md +111 -50
  4. package/README.zh.md +111 -50
  5. package/SECURITY.md +46 -0
  6. package/dist/array/index.d.mts +87 -0
  7. package/dist/array/index.d.mts.map +1 -0
  8. package/dist/array/index.mjs +161 -0
  9. package/dist/array/index.mjs.map +1 -0
  10. package/dist/async/index.d.mts +146 -0
  11. package/dist/async/index.d.mts.map +1 -0
  12. package/dist/async/index.mjs +336 -0
  13. package/dist/async/index.mjs.map +1 -0
  14. package/dist/base64/index.d.mts +105 -0
  15. package/dist/base64/index.d.mts.map +1 -0
  16. package/dist/base64/index.mjs +427 -0
  17. package/dist/base64/index.mjs.map +1 -0
  18. package/dist/color/index.d.mts +90 -0
  19. package/dist/color/index.d.mts.map +1 -0
  20. package/dist/color/index.mjs +178 -0
  21. package/dist/color/index.mjs.map +1 -0
  22. package/dist/crypto/index.d.mts +157 -0
  23. package/dist/crypto/index.d.mts.map +1 -0
  24. package/dist/crypto/index.mjs +541 -0
  25. package/dist/crypto/index.mjs.map +1 -0
  26. package/dist/date/index.d.mts +191 -0
  27. package/dist/date/index.d.mts.map +1 -0
  28. package/dist/date/index.mjs +383 -0
  29. package/dist/date/index.mjs.map +1 -0
  30. package/dist/dom/style.d.mts +30 -0
  31. package/dist/dom/style.d.mts.map +1 -0
  32. package/dist/dom/style.mjs +74 -0
  33. package/dist/dom/style.mjs.map +1 -0
  34. package/dist/env/index.d.mts +63 -0
  35. package/dist/env/index.d.mts.map +1 -0
  36. package/dist/env/index.mjs +97 -0
  37. package/dist/env/index.mjs.map +1 -0
  38. package/dist/identity/index.d.mts +78 -0
  39. package/dist/identity/index.d.mts.map +1 -0
  40. package/dist/identity/index.mjs +87 -0
  41. package/dist/identity/index.mjs.map +1 -0
  42. package/dist/index.d.mts +24 -0
  43. package/dist/index.mjs +23 -0
  44. package/dist/internal/text.mjs +36 -0
  45. package/dist/internal/text.mjs.map +1 -0
  46. package/dist/logger/index.d.mts +87 -0
  47. package/dist/logger/index.d.mts.map +1 -0
  48. package/dist/logger/index.mjs +124 -0
  49. package/dist/logger/index.mjs.map +1 -0
  50. package/dist/number/index.d.mts +89 -0
  51. package/dist/number/index.d.mts.map +1 -0
  52. package/dist/number/index.mjs +215 -0
  53. package/dist/number/index.mjs.map +1 -0
  54. package/dist/object/index.d.mts +76 -0
  55. package/dist/object/index.d.mts.map +1 -0
  56. package/dist/object/index.mjs +134 -0
  57. package/dist/object/index.mjs.map +1 -0
  58. package/dist/storage/index.d.mts +104 -0
  59. package/dist/storage/index.d.mts.map +1 -0
  60. package/dist/storage/index.mjs +324 -0
  61. package/dist/storage/index.mjs.map +1 -0
  62. package/dist/string/index.d.mts +130 -0
  63. package/dist/string/index.d.mts.map +1 -0
  64. package/dist/string/index.mjs +275 -0
  65. package/dist/string/index.mjs.map +1 -0
  66. package/dist/vue/emits.d.mts +24 -0
  67. package/dist/vue/emits.d.mts.map +1 -0
  68. package/dist/vue/emits.mjs +47 -0
  69. package/dist/vue/emits.mjs.map +1 -0
  70. package/dist/vue/expose.d.mts +12 -0
  71. package/dist/vue/expose.d.mts.map +1 -0
  72. package/dist/vue/expose.mjs +16 -0
  73. package/dist/vue/expose.mjs.map +1 -0
  74. package/dist/vue/func.d.mts +14 -0
  75. package/dist/vue/func.d.mts.map +1 -0
  76. package/dist/vue/func.mjs +16 -0
  77. package/dist/vue/func.mjs.map +1 -0
  78. package/dist/vue/index.d.mts +9 -0
  79. package/dist/vue/install.d.mts +69 -0
  80. package/dist/vue/install.d.mts.map +1 -0
  81. package/dist/vue/install.mjs +123 -0
  82. package/dist/vue/install.mjs.map +1 -0
  83. package/dist/vue/props.d.mts +23 -0
  84. package/dist/vue/props.d.mts.map +1 -0
  85. package/dist/vue/props.mjs +41 -0
  86. package/dist/vue/props.mjs.map +1 -0
  87. package/dist/vue/render.d.mts +13 -0
  88. package/dist/vue/render.d.mts.map +1 -0
  89. package/dist/vue/render.mjs +23 -0
  90. package/dist/vue/render.mjs.map +1 -0
  91. package/dist/vue/slots.d.mts +19 -0
  92. package/dist/vue/slots.d.mts.map +1 -0
  93. package/dist/vue/slots.mjs +13 -0
  94. package/dist/vue/slots.mjs.map +1 -0
  95. package/dist/vue/with.d.mts +12 -0
  96. package/dist/vue/with.d.mts.map +1 -0
  97. package/dist/vue/with.mjs +15 -0
  98. package/dist/vue/with.mjs.map +1 -0
  99. package/docs/API.md +96 -0
  100. package/docs/API.zh-CN.md +96 -0
  101. package/docs/DEVELOPMENT_RELEASE.zh-CN.md +65 -0
  102. package/docs/RUNTIME_CONTRACT.md +37 -0
  103. package/package.json +65 -73
  104. package/src/array/index.ts +173 -0
  105. package/src/async/index.ts +475 -0
  106. package/src/base64/index.ts +374 -0
  107. package/src/color/index.ts +208 -0
  108. package/src/crypto/index.ts +670 -0
  109. package/src/date/index.ts +451 -0
  110. package/src/dom/index.ts +6 -0
  111. package/src/dom/style.ts +92 -0
  112. package/src/env/index.ts +169 -0
  113. package/src/identity/index.ts +144 -0
  114. package/src/index.ts +20 -0
  115. package/src/internal/text.ts +46 -0
  116. package/src/logger/index.ts +219 -0
  117. package/src/number/index.ts +235 -0
  118. package/src/object/index.ts +160 -0
  119. package/src/storage/index.ts +524 -0
  120. package/src/string/index.ts +328 -0
  121. package/src/vue/emits.ts +71 -0
  122. package/src/vue/expose.ts +11 -0
  123. package/src/vue/func.ts +17 -0
  124. package/src/vue/index.ts +13 -0
  125. package/src/vue/install.ts +185 -0
  126. package/src/vue/props.ts +39 -0
  127. package/src/vue/render.ts +41 -0
  128. package/src/vue/slots.ts +23 -0
  129. package/src/vue/with.ts +10 -0
  130. package/Fast.png +0 -0
  131. package/dist/index.global.js +0 -14500
  132. package/dist/index.global.js.map +0 -1
  133. package/dist/index.global.min.js +0 -2
  134. package/dist/index.global.min.js.map +0 -1
  135. package/es/array/index.d.ts +0 -19
  136. package/es/array/index.mjs +0 -2
  137. package/es/array/index.mjs.map +0 -1
  138. package/es/base64/index.d.ts +0 -21
  139. package/es/base64/index.mjs +0 -2
  140. package/es/base64/index.mjs.map +0 -1
  141. package/es/click/index.d.ts +0 -33
  142. package/es/click/index.mjs +0 -2
  143. package/es/click/index.mjs.map +0 -1
  144. package/es/color/index.d.ts +0 -33
  145. package/es/color/index.mjs +0 -2
  146. package/es/color/index.mjs.map +0 -1
  147. package/es/console/index.d.ts +0 -31
  148. package/es/console/index.mjs +0 -2
  149. package/es/console/index.mjs.map +0 -1
  150. package/es/crypto/index.d.ts +0 -46
  151. package/es/crypto/index.mjs +0 -2
  152. package/es/crypto/index.mjs.map +0 -1
  153. package/es/date/index.d.ts +0 -44
  154. package/es/date/index.mjs +0 -2
  155. package/es/date/index.mjs.map +0 -1
  156. package/es/dom/index.d.ts +0 -1
  157. package/es/dom/index.mjs +0 -2
  158. package/es/dom/index.mjs.map +0 -1
  159. package/es/dom/style.d.ts +0 -12
  160. package/es/dom/style.mjs +0 -2
  161. package/es/dom/style.mjs.map +0 -1
  162. package/es/env/index.d.ts +0 -25
  163. package/es/env/index.mjs +0 -2
  164. package/es/env/index.mjs.map +0 -1
  165. package/es/error/index.d.ts +0 -3
  166. package/es/error/index.mjs +0 -2
  167. package/es/error/index.mjs.map +0 -1
  168. package/es/identity/index.d.ts +0 -14
  169. package/es/identity/index.mjs +0 -2
  170. package/es/identity/index.mjs.map +0 -1
  171. package/es/index.d.ts +0 -15
  172. package/es/index.es.d.ts +0 -2
  173. package/es/index.mjs +0 -2
  174. package/es/index.mjs.map +0 -1
  175. package/es/object/index.d.ts +0 -13
  176. package/es/object/index.mjs +0 -2
  177. package/es/object/index.mjs.map +0 -1
  178. package/es/storage/index.d.ts +0 -96
  179. package/es/storage/index.mjs +0 -2
  180. package/es/storage/index.mjs.map +0 -1
  181. package/es/string/index.d.ts +0 -114
  182. package/es/string/index.mjs +0 -2
  183. package/es/string/index.mjs.map +0 -1
  184. package/es/vue/emits.d.ts +0 -8
  185. package/es/vue/emits.mjs +0 -2
  186. package/es/vue/emits.mjs.map +0 -1
  187. package/es/vue/expose.d.ts +0 -4
  188. package/es/vue/expose.mjs +0 -2
  189. package/es/vue/expose.mjs.map +0 -1
  190. package/es/vue/func.d.ts +0 -6
  191. package/es/vue/func.mjs +0 -2
  192. package/es/vue/func.mjs.map +0 -1
  193. package/es/vue/index.d.ts +0 -8
  194. package/es/vue/index.mjs +0 -2
  195. package/es/vue/index.mjs.map +0 -1
  196. package/es/vue/install.d.ts +0 -5
  197. package/es/vue/install.mjs +0 -2
  198. package/es/vue/install.mjs.map +0 -1
  199. package/es/vue/props.d.ts +0 -9
  200. package/es/vue/props.mjs +0 -2
  201. package/es/vue/props.mjs.map +0 -1
  202. package/es/vue/slots.d.ts +0 -11
  203. package/es/vue/slots.mjs +0 -2
  204. package/es/vue/slots.mjs.map +0 -1
  205. package/es/vue/useRender.d.ts +0 -6
  206. package/es/vue/useRender.mjs +0 -2
  207. package/es/vue/useRender.mjs.map +0 -1
  208. package/es/vue/with.d.ts +0 -5
  209. package/es/vue/with.mjs +0 -2
  210. package/es/vue/with.mjs.map +0 -1
  211. package/lib/array/index.d.ts +0 -19
  212. package/lib/array/index.js +0 -2
  213. package/lib/array/index.js.map +0 -1
  214. package/lib/base64/index.d.ts +0 -21
  215. package/lib/base64/index.js +0 -2
  216. package/lib/base64/index.js.map +0 -1
  217. package/lib/click/index.d.ts +0 -33
  218. package/lib/click/index.js +0 -2
  219. package/lib/click/index.js.map +0 -1
  220. package/lib/color/index.d.ts +0 -33
  221. package/lib/color/index.js +0 -2
  222. package/lib/color/index.js.map +0 -1
  223. package/lib/console/index.d.ts +0 -31
  224. package/lib/console/index.js +0 -2
  225. package/lib/console/index.js.map +0 -1
  226. package/lib/crypto/index.d.ts +0 -46
  227. package/lib/crypto/index.js +0 -2
  228. package/lib/crypto/index.js.map +0 -1
  229. package/lib/date/index.d.ts +0 -44
  230. package/lib/date/index.js +0 -2
  231. package/lib/date/index.js.map +0 -1
  232. package/lib/dom/index.d.ts +0 -1
  233. package/lib/dom/index.js +0 -2
  234. package/lib/dom/index.js.map +0 -1
  235. package/lib/dom/style.d.ts +0 -12
  236. package/lib/dom/style.js +0 -2
  237. package/lib/dom/style.js.map +0 -1
  238. package/lib/env/index.d.ts +0 -25
  239. package/lib/env/index.js +0 -2
  240. package/lib/env/index.js.map +0 -1
  241. package/lib/error/index.d.ts +0 -3
  242. package/lib/error/index.js +0 -2
  243. package/lib/error/index.js.map +0 -1
  244. package/lib/identity/index.d.ts +0 -14
  245. package/lib/identity/index.js +0 -2
  246. package/lib/identity/index.js.map +0 -1
  247. package/lib/index.d.ts +0 -15
  248. package/lib/index.es.d.ts +0 -2
  249. package/lib/index.js +0 -2
  250. package/lib/index.js.map +0 -1
  251. package/lib/object/index.d.ts +0 -13
  252. package/lib/object/index.js +0 -2
  253. package/lib/object/index.js.map +0 -1
  254. package/lib/storage/index.d.ts +0 -96
  255. package/lib/storage/index.js +0 -2
  256. package/lib/storage/index.js.map +0 -1
  257. package/lib/string/index.d.ts +0 -114
  258. package/lib/string/index.js +0 -2
  259. package/lib/string/index.js.map +0 -1
  260. package/lib/vue/emits.d.ts +0 -8
  261. package/lib/vue/emits.js +0 -2
  262. package/lib/vue/emits.js.map +0 -1
  263. package/lib/vue/expose.d.ts +0 -4
  264. package/lib/vue/expose.js +0 -2
  265. package/lib/vue/expose.js.map +0 -1
  266. package/lib/vue/func.d.ts +0 -6
  267. package/lib/vue/func.js +0 -2
  268. package/lib/vue/func.js.map +0 -1
  269. package/lib/vue/index.d.ts +0 -8
  270. package/lib/vue/index.js +0 -2
  271. package/lib/vue/index.js.map +0 -1
  272. package/lib/vue/install.d.ts +0 -5
  273. package/lib/vue/install.js +0 -2
  274. package/lib/vue/install.js.map +0 -1
  275. package/lib/vue/props.d.ts +0 -9
  276. package/lib/vue/props.js +0 -2
  277. package/lib/vue/props.js.map +0 -1
  278. package/lib/vue/slots.d.ts +0 -11
  279. package/lib/vue/slots.js +0 -2
  280. package/lib/vue/slots.js.map +0 -1
  281. package/lib/vue/useRender.d.ts +0 -6
  282. package/lib/vue/useRender.js +0 -2
  283. package/lib/vue/useRender.js.map +0 -1
  284. package/lib/vue/with.d.ts +0 -5
  285. package/lib/vue/with.js +0 -2
  286. package/lib/vue/with.js.map +0 -1
package/CHANGELOG.md ADDED
@@ -0,0 +1,21 @@
1
+ # Changelog
2
+
3
+ All notable changes to Fast.Utils are documented in this file.
4
+
5
+ ## [2.0.0] - 2026-08-03
6
+
7
+ ### Added
8
+
9
+ - Named utilities for arrays, asynchronous control flow, Base64, colors, cryptography, dates, DOM styles, environment detection, identity, logging, numbers, objects, storage, and strings.
10
+ - Promise-aware cancellation, timeout, retry, bounded concurrency, debounce, and throttle primitives.
11
+ - Strict Base64/Base64URL, secure random generation, authenticated password encryption, RSA-OAEP, ECDSA, ECDH, and protocol-compatibility hash/AES functions.
12
+ - Browser and automatically detected uni-app Storage with TTL, codecs, namespace isolation, and cleanup.
13
+ - Optional Vue 2.7/3 entry with Composition API, typed emits/props/slots, render, and install helpers.
14
+ - Pure ESM ES2022 publishing with exact public subpaths, one root package, and one root `dist/` directory.
15
+ - Runtime, type-consumer, package-contract, Source Map, Tree Shaking, package-size, Publint, and CI validation.
16
+
17
+ ### Security
18
+
19
+ - Added authenticated ciphertext validation, bounded crypto parameters and payloads, unbiased Web Crypto randomness, prototype-safe query/object transforms, and namespace-scoped Storage cleanup.
20
+
21
+ [2.0.0]: https://github.com/China-xiaoFang/Fast.Utils/releases/tag/v2.0.0
@@ -0,0 +1,87 @@
1
+ # Contributing to Fast.Utils
2
+
3
+ Thank you for improving Fast.Utils. Contributions should make behavior more predictable, types more truthful, or supported workflows easier to verify.
4
+
5
+ ## Requirements
6
+
7
+ - Node.js `^22.18.0 || ^24.18.0`
8
+ - pnpm `^11.0.0` through Corepack
9
+ - Git with LF line endings
10
+
11
+ ```bash
12
+ corepack enable
13
+ pnpm install --frozen-lockfile
14
+ pnpm check
15
+ ```
16
+
17
+ Use `pnpm dev` when a long-running tsdown watch build is useful during implementation.
18
+
19
+ ## Design rules
20
+
21
+ - Prefer small named functions with explicit semantics over mutable utility singletons.
22
+ - Do not introduce global configuration, import-time platform access, or hidden logging.
23
+ - Keep the framework-neutral root independent from Vue.
24
+ - Do not add a production dependency when the platform or a small reviewed implementation is sufficient.
25
+ - Do not add ambiguous deep merge, string-path access, unbounded cache, or automatic retry behavior without a concrete contract and bounded risk.
26
+ - Treat serialized data, cryptographic formats, storage namespaces, package exports, runtime requirements, and peer ranges as public design decisions.
27
+ - Reject invalid input early. Do not silently return raw or partially parsed data after corruption.
28
+
29
+ ## Public API checklist
30
+
31
+ Every new public function, type, interface, class, method, or option must include TSDoc covering the applicable items:
32
+
33
+ - purpose and non-obvious design rationale;
34
+ - type parameters, parameters, defaults, units, and accepted ranges;
35
+ - return value, ordering, mutation, allocation, and empty-input behavior;
36
+ - native error classes, `name`, `cause`, and failure semantics;
37
+ - cancellation, concurrency, cleanup, and ownership semantics;
38
+ - browser, Vue, or uni-app runtime restrictions;
39
+ - security boundaries and common misuse risks;
40
+ - a focused example when the signature alone is insufficient.
41
+
42
+ Comments should explain why a choice exists. Do not repeat obvious syntax or add comments only to increase volume.
43
+
44
+ ## Tests
45
+
46
+ - Add a regression test for every defect.
47
+ - Test successful calls, invalid input, empty input, boundary values, and relevant cancellation or platform branches.
48
+ - Add compile-only cases to `tests/public-api.test.ts` for inference and rejected calls.
49
+ - Avoid tests that execute code without asserting meaningful behavior.
50
+ - Keep tests deterministic; inject clocks, storage, sinks, identifiers, and signals where supported.
51
+
52
+ Run the narrowest relevant command during development, then run the full set before opening a pull request:
53
+
54
+ ```bash
55
+ pnpm typecheck
56
+ pnpm test
57
+ pnpm test:types
58
+ pnpm lint
59
+ pnpm format:check
60
+ pnpm build
61
+ pnpm test:package
62
+ ```
63
+
64
+ ## Dependencies
65
+
66
+ Development tools use reviewed caret ranges and are resolved exactly by `pnpm-lock.yaml`. Before changing a tool version:
67
+
68
+ 1. verify Node.js and peer requirements;
69
+ 2. review release notes and security advisories;
70
+ 3. regenerate only the lock file with the pinned pnpm version;
71
+ 4. run type, lint, test, build, package-consumer, audit, and dry-run checks;
72
+ 5. avoid unrelated upgrades in the same pull request.
73
+
74
+ This repository intentionally defines its own ESLint Flat Config and must not depend on `@fast-china/eslint-config`.
75
+
76
+ ## Pull requests
77
+
78
+ - Keep the diff focused and avoid repository-wide formatting unrelated to the change.
79
+ - Update English and Chinese docs for user-visible behavior.
80
+ - Add a dated `CHANGELOG.md` entry only when preparing a release.
81
+ - Describe API, runtime, package-entry, type, security, and size impact.
82
+ - Never include credentials, private endpoints, connection strings, or production data.
83
+ - Do not publish, tag, push, or deploy from a contribution workflow.
84
+
85
+ ## Security reports
86
+
87
+ Do not open a public issue for a suspected vulnerability. Follow [SECURITY.md](./SECURITY.md).
package/README.md CHANGED
@@ -1,83 +1,144 @@
1
- [中](https://gitee.com/FastDotnet/Fast.Utils) | **En**
2
-
3
- <h1 align="center">Fast.Utils</h1>
4
-
5
- <p align="center">
6
- <code>Fast</code> platform An util library built based on <code>TypeScript</code>.
1
+ <p align="left">
2
+ <a href="./README.zh.md">简体中文</a> | <strong>English</strong>
7
3
  </p>
8
4
 
9
5
  <p align="center">
10
- <a href="https://www.npmjs.com/package/@fast-china/utils">
11
- <img src="https://img.shields.io/npm/v/@fast-china/utils?color=orange&label=" alt="version" />
12
- </a>
13
- <a href="https://gitee.com/FastDotnet/Fast.Utils/blob/master/LICENSE">
14
- <img src="https://img.shields.io/npm/l/@fast-china/utils" alt="license" />
15
- </a>
6
+ <img src="./Fast.png" alt="logo" width="160" />
16
7
  </p>
17
8
 
18
- ## Install
9
+ # @fast-china/utils
10
+
11
+ Browser-first TypeScript utilities for modern browsers, WebViews, Vue 2.7/3, and uni-app.
19
12
 
20
- #### Using a Package Manager
13
+ [![npm version](https://img.shields.io/npm/v/@fast-china/utils?color=orange)](https://www.npmjs.com/package/@fast-china/utils) [![node](https://img.shields.io/badge/node-%5E22.18%20%7C%7C%20%5E24.18-brightgreen)](https://nodejs.org/) [![vue](https://img.shields.io/badge/vue-%5E2.7%20%7C%7C%20%5E3.3-42b883)](https://vuejs.org/) [![license](https://img.shields.io/npm/l/@fast-china/utils)](./LICENSE)
21
14
 
22
- ```sh
23
- # Choose a package manager of your choice
15
+ ## Highlights
24
16
 
25
- # NPM
26
- npm install @fast-china/utils
17
+ - Typed, side-effect-free utilities with one named-export entry for effective Tree Shaking.
18
+ - Browser, WebView, Vue 2.7/3, and uni-app contracts without import-time platform access.
19
+ - Explicit security boundaries for storage, identity, encoding, random generation, and cryptography.
20
+ - TypeScript 6 strict checks, ESLint, runtime tests, consumer type tests, package validation, and Publint.
21
+
22
+ ## Install
23
+
24
+ ```bash
25
+ pnpm add @fast-china/utils
26
+ ```
27
27
 
28
- # Yarn
29
- yarn add @fast-china/utils
28
+ Install the optional Vue peer only when using Vue helpers:
30
29
 
31
- # pnpm (recommend)
32
- pnpm install @fast-china/utils
30
+ ```bash
31
+ pnpm add vue
33
32
  ```
34
33
 
35
- ## Update log
34
+ Supported peer range: Vue `^2.7.0 || ^3.3.0`. Vue 2.6 and Vue 3.0-3.2 are outside the declared range.
36
35
 
37
- Update log [Click to view](https://gitee.com/FastDotnet/Fast.Utils/commits/master)
36
+ ## Storage
38
37
 
39
- ## Protocol
38
+ Configure storage exactly once from the browser application entry:
40
39
 
41
- [Fast.Utils](https://gitee.com/FastDotnet/Fast.Utils) complies with the [Apache-2.0](https://gitee.com/FastDotnet/Fast.Utils/blob/master/LICENSE) open source agreement. Welcome to submit `PR` or `Issue`.
40
+ ```ts
41
+ import { configureStorage } from "@fast-china/utils";
42
42
 
43
+ configureStorage({
44
+ prefix: "my-app:",
45
+ });
43
46
  ```
44
- Apache Open Source License
45
47
 
46
- Copyright © 2018-Now xiaoFang
48
+ Every other module imports the stable package exports directly:
47
49
 
48
- License:
49
- This Agreement grants any individual or organization that obtains a copy of this software and its related documentation (hereinafter referred to as the "Software").
50
- Subject to the terms of this Agreement, you have the right to use, copy, modify, merge, publish, distribute, sublicense, and sell copies of the Software:
51
- 1.All copies or major parts of the Software must retain this Copyright Notice and this License Agreement.
52
- 2.The use, copying, modification, or distribution of the Software shall not violate applicable laws or infringe upon the legitimate rights and interests of others.
53
- 3.Modified or derivative works must clearly indicate the original author and the source of the original Software.
50
+ ```ts
51
+ import { Local, Session } from "@fast-china/utils";
54
52
 
55
- Special Statement:
56
- - This Software is provided "as is" without any express or implied warranty of any kind, including but not limited to the warranty of merchantability, fitness for purpose, and non-infringement.
57
- - In no event shall the author or copyright holder be liable for any direct or indirect loss caused by the use or inability to use this Software.
58
- - Including but not limited to data loss, business interruption, etc.
53
+ Local.set("user", { id: 1 }, { ttlMs: 30 * 60 * 1000 });
54
+ const user = Local.get<{ id: number }>("user");
59
55
 
60
- Disclaimer:
61
- It is prohibited to use this software to engage in illegal activities such as endangering national security, disrupting social order, or infringing on the legitimate rights and interests of others.
62
- The author does not assume any responsibility for any legal disputes and liabilities caused by the secondary development of this software.
56
+ Session.set("redirect", "/home");
63
57
  ```
64
58
 
65
- ## Disclaimer
59
+ The configuration is immutable after the first call. Repeating the same configuration is idempotent; a conflicting configuration throws.
66
60
 
61
+ In uni-app, the same configuration automatically uses the global `uni` synchronous Storage API:
62
+
63
+ ```ts
64
+ import { configureStorage } from "@fast-china/utils";
65
+
66
+ configureStorage({
67
+ prefix: "my-app:",
68
+ });
67
69
  ```
68
- Please do not use it for projects that violate our country's laws
70
+
71
+ uni-app uses `Local`; `Session` throws because uni-app has no sessionStorage equivalent. `clear()` removes only keys inside the configured prefix. The optional `base64StorageCodec` is reversible obfuscation, not encryption.
72
+
73
+ ## Base64
74
+
75
+ Prefer the UTF-8 or Base64URL APIs in new code:
76
+
77
+ ```ts
78
+ import { decodeBase64, encodeBase64, encodeBase64Url } from "@fast-china/utils";
79
+
80
+ const encoded = encodeBase64("Fast utilities");
81
+ decodeBase64(encoded);
82
+ encodeBase64Url("path/value");
69
83
  ```
70
84
 
71
- ## Contributors
85
+ `encodeSecureBase64` and `decodeSecureBase64` exist only for the legacy dictionary format. Given the same default six-character prefix, valid legacy payloads remain byte-for-byte identical. A historical Base64-length 101–124 dictionary gap uses a one-character fallback that the legacy removal flow understands. This format is not encryption and must not protect passwords, tokens, or other secrets.
86
+
87
+ ## Identity
72
88
 
73
- Thank you for all their contributions!
89
+ ```ts
90
+ import { configureInstallationIdentity, getOrCreateInstallationId } from "@fast-china/utils";
74
91
 
75
- <a href="https://github.com/China-xiaoFang/Fast.Utils/graphs/contributors">
76
- <img src="https://contrib.rocks/image?repo=China-xiaoFang/Fast.Utils" />
77
- </a>
92
+ configureInstallationIdentity({ cacheKey: "account:installation-id" });
78
93
 
79
- ## Supplementary instructions
94
+ const installationId = getOrCreateInstallationId();
95
+ ```
96
+
97
+ Call `configureInstallationIdentity` in the application entry before first use. The default business key is `identity:installation-id`; repeated identical configuration is idempotent and conflicting configuration throws. Installation Identity uses the configured `Local` storage and Web Crypto UUID v4 generation. It never falls back to `Math.random()`.
98
+
99
+ ## Vue 2.7 and Vue 3
80
100
 
101
+ ```ts
102
+ import { useEmits, useProps, withInstall } from "@fast-china/utils";
81
103
  ```
82
- If it is helpful to you, you can click ⭐Star in the upper right corner to collect it and get the latest updates. Thank you!
104
+
105
+ The package provides structural plugin registration compatible with Vue 2.7 `Vue.use()` and Vue 3 `app.use()`, Composition API helpers, typed props/emits/slots, and TSX rendering. Vue remains external to the bundle and is declared as an optional peer dependency. `makeSlots` uses Vue 3's official `SlotsType` and is intended for Vue 3 components.
106
+
107
+ ## Modules
108
+
109
+ `@fast-china/utils` is the only public entry and exposes every API as a named export. Source modules remain separate in `dist/` so modern bundlers can remove unused exports; those internal files are not public package subpaths.
110
+
111
+ Historical aggregate objects are not public. Their behavior is available through named functions, improving auto-imports and Tree Shaking.
112
+
113
+ ## Runtime contract
114
+
115
+ - Pure ESM; no CommonJS, UMD, or IIFE.
116
+ - ES2022 modern browsers and WebViews.
117
+ - Vue 2.7 or Vue 3 through an optional peer.
118
+ - uni-app through automatic global `uni` detection when Storage is configured.
119
+ - No import-time access to `window`, Storage, or `uni`; unsupported calls fail explicitly.
120
+ - Web Crypto, URL, Intl, TextEncoder, and related platform capabilities are not polyfilled.
121
+
122
+ ## Documentation
123
+
124
+ - [API reference](./docs/API.md)
125
+ - [Runtime contract](./docs/RUNTIME_CONTRACT.md)
126
+ - [Development and release guide (Chinese)](./docs/DEVELOPMENT_RELEASE.zh-CN.md)
127
+ - [Security policy](./SECURITY.md)
128
+ - [Contributing guide](./CONTRIBUTING.md)
129
+ - [Changelog](./CHANGELOG.md)
130
+
131
+ ## Development
132
+
133
+ Development requires Node.js `^22.18.0 || ^24.18.0` and pnpm `^11.0.0`.
134
+
135
+ ```bash
136
+ pnpm install --frozen-lockfile
137
+ pnpm check
83
138
  ```
139
+
140
+ Use `pnpm dev` for a long-running tsdown watch build while editing source files.
141
+
142
+ ## License
143
+
144
+ [Apache-2.0](./LICENSE)
package/README.zh.md CHANGED
@@ -1,83 +1,144 @@
1
- **中** | [En](https://github.com/China-xiaoFang/fast.utils)
2
-
3
- <h1 align="center">Fast.Utils</h1>
4
-
5
- <p align="center">
6
- <code>Fast</code> 平台下基于 <code>TypeScript</code> 构建的工具库。
1
+ <p align="left">
2
+ <strong>简体中文</strong> | <a href="./README.md">English</a>
7
3
  </p>
8
4
 
9
5
  <p align="center">
10
- <a href="https://www.npmjs.com/package/@fast-china/utils">
11
- <img src="https://img.shields.io/npm/v/@fast-china/utils?color=orange&label=" alt="version" />
12
- </a>
13
- <a href="https://gitee.com/FastDotnet/Fast.Utils/blob/master/LICENSE">
14
- <img src="https://img.shields.io/npm/l/@fast-china/utils" alt="license" />
15
- </a>
6
+ <img src="./Fast.png" alt="logo" width="160" />
16
7
  </p>
17
8
 
18
- ## 安装
9
+ # @fast-china/utils
10
+
11
+ 面向现代浏览器、WebView、Vue 2.7/3 与 uni-app 的 TypeScript 前端工具库。
19
12
 
20
- #### 使用包管理器
13
+ [![npm 版本](https://img.shields.io/npm/v/@fast-china/utils?color=orange)](https://www.npmjs.com/package/@fast-china/utils) [![node](https://img.shields.io/badge/node-%5E22.18%20%7C%7C%20%5E24.18-brightgreen)](https://nodejs.org/) [![Vue](https://img.shields.io/badge/vue-%5E2.7%20%7C%7C%20%5E3.3-42b883)](https://vuejs.org/) [![开源协议](https://img.shields.io/npm/l/@fast-china/utils)](./LICENSE)
21
14
 
22
- ```sh
23
- # 选择一个你喜欢的包管理器
15
+ ## 特性
24
16
 
25
- # NPM
26
- npm install @fast-china/utils
17
+ - 提供完整类型、无副作用实现和统一具名导出入口,便于 Tree Shaking。
18
+ - 明确支持浏览器、WebView、Vue 2.7/3 与 uni-app,导入阶段不访问平台全局对象。
19
+ - 为 Storage、安装标识、编码、安全随机数与密码学能力划定清晰的安全边界。
20
+ - 使用 TypeScript 6 严格检查、ESLint、运行时测试、消费者类型测试、包契约与 Publint 共同验证。
21
+
22
+ ## 安装
23
+
24
+ ```bash
25
+ pnpm add @fast-china/utils
26
+ ```
27
27
 
28
- # Yarn
29
- yarn add @fast-china/utils
28
+ 使用 Vue 工具时由应用安装 Vue:
30
29
 
31
- # pnpm(推荐)
32
- pnpm install @fast-china/utils
30
+ ```bash
31
+ pnpm add vue
33
32
  ```
34
33
 
35
- ## 更新日志
34
+ Peer 范围为 Vue `^2.7.0 || ^3.3.0`。Vue 2.6 与 Vue 3.0-3.2 不在声明范围内。
36
35
 
37
- 更新日志 [点击查看](https://gitee.com/FastDotnet/Fast.Utils/commits/master)
36
+ ## Storage
38
37
 
39
- ## 协议
38
+ 只在浏览器程序入口配置一次:
40
39
 
41
- [Fast.Utils](https://gitee.com/FastDotnet/Fast.Utils) 遵循 [Apache-2.0](https://gitee.com/FastDotnet/Fast.Utils/blob/master/LICENSE) 开源协议,欢迎大家提交 `PR` 或 `Issue`。
40
+ ```ts
41
+ import { configureStorage } from "@fast-china/utils";
42
42
 
43
+ configureStorage({
44
+ prefix: "my-app:",
45
+ });
43
46
  ```
44
- Apache开源许可证
45
47
 
46
- 版权所有 © 2018-Now 小方
48
+ 其他业务文件直接引用包:
47
49
 
48
- 许可授权:
49
- 本协议授予任何获得本软件及其相关文档(以下简称“软件”)副本的个人或组织。
50
- 在遵守本协议条款的前提下,享有使用、复制、修改、合并、发布、分发、再许可、销售软件副本的权利:
51
- 1.所有软件副本或主要部分必须保留本版权声明及本许可协议。
52
- 2.软件的使用、复制、修改或分发不得违反适用法律或侵犯他人合法权益。
53
- 3.修改或衍生作品须明确标注原作者及原软件出处。
50
+ ```ts
51
+ import { Local, Session } from "@fast-china/utils";
54
52
 
55
- 特别声明:
56
- - 本软件按“原样”提供,不提供任何形式的明示或暗示的保证,包括但不限于对适销性、适用性和非侵权的保证。
57
- - 在任何情况下,作者或版权持有人均不对因使用或无法使用本软件导致的任何直接或间接损失的责任。
58
- - 包括但不限于数据丢失、业务中断等情况。
53
+ Local.set("user", { id: 1 }, { ttlMs: 30 * 60 * 1000 });
54
+ const user = Local.get<{ id: number }>("user");
59
55
 
60
- 免责条款:
61
- 禁止利用本软件从事危害国家安全、扰乱社会秩序或侵犯他人合法权益等违法活动。
62
- 对于基于本软件二次开发所引发的任何法律纠纷及责任,作者不承担任何责任。
56
+ Session.set("redirect", "/home");
63
57
  ```
64
58
 
65
- ## 免责申明
59
+ 首次配置后不可变;相同配置重复调用保持幂等,不同配置会抛错。
66
60
 
61
+ 在 uni-app 中,同一配置会自动使用全局 `uni` 的同步 Storage API:
62
+
63
+ ```ts
64
+ import { configureStorage } from "@fast-china/utils";
65
+
66
+ configureStorage({
67
+ prefix: "my-app:",
68
+ });
67
69
  ```
68
- 请勿用于违反我国法律的项目上
70
+
71
+ uni-app 使用 `Local`;由于不存在等价的 sessionStorage,调用 `Session` 会明确抛错。`clear()` 只清理当前前缀。可选的 `base64StorageCodec` 只是可逆混淆,不是加密。
72
+
73
+ ## Base64
74
+
75
+ 新代码优先使用 UTF-8 或 Base64URL API:
76
+
77
+ ```ts
78
+ import { decodeBase64, encodeBase64, encodeBase64Url } from "@fast-china/utils";
79
+
80
+ const encoded = encodeBase64("Fast 工具库");
81
+ decodeBase64(encoded);
82
+ encodeBase64Url("path/参数");
69
83
  ```
70
84
 
71
- ## 贡献者
85
+ `encodeSecureBase64` / `decodeSecureBase64` 仅用于兼容旧字典格式。给定相同的默认 6 字符前缀时,有效旧载荷保持逐字符一致;历史字典无法自解码的 101–124 字符 Base64 区间使用旧删除流程可识别的单字符回退。它不是加密,不应用于密码、Token 或其他秘密。
86
+
87
+ ## 安装实例标识
72
88
 
73
- 感谢他们的所做的一切贡献!
89
+ ```ts
90
+ import { configureInstallationIdentity, getOrCreateInstallationId } from "@fast-china/utils";
74
91
 
75
- <a href="https://github.com/China-xiaoFang/Fast.Utils/graphs/contributors">
76
- <img src="https://contrib.rocks/image?repo=China-xiaoFang/Fast.Utils" />
77
- </a>
92
+ configureInstallationIdentity({ cacheKey: "account:installation-id" });
78
93
 
79
- ## 补充说明
94
+ const installationId = getOrCreateInstallationId();
95
+ ```
96
+
97
+ 在程序入口、首次使用安装标识前调用 `configureInstallationIdentity`。默认业务键是 `identity:installation-id`;相同配置可幂等重复调用,不同配置会抛错。安装标识使用已配置的 `Local` 和 Web Crypto UUID v4,不回退 `Math.random()`。它不是硬件 ID、认证凭证或风控信号。
98
+
99
+ ## Vue 2.7 与 Vue 3
80
100
 
101
+ ```ts
102
+ import { useEmits, useProps, withInstall } from "@fast-china/utils";
81
103
  ```
82
- 如果对您有帮助,您可以点右上角 ⭐Star 收藏一下 ,获取第一时间更新,谢谢!
104
+
105
+ 包内提供结构化插件注册,同时兼容 Vue 2.7 `Vue.use()` 与 Vue 3 `app.use()`,并提供 Composition API、Props/Emits/Slots 类型和 TSX 渲染。Vue 不会打进本包产物,并声明为可选 Peer Dependency。`makeSlots` 使用 Vue 3 官方 `SlotsType`,仅供 Vue 3 组件使用。
106
+
107
+ ## 模块
108
+
109
+ `@fast-china/utils` 是唯一公开入口,全部 API 都通过具名导出提供。源码模块仍会在 `dist/` 中独立保留,便于现代打包器移除未使用代码,但这些内部文件不是公开子路径。
110
+
111
+ 历史聚合对象不再公开,其功能全部通过具名函数提供,便于自动导入与 Tree Shaking。
112
+
113
+ ## 运行时契约
114
+
115
+ - 仅纯 ESM,不提供 CommonJS、UMD 或 IIFE。
116
+ - 面向 ES2022 现代浏览器与 WebView。
117
+ - Vue 2.7 或 Vue 3 通过可选 Peer 接入。
118
+ - 配置 Storage 时自动检测全局 `uni` 并接入 uni-app。
119
+ - 导入阶段不访问 `window`、Storage 或 `uni`;不支持的调用明确失败。
120
+ - 不注入 Web Crypto、URL、Intl、TextEncoder 等 Polyfill。
121
+
122
+ ## 文档
123
+
124
+ - [API 文档](./docs/API.zh-CN.md)
125
+ - [运行时契约](./docs/RUNTIME_CONTRACT.md)
126
+ - [开发与发布](./docs/DEVELOPMENT_RELEASE.zh-CN.md)
127
+ - [安全策略](./SECURITY.md)
128
+ - [贡献指南](./CONTRIBUTING.md)
129
+ - [更新日志](./CHANGELOG.md)
130
+
131
+ ## 开发
132
+
133
+ 开发工具链要求 Node.js `^22.18.0 || ^24.18.0` 与 pnpm `^11.0.0`。
134
+
135
+ ```bash
136
+ pnpm install --frozen-lockfile
137
+ pnpm check
83
138
  ```
139
+
140
+ 修改源码时可使用 `pnpm dev` 启动长期运行的 tsdown 监听构建。
141
+
142
+ ## 许可证
143
+
144
+ [Apache-2.0](./LICENSE)
package/SECURITY.md ADDED
@@ -0,0 +1,46 @@
1
+ # Security Policy
2
+
3
+ ## Supported releases
4
+
5
+ Security fixes are provided for the latest stable release. Pre-release builds and unsupported runtime combinations receive best-effort investigation only.
6
+
7
+ ## Reporting a vulnerability
8
+
9
+ Use the repository's private GitHub Security Advisory reporting flow. Do not disclose the issue publicly until a fix and coordinated disclosure plan are available.
10
+
11
+ Include:
12
+
13
+ - affected package version and public API;
14
+ - runtime, browser, framework, and platform;
15
+ - minimal reproduction without real credentials or user data;
16
+ - expected and observed impact;
17
+ - whether untrusted input, authentication, storage, or cryptography is involved.
18
+
19
+ Maintainers should acknowledge a complete report within five business days. Timelines depend on severity, reproducibility, affected platforms, and release coordination.
20
+
21
+ ## Security boundaries
22
+
23
+ Fast.Utils is a utility library, not a complete security system.
24
+
25
+ - `encryptText` provides authenticated encryption for caller-owned text up to 8 MiB of UTF-8 with a caller-owned password. It does not provide KMS, key rotation, account recovery, rate limiting, or protocol negotiation.
26
+ - `sha256` is a fast digest and must not be used directly for password storage.
27
+ - `timingSafeEqual` avoids explicit early exit, but JavaScript engines cannot guarantee strict constant-time execution.
28
+ - Base64 and Base64URL are encodings, not encryption.
29
+ - Web Storage is readable by same-origin script and must not contain passwords, private keys, or long-lived credentials.
30
+ - Installation IDs are local convenience identifiers, not authentication, hardware identity, or fraud signals.
31
+ - User-Agent detection is heuristic and must not drive authorization or trust decisions.
32
+ - `escapeHtml` is limited to HTML text context and is not a general sanitizer.
33
+ - `serializeStyle` converts trusted structures and does not sanitize untrusted CSS.
34
+ - Logger calls must not receive passwords, tokens, keys, connection strings, or complete personal data.
35
+
36
+ ## Supply chain and release controls
37
+
38
+ - The runtime package allows only the reviewed `crypto-js` production dependency; package checks enforce this allowlist.
39
+ - Development dependencies are exact and locked.
40
+ - CI runs frozen installation, lint, strict type checks, tests, build, package consumers, and package inspection.
41
+ - The release gate validates package metadata, changelog/version consistency, build output, consumers, and the npm archive before publication.
42
+ - Release workflows use pinned action commits and do not persist checkout credentials.
43
+
44
+ ## Handling secrets
45
+
46
+ No secret is required to build or test the repository. Never commit npm tokens, GitHub tokens, signing keys, private registry credentials, `.env` files, production logs, or encrypted data whose password is available in the same repository.
@@ -0,0 +1,87 @@
1
+ //#region src/array/index.d.ts
2
+ /** 从数组项中提取可比较键的函数。 */
3
+ type KeySelector<Item, Key> = (item: Item, index: number) => Key;
4
+ /**
5
+ * 将只读数组按固定大小分组。
6
+ *
7
+ * @typeParam Item - 数组项类型。
8
+ * @param items - 不会被修改的输入数组。
9
+ * @param size - 每组最多包含的项目数,必须是正安全整数。
10
+ * @returns 新建的二维数组;最后一组可能小于 `size`。
11
+ * @throws `RangeError` 当 `size` 不是正安全整数。
12
+ */
13
+ declare function chunk<Item>(items: readonly Item[], size: number): Item[][];
14
+ /**
15
+ * 删除数组中的 `null` 与 `undefined`,保留 `false`、`0` 和空字符串。
16
+ *
17
+ * @param items - 可包含空值的只读数组。
18
+ * @returns 保持原顺序的新数组。
19
+ */
20
+ declare function removeNullishValues<Item>(items: readonly (Item | null | undefined)[]): Item[];
21
+ /**
22
+ * 使用 JavaScript `Set` 的 SameValueZero 语义去重。
23
+ *
24
+ * @param items - 不会被修改的输入数组。
25
+ * @returns 保留每个值首次出现顺序的新数组;稀疏数组空位被忽略。
26
+ */
27
+ declare function unique<Item>(items: readonly Item[]): Item[];
28
+ /**
29
+ * 按选择器返回的键去重。
30
+ *
31
+ * @param items - 不会被修改的输入数组。
32
+ * @param selectKey - 接收项目与索引并返回去重键的函数。
33
+ * @returns 保留每个键首次出现项目的新数组;稀疏数组空位被忽略。
34
+ */
35
+ declare function uniqueBy<Item, Key>(items: readonly Item[], selectKey: KeySelector<Item, Key>): Item[];
36
+ /**
37
+ * 按选择器结果分组。
38
+ *
39
+ * @param items - 不会被修改的输入数组。
40
+ * @param selectKey - 返回任意 `Map` 键的函数。
41
+ * @returns 按键首次出现顺序排列的 `Map`;每个分组保持输入顺序,稀疏空位被忽略。
42
+ */
43
+ declare function groupBy<Item, Key>(items: readonly Item[], selectKey: KeySelector<Item, Key>): Map<Key, Item[]>;
44
+ /**
45
+ * 按谓词把数组拆分为匹配项和非匹配项。
46
+ *
47
+ * @param items - 不会被修改的输入数组。
48
+ * @param predicate - 接收项目与索引的判断函数。
49
+ * @returns 二元组:第一项匹配谓词,第二项不匹配;两组都保持原顺序并忽略稀疏空位。
50
+ */
51
+ declare function partition<Item>(items: readonly Item[], predicate: (item: Item, index: number) => boolean): [matched: Item[], unmatched: Item[]];
52
+ /**
53
+ * 返回只出现在左侧数组中的不同值。
54
+ *
55
+ * @param left - 主输入数组。
56
+ * @param right - 需要排除的值。
57
+ * @returns 保留左侧首次出现顺序的去重结果;两侧稀疏空位都被忽略。
58
+ */
59
+ declare function difference<Item>(left: readonly Item[], right: readonly Item[]): Item[];
60
+ /**
61
+ * 返回两个数组共有的不同值。
62
+ *
63
+ * @param left - 决定结果顺序的数组。
64
+ * @param right - 用于成员判断的数组。
65
+ * @returns 保留左侧首次出现顺序的去重结果;两侧稀疏空位都被忽略。
66
+ */
67
+ declare function intersection<Item>(left: readonly Item[], right: readonly Item[]): Item[];
68
+ /**
69
+ * 判断选择器产生的键是否重复。
70
+ *
71
+ * @param items - 不会被修改的输入数组。
72
+ * @param selectKey - 返回比较键的函数;键使用 SameValueZero 语义比较。
73
+ * @returns 存在至少一个重复键时返回 `true`。
74
+ */
75
+ declare function hasDuplicatesBy<Item, Key>(items: readonly Item[], selectKey: KeySelector<Item, Key>): boolean;
76
+ /**
77
+ * 判断所有项目是否具有相同的选择器结果。
78
+ *
79
+ * @remarks 空数组、只有稀疏空位的数组和单项数组按数学惯例返回 `true`;空位不会调用选择器。
80
+ * @param items - 不会被修改的输入数组。
81
+ * @param selectKey - 返回比较键的函数。
82
+ * @returns 所有键都满足 SameValueZero 相等时返回 `true`。
83
+ */
84
+ declare function allEqualBy<Item, Key>(items: readonly Item[], selectKey: KeySelector<Item, Key>): boolean;
85
+ //#endregion
86
+ export { KeySelector, allEqualBy, chunk, difference, groupBy, hasDuplicatesBy, intersection, partition, removeNullishValues, unique, uniqueBy };
87
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/array/index.ts"],"mappings":";;KACY,YAAY,MAAM,QAAQ,MAAM,MAAM,kBAAkB;;;;;;;;;;iBAWpD,MAAM,MAAM,gBAAgB,QAAQ,eAAe;;;;;;;iBAkBnD,oBAAoB,MAAM,iBAAiB,6BAA6B;;;;;;;iBAUxE,OAAO,MAAM,gBAAgB,SAAS;;;;;;;;iBAoBtC,SAAS,MAAM,KAAK,gBAAgB,QAAQ,WAAW,YAAY,MAAM,OAAO;;;;;;;;iBAqBhF,QAAQ,MAAM,KAAK,gBAAgB,QAAQ,WAAW,YAAY,MAAM,OAAO,IAAI,KAAK;;;;;;;;iBAkBxF,UAAU,MAAM,gBAAgB,QAAQ,YAAY,MAAM,MAAM,6BAA6B,SAAS,QAAQ,WAAW;;;;;;;;iBAczH,WAAW,MAAM,eAAe,QAAQ,gBAAgB,SAAS;;;;;;;;iBAYjE,aAAa,MAAM,eAAe,QAAQ,gBAAgB,SAAS;;;;;;;;iBAYnE,gBAAgB,MAAM,KAAK,gBAAgB,QAAQ,WAAW,YAAY,MAAM;;;;;;;;;iBAoBhF,WAAW,MAAM,KAAK,gBAAgB,QAAQ,WAAW,YAAY,MAAM"}