@moxon/api 6.0.0-pre

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 (246) hide show
  1. package/.prettierignore +5 -0
  2. package/LICENSE +28 -0
  3. package/README.md +277 -0
  4. package/dist/app.d.ts +2 -0
  5. package/dist/app.js +55 -0
  6. package/dist/app.js.map +1 -0
  7. package/dist/config/env.d.ts +22 -0
  8. package/dist/config/env.js +36 -0
  9. package/dist/config/env.js.map +1 -0
  10. package/dist/config/plans.d.ts +26 -0
  11. package/dist/config/plans.js +44 -0
  12. package/dist/config/plans.js.map +1 -0
  13. package/dist/config/versions.d.ts +18 -0
  14. package/dist/config/versions.js +248 -0
  15. package/dist/config/versions.js.map +1 -0
  16. package/dist/constants.d.ts +48 -0
  17. package/dist/constants.js +75 -0
  18. package/dist/constants.js.map +1 -0
  19. package/dist/middleware/cors.d.ts +2 -0
  20. package/dist/middleware/cors.js +31 -0
  21. package/dist/middleware/cors.js.map +1 -0
  22. package/dist/middleware/error.d.ts +4 -0
  23. package/dist/middleware/error.js +8 -0
  24. package/dist/middleware/error.js.map +1 -0
  25. package/dist/middleware/json.d.ts +2 -0
  26. package/dist/middleware/json.js +8 -0
  27. package/dist/middleware/json.js.map +1 -0
  28. package/dist/middleware/logger.d.ts +26 -0
  29. package/dist/middleware/logger.js +65 -0
  30. package/dist/middleware/logger.js.map +1 -0
  31. package/dist/middleware/ratelimit.d.ts +2 -0
  32. package/dist/middleware/ratelimit.js +83 -0
  33. package/dist/middleware/ratelimit.js.map +1 -0
  34. package/dist/middleware/version.d.ts +3 -0
  35. package/dist/middleware/version.js +30 -0
  36. package/dist/middleware/version.js.map +1 -0
  37. package/dist/modules/v4/address.d.ts +20 -0
  38. package/dist/modules/v4/address.js +381 -0
  39. package/dist/modules/v4/address.js.map +1 -0
  40. package/dist/modules/v4/agent.d.ts +30 -0
  41. package/dist/modules/v4/agent.js +92 -0
  42. package/dist/modules/v4/agent.js.map +1 -0
  43. package/dist/modules/v4/algorithms.d.ts +90 -0
  44. package/dist/modules/v4/algorithms.js +279 -0
  45. package/dist/modules/v4/algorithms.js.map +1 -0
  46. package/dist/modules/v4/avatar.d.ts +23 -0
  47. package/dist/modules/v4/avatar.js +136 -0
  48. package/dist/modules/v4/avatar.js.map +1 -0
  49. package/dist/modules/v4/barcode.d.ts +27 -0
  50. package/dist/modules/v4/barcode.js +440 -0
  51. package/dist/modules/v4/barcode.js.map +1 -0
  52. package/dist/modules/v4/captcha.d.ts +22 -0
  53. package/dist/modules/v4/captcha.js +79 -0
  54. package/dist/modules/v4/captcha.js.map +1 -0
  55. package/dist/modules/v4/chat.d.ts +21 -0
  56. package/dist/modules/v4/chat.js +100 -0
  57. package/dist/modules/v4/chat.js.map +1 -0
  58. package/dist/modules/v4/color.d.ts +16 -0
  59. package/dist/modules/v4/color.js +59 -0
  60. package/dist/modules/v4/color.js.map +1 -0
  61. package/dist/modules/v4/convert.d.ts +15 -0
  62. package/dist/modules/v4/convert.js +116 -0
  63. package/dist/modules/v4/convert.js.map +1 -0
  64. package/dist/modules/v4/credit.d.ts +22 -0
  65. package/dist/modules/v4/credit.js +104 -0
  66. package/dist/modules/v4/credit.js.map +1 -0
  67. package/dist/modules/v4/cron.d.ts +17 -0
  68. package/dist/modules/v4/cron.js +202 -0
  69. package/dist/modules/v4/cron.js.map +1 -0
  70. package/dist/modules/v4/dice.d.ts +16 -0
  71. package/dist/modules/v4/dice.js +37 -0
  72. package/dist/modules/v4/dice.js.map +1 -0
  73. package/dist/modules/v4/domain.d.ts +6 -0
  74. package/dist/modules/v4/domain.js +83 -0
  75. package/dist/modules/v4/domain.js.map +1 -0
  76. package/dist/modules/v4/encode.d.ts +81 -0
  77. package/dist/modules/v4/encode.js +236 -0
  78. package/dist/modules/v4/encode.js.map +1 -0
  79. package/dist/modules/v4/geo.d.ts +30 -0
  80. package/dist/modules/v4/geo.js +51 -0
  81. package/dist/modules/v4/geo.js.map +1 -0
  82. package/dist/modules/v4/hash.d.ts +15 -0
  83. package/dist/modules/v4/hash.js +25 -0
  84. package/dist/modules/v4/hash.js.map +1 -0
  85. package/dist/modules/v4/hyperplanning.d.ts +19 -0
  86. package/dist/modules/v4/hyperplanning.js +80 -0
  87. package/dist/modules/v4/hyperplanning.js.map +1 -0
  88. package/dist/modules/v4/ip.d.ts +19 -0
  89. package/dist/modules/v4/ip.js +132 -0
  90. package/dist/modules/v4/ip.js.map +1 -0
  91. package/dist/modules/v4/levenshtein.d.ts +13 -0
  92. package/dist/modules/v4/levenshtein.js +37 -0
  93. package/dist/modules/v4/levenshtein.js.map +1 -0
  94. package/dist/modules/v4/palette.d.ts +19 -0
  95. package/dist/modules/v4/palette.js +56 -0
  96. package/dist/modules/v4/palette.js.map +1 -0
  97. package/dist/modules/v4/password.d.ts +25 -0
  98. package/dist/modules/v4/password.js +343 -0
  99. package/dist/modules/v4/password.js.map +1 -0
  100. package/dist/modules/v4/personal.d.ts +6 -0
  101. package/dist/modules/v4/personal.js +121 -0
  102. package/dist/modules/v4/personal.js.map +1 -0
  103. package/dist/modules/v4/placeholder.d.ts +30 -0
  104. package/dist/modules/v4/placeholder.js +160 -0
  105. package/dist/modules/v4/placeholder.js.map +1 -0
  106. package/dist/modules/v4/qrcode.d.ts +25 -0
  107. package/dist/modules/v4/qrcode.js +92 -0
  108. package/dist/modules/v4/qrcode.js.map +1 -0
  109. package/dist/modules/v4/regex.d.ts +23 -0
  110. package/dist/modules/v4/regex.js +48 -0
  111. package/dist/modules/v4/regex.js.map +1 -0
  112. package/dist/modules/v4/statistics.d.ts +20 -0
  113. package/dist/modules/v4/statistics.js +48 -0
  114. package/dist/modules/v4/statistics.js.map +1 -0
  115. package/dist/modules/v4/text.d.ts +43 -0
  116. package/dist/modules/v4/text.js +323 -0
  117. package/dist/modules/v4/text.js.map +1 -0
  118. package/dist/modules/v4/tic_tac_toe.d.ts +19 -0
  119. package/dist/modules/v4/tic_tac_toe.js +214 -0
  120. package/dist/modules/v4/tic_tac_toe.js.map +1 -0
  121. package/dist/modules/v4/time.d.ts +15 -0
  122. package/dist/modules/v4/time.js +124 -0
  123. package/dist/modules/v4/time.js.map +1 -0
  124. package/dist/modules/v4/token.d.ts +9 -0
  125. package/dist/modules/v4/token.js +45 -0
  126. package/dist/modules/v4/token.js.map +1 -0
  127. package/dist/modules/v4/username.d.ts +6 -0
  128. package/dist/modules/v4/username.js +92 -0
  129. package/dist/modules/v4/username.js.map +1 -0
  130. package/dist/modules/v4/validate.d.ts +34 -0
  131. package/dist/modules/v4/validate.js +75 -0
  132. package/dist/modules/v4/validate.js.map +1 -0
  133. package/dist/modules/v4.d.ts +32 -0
  134. package/dist/modules/v4.js +33 -0
  135. package/dist/modules/v4.js.map +1 -0
  136. package/dist/modules/v5/address.d.ts +5 -0
  137. package/dist/modules/v5/address.js +20 -0
  138. package/dist/modules/v5/address.js.map +1 -0
  139. package/dist/modules/v5/algorithms.d.ts +9 -0
  140. package/dist/modules/v5/algorithms.js +39 -0
  141. package/dist/modules/v5/algorithms.js.map +1 -0
  142. package/dist/modules/v5/asymmetric.d.ts +26 -0
  143. package/dist/modules/v5/asymmetric.js +74 -0
  144. package/dist/modules/v5/asymmetric.js.map +1 -0
  145. package/dist/modules/v5/barcode.d.ts +27 -0
  146. package/dist/modules/v5/barcode.js +424 -0
  147. package/dist/modules/v5/barcode.js.map +1 -0
  148. package/dist/modules/v5/base.d.ts +16 -0
  149. package/dist/modules/v5/base.js +41 -0
  150. package/dist/modules/v5/base.js.map +1 -0
  151. package/dist/modules/v5/captcha.d.ts +27 -0
  152. package/dist/modules/v5/captcha.js +136 -0
  153. package/dist/modules/v5/captcha.js.map +1 -0
  154. package/dist/modules/v5/case.d.ts +10 -0
  155. package/dist/modules/v5/case.js +57 -0
  156. package/dist/modules/v5/case.js.map +1 -0
  157. package/dist/modules/v5/chart.d.ts +53 -0
  158. package/dist/modules/v5/chart.js +385 -0
  159. package/dist/modules/v5/chart.js.map +1 -0
  160. package/dist/modules/v5/chat.d.ts +21 -0
  161. package/dist/modules/v5/chat.js +107 -0
  162. package/dist/modules/v5/chat.js.map +1 -0
  163. package/dist/modules/v5/csv.d.ts +29 -0
  164. package/dist/modules/v5/csv.js +143 -0
  165. package/dist/modules/v5/csv.js.map +1 -0
  166. package/dist/modules/v5/diff.d.ts +20 -0
  167. package/dist/modules/v5/diff.js +81 -0
  168. package/dist/modules/v5/diff.js.map +1 -0
  169. package/dist/modules/v5/evaluate.d.ts +14 -0
  170. package/dist/modules/v5/evaluate.js +284 -0
  171. package/dist/modules/v5/evaluate.js.map +1 -0
  172. package/dist/modules/v5/jwt.d.ts +11 -0
  173. package/dist/modules/v5/jwt.js +42 -0
  174. package/dist/modules/v5/jwt.js.map +1 -0
  175. package/dist/modules/v5/matrix.d.ts +77 -0
  176. package/dist/modules/v5/matrix.js +239 -0
  177. package/dist/modules/v5/matrix.js.map +1 -0
  178. package/dist/modules/v5/otp.d.ts +30 -0
  179. package/dist/modules/v5/otp.js +117 -0
  180. package/dist/modules/v5/otp.js.map +1 -0
  181. package/dist/modules/v5/pow.d.ts +29 -0
  182. package/dist/modules/v5/pow.js +49 -0
  183. package/dist/modules/v5/pow.js.map +1 -0
  184. package/dist/modules/v5/read.d.ts +20 -0
  185. package/dist/modules/v5/read.js +59 -0
  186. package/dist/modules/v5/read.js.map +1 -0
  187. package/dist/modules/v5/semver.d.ts +33 -0
  188. package/dist/modules/v5/semver.js +99 -0
  189. package/dist/modules/v5/semver.js.map +1 -0
  190. package/dist/modules/v5/symmetric.d.ts +15 -0
  191. package/dist/modules/v5/symmetric.js +88 -0
  192. package/dist/modules/v5/symmetric.js.map +1 -0
  193. package/dist/modules/v5/text.d.ts +5 -0
  194. package/dist/modules/v5/text.js +12 -0
  195. package/dist/modules/v5/text.js.map +1 -0
  196. package/dist/modules/v5/tic_tac_toe.d.ts +19 -0
  197. package/dist/modules/v5/tic_tac_toe.js +226 -0
  198. package/dist/modules/v5/tic_tac_toe.js.map +1 -0
  199. package/dist/modules/v5/url.d.ts +18 -0
  200. package/dist/modules/v5/url.js +51 -0
  201. package/dist/modules/v5/url.js.map +1 -0
  202. package/dist/modules/v5/uuid.d.ts +25 -0
  203. package/dist/modules/v5/uuid.js +40 -0
  204. package/dist/modules/v5/uuid.js.map +1 -0
  205. package/dist/modules/v5.d.ts +24 -0
  206. package/dist/modules/v5.js +25 -0
  207. package/dist/modules/v5.js.map +1 -0
  208. package/dist/modules/v6.d.ts +1 -0
  209. package/dist/modules/v6.js +2 -0
  210. package/dist/modules/v6.js.map +1 -0
  211. package/dist/routes/delete.d.ts +2 -0
  212. package/dist/routes/delete.js +73 -0
  213. package/dist/routes/delete.js.map +1 -0
  214. package/dist/routes/get.d.ts +2 -0
  215. package/dist/routes/get.js +857 -0
  216. package/dist/routes/get.js.map +1 -0
  217. package/dist/routes/index.d.ts +2 -0
  218. package/dist/routes/index.js +95 -0
  219. package/dist/routes/index.js.map +1 -0
  220. package/dist/routes/patch.d.ts +2 -0
  221. package/dist/routes/patch.js +45 -0
  222. package/dist/routes/patch.js.map +1 -0
  223. package/dist/routes/post.d.ts +2 -0
  224. package/dist/routes/post.js +604 -0
  225. package/dist/routes/post.js.map +1 -0
  226. package/dist/storage/index.d.ts +5 -0
  227. package/dist/storage/index.js +14 -0
  228. package/dist/storage/index.js.map +1 -0
  229. package/dist/types/storage.d.ts +52 -0
  230. package/dist/types/storage.js +2 -0
  231. package/dist/types/storage.js.map +1 -0
  232. package/dist/utils/challenge.d.ts +40 -0
  233. package/dist/utils/challenge.js +75 -0
  234. package/dist/utils/challenge.js.map +1 -0
  235. package/dist/utils/colors.d.ts +44 -0
  236. package/dist/utils/colors.js +93 -0
  237. package/dist/utils/colors.js.map +1 -0
  238. package/dist/utils/helpers.d.ts +55 -0
  239. package/dist/utils/helpers.js +82 -0
  240. package/dist/utils/helpers.js.map +1 -0
  241. package/dist/utils/response.d.ts +9 -0
  242. package/dist/utils/response.js +24 -0
  243. package/dist/utils/response.js.map +1 -0
  244. package/package.json +90 -0
  245. package/robots.txt +74 -0
  246. package/src/favicon.ico +0 -0
@@ -0,0 +1,77 @@
1
+ export type Matrix = number[][];
2
+ export interface MatrixResult {
3
+ operation: string;
4
+ result: Matrix | number;
5
+ dimensions: {
6
+ rows: number;
7
+ cols: number;
8
+ };
9
+ }
10
+ /**
11
+ * Adds two matrices element-wise.
12
+ *
13
+ * @param matrix - First matrix (2D array of finite numbers)
14
+ * @param matrix2 - Second matrix (must have the same dimensions as matrix)
15
+ * @returns MatrixResult with the resulting matrix and its dimensions
16
+ * @throws Error if either argument is not a valid matrix or dimensions do not match
17
+ */
18
+ export declare function add(matrix: unknown, matrix2: unknown): MatrixResult;
19
+ /**
20
+ * Subtracts the second matrix from the first element-wise.
21
+ *
22
+ * @param matrix - Matrix to subtract from (2D array of finite numbers)
23
+ * @param matrix2 - Matrix to subtract (must have the same dimensions as matrix)
24
+ * @returns MatrixResult with the resulting matrix and its dimensions
25
+ * @throws Error if either argument is not a valid matrix or dimensions do not match
26
+ */
27
+ export declare function subtract(matrix: unknown, matrix2: unknown): MatrixResult;
28
+ /**
29
+ * Multiplies two matrices using standard matrix multiplication.
30
+ *
31
+ * @param matrix - Left-hand matrix (2D array of finite numbers)
32
+ * @param matrix2 - Right-hand matrix; its row count must equal matrix's column count
33
+ * @returns MatrixResult with the resulting matrix and its dimensions
34
+ * @throws Error if either argument is not a valid matrix or inner dimensions are incompatible
35
+ */
36
+ export declare function multiply(matrix: unknown, matrix2: unknown): MatrixResult;
37
+ /**
38
+ * Multiplies every element of a matrix by a scalar value.
39
+ *
40
+ * @param matrix - Matrix to scale (2D array of finite numbers)
41
+ * @param scalarVal - Finite number to multiply each element by
42
+ * @returns MatrixResult with the scaled matrix and its dimensions
43
+ * @throws Error if matrix is invalid or scalarVal is not a finite number
44
+ */
45
+ export declare function scalar(matrix: unknown, scalarVal: unknown): MatrixResult;
46
+ /**
47
+ * Transposes a matrix, swapping its rows and columns.
48
+ *
49
+ * @param matrix - Matrix to transpose (2D array of finite numbers)
50
+ * @returns MatrixResult with the transposed matrix and its dimensions
51
+ * @throws Error if matrix is not a valid 2D array of finite numbers
52
+ */
53
+ export declare function transpose(matrix: unknown): MatrixResult;
54
+ /**
55
+ * Computes the determinant of a square matrix using Gaussian elimination with partial pivoting.
56
+ *
57
+ * @param matrix - Square matrix (2D array of finite numbers)
58
+ * @returns MatrixResult with the determinant as a scalar result and the input dimensions
59
+ * @throws Error if matrix is not a valid square matrix
60
+ */
61
+ export declare function determinant(matrix: unknown): MatrixResult;
62
+ /**
63
+ * Computes the inverse of a square matrix using Gauss-Jordan elimination.
64
+ *
65
+ * @param matrix - Square matrix (2D array of finite numbers)
66
+ * @returns MatrixResult with the inverted matrix and its dimensions
67
+ * @throws Error if matrix is not a valid square matrix or is singular (determinant is 0)
68
+ */
69
+ export declare function inverse(matrix: unknown): MatrixResult;
70
+ /**
71
+ * Generates an n×n identity matrix.
72
+ *
73
+ * @param n - Size of the identity matrix (positive integer, max MAX_MATRIX_SIZE)
74
+ * @returns MatrixResult with the identity matrix and its dimensions
75
+ * @throws Error if n is not a positive integer or exceeds the maximum allowed size
76
+ */
77
+ export declare function identity(n: unknown): MatrixResult;
@@ -0,0 +1,239 @@
1
+ import { MAX_MATRIX_SIZE } from '../../constants.js';
2
+ function validateMatrix(m, name = 'matrix') {
3
+ if (!Array.isArray(m) || m.length === 0) {
4
+ throw new Error(`Field '${name}' must be a non-empty 2D array`);
5
+ }
6
+ const cols = m[0].length;
7
+ if (cols === 0)
8
+ throw new Error(`Field '${name}' rows must be non-empty`);
9
+ for (const row of m) {
10
+ if (!Array.isArray(row) || row.length !== cols) {
11
+ throw new Error(`All rows in '${name}' must have the same length`);
12
+ }
13
+ for (const cell of row) {
14
+ if (typeof cell !== 'number' || !isFinite(cell)) {
15
+ throw new Error(`Field '${name}' must contain finite numbers only`);
16
+ }
17
+ }
18
+ }
19
+ if (m.length > MAX_MATRIX_SIZE || cols > MAX_MATRIX_SIZE) {
20
+ throw new Error(`Matrix dimensions cannot exceed ${MAX_MATRIX_SIZE}×${MAX_MATRIX_SIZE}`);
21
+ }
22
+ return m;
23
+ }
24
+ function dims(m) {
25
+ return { rows: m.length, cols: m[0].length };
26
+ }
27
+ function assertSquare(m, op) {
28
+ const { rows, cols } = dims(m);
29
+ if (rows !== cols)
30
+ throw new Error(`Operation '${op}' requires a square matrix`);
31
+ }
32
+ function assertSameDimensions(a, b) {
33
+ if (a.length !== b.length || a[0].length !== b[0].length) {
34
+ throw new Error('Both matrices must have the same dimensions');
35
+ }
36
+ }
37
+ function copy(m) {
38
+ return m.map((row) => [...row]);
39
+ }
40
+ function clean(x) {
41
+ return x === 0 ? 0 : Number(x.toPrecision(12));
42
+ }
43
+ /**
44
+ * Adds two matrices element-wise.
45
+ *
46
+ * @param matrix - First matrix (2D array of finite numbers)
47
+ * @param matrix2 - Second matrix (must have the same dimensions as matrix)
48
+ * @returns MatrixResult with the resulting matrix and its dimensions
49
+ * @throws Error if either argument is not a valid matrix or dimensions do not match
50
+ */
51
+ export function add(matrix, matrix2) {
52
+ const a = validateMatrix(matrix);
53
+ const b = validateMatrix(matrix2, 'matrix2');
54
+ assertSameDimensions(a, b);
55
+ const result = a.map((row, i) => row.map((v, j) => v + b[i][j]));
56
+ return { operation: 'add', result, dimensions: dims(result) };
57
+ }
58
+ /**
59
+ * Subtracts the second matrix from the first element-wise.
60
+ *
61
+ * @param matrix - Matrix to subtract from (2D array of finite numbers)
62
+ * @param matrix2 - Matrix to subtract (must have the same dimensions as matrix)
63
+ * @returns MatrixResult with the resulting matrix and its dimensions
64
+ * @throws Error if either argument is not a valid matrix or dimensions do not match
65
+ */
66
+ export function subtract(matrix, matrix2) {
67
+ const a = validateMatrix(matrix);
68
+ const b = validateMatrix(matrix2, 'matrix2');
69
+ assertSameDimensions(a, b);
70
+ const result = a.map((row, i) => row.map((v, j) => v - b[i][j]));
71
+ return { operation: 'subtract', result, dimensions: dims(result) };
72
+ }
73
+ /**
74
+ * Multiplies two matrices using standard matrix multiplication.
75
+ *
76
+ * @param matrix - Left-hand matrix (2D array of finite numbers)
77
+ * @param matrix2 - Right-hand matrix; its row count must equal matrix's column count
78
+ * @returns MatrixResult with the resulting matrix and its dimensions
79
+ * @throws Error if either argument is not a valid matrix or inner dimensions are incompatible
80
+ */
81
+ export function multiply(matrix, matrix2) {
82
+ const a = validateMatrix(matrix);
83
+ const b = validateMatrix(matrix2, 'matrix2');
84
+ const { rows: ar, cols: ac } = dims(a);
85
+ const { rows: br, cols: bc } = dims(b);
86
+ if (ac !== br) {
87
+ throw new Error(`Cannot multiply: columns of first matrix (${ac}) must equal rows of second (${br})`);
88
+ }
89
+ const result = Array.from({ length: ar }, () => new Array(bc).fill(0));
90
+ for (let i = 0; i < ar; i++) {
91
+ for (let j = 0; j < bc; j++) {
92
+ let sum = 0;
93
+ for (let k = 0; k < ac; k++) {
94
+ sum += a[i][k] * b[k][j];
95
+ }
96
+ result[i][j] = sum;
97
+ }
98
+ }
99
+ return { operation: 'multiply', result, dimensions: dims(result) };
100
+ }
101
+ /**
102
+ * Multiplies every element of a matrix by a scalar value.
103
+ *
104
+ * @param matrix - Matrix to scale (2D array of finite numbers)
105
+ * @param scalarVal - Finite number to multiply each element by
106
+ * @returns MatrixResult with the scaled matrix and its dimensions
107
+ * @throws Error if matrix is invalid or scalarVal is not a finite number
108
+ */
109
+ export function scalar(matrix, scalarVal) {
110
+ const a = validateMatrix(matrix);
111
+ if (typeof scalarVal !== 'number' || !isFinite(scalarVal)) {
112
+ throw new Error("Field 'scalar' must be a finite number");
113
+ }
114
+ const result = a.map((row) => row.map((v) => v * scalarVal));
115
+ return { operation: 'scalar', result, dimensions: dims(result) };
116
+ }
117
+ /**
118
+ * Transposes a matrix, swapping its rows and columns.
119
+ *
120
+ * @param matrix - Matrix to transpose (2D array of finite numbers)
121
+ * @returns MatrixResult with the transposed matrix and its dimensions
122
+ * @throws Error if matrix is not a valid 2D array of finite numbers
123
+ */
124
+ export function transpose(matrix) {
125
+ const a = validateMatrix(matrix);
126
+ const { rows, cols } = dims(a);
127
+ const result = Array.from({ length: cols }, (_, j) => Array.from({ length: rows }, (__, i) => a[i][j]));
128
+ return { operation: 'transpose', result, dimensions: dims(result) };
129
+ }
130
+ function gaussElim(m) {
131
+ const n = m.length;
132
+ const lu = copy(m);
133
+ let sign = 1;
134
+ for (let col = 0; col < n; col++) {
135
+ // Partial pivoting
136
+ let maxRow = col;
137
+ for (let row = col + 1; row < n; row++) {
138
+ if (Math.abs(lu[row][col]) > Math.abs(lu[maxRow][col]))
139
+ maxRow = row;
140
+ }
141
+ if (maxRow !== col) {
142
+ [lu[col], lu[maxRow]] = [lu[maxRow], lu[col]];
143
+ sign *= -1;
144
+ }
145
+ const pivot = lu[col][col];
146
+ if (pivot === 0)
147
+ continue;
148
+ for (let row = col + 1; row < n; row++) {
149
+ const factor = lu[row][col] / pivot;
150
+ for (let k = col; k < n; k++) {
151
+ lu[row][k] -= factor * lu[col][k];
152
+ }
153
+ }
154
+ }
155
+ return { lu, sign };
156
+ }
157
+ /**
158
+ * Computes the determinant of a square matrix using Gaussian elimination with partial pivoting.
159
+ *
160
+ * @param matrix - Square matrix (2D array of finite numbers)
161
+ * @returns MatrixResult with the determinant as a scalar result and the input dimensions
162
+ * @throws Error if matrix is not a valid square matrix
163
+ */
164
+ export function determinant(matrix) {
165
+ const a = validateMatrix(matrix);
166
+ assertSquare(a, 'determinant');
167
+ const n = a.length;
168
+ if (n === 1)
169
+ return { operation: 'determinant', result: a[0][0], dimensions: dims(a) };
170
+ if (n === 2) {
171
+ const det = a[0][0] * a[1][1] - a[0][1] * a[1][0];
172
+ return { operation: 'determinant', result: det, dimensions: dims(a) };
173
+ }
174
+ const { lu, sign } = gaussElim(a);
175
+ let det = sign;
176
+ for (let i = 0; i < n; i++)
177
+ det *= lu[i][i];
178
+ const result = clean(det);
179
+ return { operation: 'determinant', result, dimensions: dims(a) };
180
+ }
181
+ /**
182
+ * Computes the inverse of a square matrix using Gauss-Jordan elimination.
183
+ *
184
+ * @param matrix - Square matrix (2D array of finite numbers)
185
+ * @returns MatrixResult with the inverted matrix and its dimensions
186
+ * @throws Error if matrix is not a valid square matrix or is singular (determinant is 0)
187
+ */
188
+ export function inverse(matrix) {
189
+ const a = validateMatrix(matrix);
190
+ assertSquare(a, 'inverse');
191
+ const n = a.length;
192
+ // Build augmented matrix [A | I]
193
+ const aug = a.map((row, i) => [...row, ...Array.from({ length: n }, (_, j) => (i === j ? 1 : 0))]);
194
+ // Gauss-Jordan elimination
195
+ for (let col = 0; col < n; col++) {
196
+ // Partial pivoting
197
+ let maxRow = col;
198
+ for (let row = col + 1; row < n; row++) {
199
+ if (Math.abs(aug[row][col]) > Math.abs(aug[maxRow][col]))
200
+ maxRow = row;
201
+ }
202
+ if (maxRow !== col)
203
+ [aug[col], aug[maxRow]] = [aug[maxRow], aug[col]];
204
+ const pivot = aug[col][col];
205
+ if (Math.abs(pivot) < 1e-12)
206
+ throw new Error('Matrix is singular (determinant is 0)');
207
+ for (let k = 0; k < 2 * n; k++)
208
+ aug[col][k] /= pivot;
209
+ for (let row = 0; row < n; row++) {
210
+ if (row === col)
211
+ continue;
212
+ const factor = aug[row][col];
213
+ for (let k = 0; k < 2 * n; k++) {
214
+ aug[row][k] -= factor * aug[col][k];
215
+ }
216
+ }
217
+ }
218
+ // Extract right half
219
+ const result = aug.map((row) => row.slice(n).map((v) => clean(v)));
220
+ return { operation: 'inverse', result, dimensions: dims(result) };
221
+ }
222
+ /**
223
+ * Generates an n×n identity matrix.
224
+ *
225
+ * @param n - Size of the identity matrix (positive integer, max MAX_MATRIX_SIZE)
226
+ * @returns MatrixResult with the identity matrix and its dimensions
227
+ * @throws Error if n is not a positive integer or exceeds the maximum allowed size
228
+ */
229
+ export function identity(n) {
230
+ if (typeof n !== 'number' || !Number.isInteger(n) || n <= 0) {
231
+ throw new Error("Field 'scalar' must be a positive integer for the identity operation");
232
+ }
233
+ if (n > MAX_MATRIX_SIZE) {
234
+ throw new Error(`Identity size cannot exceed ${MAX_MATRIX_SIZE}`);
235
+ }
236
+ const result = Array.from({ length: n }, (_, i) => Array.from({ length: n }, (__, j) => (i === j ? 1 : 0)));
237
+ return { operation: 'identity', result, dimensions: { rows: n, cols: n } };
238
+ }
239
+ //# sourceMappingURL=matrix.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matrix.js","sourceRoot":"","sources":["../../../src/modules/v5/matrix.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ export interface OtpSecretResult {
2
+ secret: string;
3
+ uri: string;
4
+ }
5
+ export interface OtpGenerateResult {
6
+ code: string;
7
+ remaining: number;
8
+ period: number;
9
+ }
10
+ export interface OtpVerifyResult {
11
+ valid: boolean;
12
+ drift: number;
13
+ }
14
+ /**
15
+ * Generates or verifies TOTP/HOTP codes (RFC 4226 / RFC 6238).
16
+ *
17
+ * @param action - "secret", "generate", or "verify"
18
+ * @param options - Configuration options
19
+ * @returns Result depending on action
20
+ */
21
+ export default function otp(action: string, options?: {
22
+ secret?: string;
23
+ code?: string;
24
+ algorithm?: string;
25
+ digits?: number;
26
+ period?: number;
27
+ counter?: number;
28
+ label?: string;
29
+ issuer?: string;
30
+ }): OtpSecretResult | OtpGenerateResult | OtpVerifyResult;
@@ -0,0 +1,117 @@
1
+ import { createHmac, randomBytes, timingSafeEqual } from 'crypto';
2
+ const BASE32_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';
3
+ function encodeBase32(buffer) {
4
+ let bits = 0;
5
+ let value = 0;
6
+ let result = '';
7
+ for (const byte of buffer) {
8
+ value = (value << 8) | byte;
9
+ bits += 8;
10
+ while (bits >= 5) {
11
+ bits -= 5;
12
+ result += BASE32_CHARS[(value >>> bits) & 0x1f];
13
+ }
14
+ }
15
+ if (bits > 0) {
16
+ result += BASE32_CHARS[(value << (5 - bits)) & 0x1f];
17
+ }
18
+ return result;
19
+ }
20
+ function decodeBase32(encoded) {
21
+ const cleaned = encoded.replace(/=+$/, '').toUpperCase();
22
+ let bits = 0;
23
+ let value = 0;
24
+ const bytes = [];
25
+ for (const char of cleaned) {
26
+ const idx = BASE32_CHARS.indexOf(char);
27
+ if (idx === -1)
28
+ throw new Error('Invalid base32 character');
29
+ value = (value << 5) | idx;
30
+ bits += 5;
31
+ if (bits >= 8) {
32
+ bits -= 8;
33
+ bytes.push((value >>> bits) & 0xff);
34
+ }
35
+ }
36
+ return Buffer.from(bytes);
37
+ }
38
+ function generateHotp(secret, counter, algorithm, digits) {
39
+ const counterBuf = Buffer.alloc(8);
40
+ counterBuf.writeBigUInt64BE(counter);
41
+ const hmac = createHmac(algorithm, secret).update(counterBuf).digest();
42
+ const offset = hmac[hmac.length - 1] & 0x0f;
43
+ const binary = ((hmac[offset] & 0x7f) << 24) |
44
+ ((hmac[offset + 1] & 0xff) << 16) |
45
+ ((hmac[offset + 2] & 0xff) << 8) |
46
+ (hmac[offset + 3] & 0xff);
47
+ const otp = binary % 10 ** digits;
48
+ return otp.toString().padStart(digits, '0');
49
+ }
50
+ function codesEqual(a, b) {
51
+ const ab = Buffer.from(a);
52
+ const bb = Buffer.from(b);
53
+ if (ab.length !== bb.length)
54
+ return false;
55
+ return timingSafeEqual(ab, bb);
56
+ }
57
+ const VALID_ALGORITHMS = new Set(['sha1', 'sha256', 'sha512']);
58
+ const VALID_DIGITS = new Set([6, 8]);
59
+ const VALID_PERIODS = new Set([15, 30, 60]);
60
+ /**
61
+ * Generates or verifies TOTP/HOTP codes (RFC 4226 / RFC 6238).
62
+ *
63
+ * @param action - "secret", "generate", or "verify"
64
+ * @param options - Configuration options
65
+ * @returns Result depending on action
66
+ */
67
+ export default function otp(action, options = {}) {
68
+ if (!action || !['secret', 'generate', 'verify'].includes(action))
69
+ throw new Error('Action must be "secret", "generate", or "verify"');
70
+ const algorithm = options.algorithm ?? 'sha1';
71
+ const digits = options.digits ?? 6;
72
+ const period = options.period ?? 30;
73
+ if (!VALID_ALGORITHMS.has(algorithm))
74
+ throw new Error(`Algorithm must be one of: ${[...VALID_ALGORITHMS].join(', ')}`);
75
+ if (!VALID_DIGITS.has(digits))
76
+ throw new Error('Digits must be 6 or 8');
77
+ if (!VALID_PERIODS.has(period))
78
+ throw new Error('Period must be 15, 30, or 60');
79
+ if (action === 'secret') {
80
+ const label = options.label ?? 'user';
81
+ const issuer = options.issuer ?? 'API';
82
+ const secretBuf = randomBytes(20);
83
+ const secret = encodeBase32(secretBuf);
84
+ const uri = `otpauth://totp/${encodeURIComponent(issuer)}:${encodeURIComponent(label)}?secret=${secret}&issuer=${encodeURIComponent(issuer)}&algorithm=${algorithm.toUpperCase()}&digits=${digits}&period=${period}`;
85
+ return { secret, uri };
86
+ }
87
+ if (!options.secret)
88
+ throw new Error('Secret is required for generate/verify');
89
+ if (options.counter !== undefined && (!Number.isInteger(options.counter) || options.counter < 0))
90
+ throw new Error('Counter must be a non-negative integer');
91
+ const secretBuf = decodeBase32(options.secret);
92
+ if (action === 'generate') {
93
+ const counter = options.counter !== undefined ? BigInt(options.counter) : BigInt(Math.floor(Date.now() / 1000 / period));
94
+ const code = generateHotp(secretBuf, counter, algorithm, digits);
95
+ const remaining = options.counter !== undefined ? period : period - (Math.floor(Date.now() / 1000) % period);
96
+ return { code, remaining, period };
97
+ }
98
+ // action === 'verify'
99
+ if (!options.code)
100
+ throw new Error('Code is required for verify');
101
+ const currentCounter = options.counter !== undefined ? BigInt(options.counter) : BigInt(Math.floor(Date.now() / 1000 / period));
102
+ for (let drift = 0; drift <= 1; drift++) {
103
+ const counter = currentCounter - BigInt(drift);
104
+ if (counter < 0n)
105
+ continue;
106
+ const code = generateHotp(secretBuf, counter, algorithm, digits);
107
+ if (codesEqual(code, options.code))
108
+ return { valid: true, drift: drift === 0 ? 0 : -drift };
109
+ }
110
+ for (let drift = 1; drift <= 1; drift++) {
111
+ const code = generateHotp(secretBuf, currentCounter + BigInt(drift), algorithm, digits);
112
+ if (codesEqual(code, options.code))
113
+ return { valid: true, drift };
114
+ }
115
+ return { valid: false, drift: 0 };
116
+ }
117
+ //# sourceMappingURL=otp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otp.js","sourceRoot":"","sources":["../../../src/modules/v5/otp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import type { ChallengeStorage } from '../../types/storage.js';
2
+ import type { ChallengeVerification } from '../../utils/challenge.js';
3
+ export interface PowChallenge {
4
+ algorithm: 'sha256';
5
+ salt: string;
6
+ difficulty: number;
7
+ expires: number;
8
+ token: string;
9
+ instructions: string;
10
+ }
11
+ /**
12
+ * Issues a proof-of-work challenge: the client must find a nonce whose hash
13
+ * starts with the requested number of hexadecimal zeros. Difficulty 4 averages
14
+ * about 32k hashes, unnoticeable for a person but costly to repeat at scale.
15
+ *
16
+ * @param difficulty - Leading hexadecimal zeros required (1-6, default 4)
17
+ * @returns Challenge with its salt, difficulty, expiry and signed token
18
+ * @throws Error if the difficulty is not a number or out of range
19
+ */
20
+ export default function pow(difficulty?: number): PowChallenge;
21
+ /**
22
+ * Verifies a solved proof-of-work challenge, then consumes the token.
23
+ *
24
+ * @param token - Token issued by the challenge
25
+ * @param nonce - Nonce found by the client
26
+ * @param storage - Store of already consumed nonces
27
+ * @returns Verification result, with a reason when it fails
28
+ */
29
+ export declare function verifyPow(token: string, nonce: string, storage: ChallengeStorage): ChallengeVerification;
@@ -0,0 +1,49 @@
1
+ import { createHash, randomBytes } from 'node:crypto';
2
+ import { MAX_POW_DIFFICULTY, POW_DEFAULT_DIFFICULTY } from '../../constants.js';
3
+ import { readToken, signToken, verifyToken } from '../../utils/challenge.js';
4
+ const digest = (salt, nonce) => createHash('sha256').update(`${salt}${nonce}`).digest('hex');
5
+ /**
6
+ * Issues a proof-of-work challenge: the client must find a nonce whose hash
7
+ * starts with the requested number of hexadecimal zeros. Difficulty 4 averages
8
+ * about 32k hashes, unnoticeable for a person but costly to repeat at scale.
9
+ *
10
+ * @param difficulty - Leading hexadecimal zeros required (1-6, default 4)
11
+ * @returns Challenge with its salt, difficulty, expiry and signed token
12
+ * @throws Error if the difficulty is not a number or out of range
13
+ */
14
+ export default function pow(difficulty = POW_DEFAULT_DIFFICULTY) {
15
+ if (isNaN(difficulty))
16
+ throw new Error('Difficulty must be a number');
17
+ if (!Number.isInteger(difficulty) || difficulty < 1 || difficulty > MAX_POW_DIFFICULTY) {
18
+ throw new Error(`Difficulty must be between 1 and ${MAX_POW_DIFFICULTY}`);
19
+ }
20
+ const salt = randomBytes(8).toString('hex');
21
+ const token = signToken('pow', `${salt}.${difficulty}`, { salt, difficulty });
22
+ return {
23
+ algorithm: 'sha256',
24
+ salt,
25
+ difficulty,
26
+ expires: readToken(token).exp,
27
+ token,
28
+ instructions: `Find nonce so that sha256(salt + nonce) starts with ${difficulty} hex zeros`,
29
+ };
30
+ }
31
+ /**
32
+ * Verifies a solved proof-of-work challenge, then consumes the token.
33
+ *
34
+ * @param token - Token issued by the challenge
35
+ * @param nonce - Nonce found by the client
36
+ * @param storage - Store of already consumed nonces
37
+ * @returns Verification result, with a reason when it fails
38
+ */
39
+ export function verifyPow(token, nonce, storage) {
40
+ const decoded = readToken(token);
41
+ if (!decoded || decoded.type !== 'pow' || !decoded.salt || !decoded.difficulty) {
42
+ return { valid: false, reason: 'invalid' };
43
+ }
44
+ if (!digest(decoded.salt, nonce).startsWith('0'.repeat(decoded.difficulty))) {
45
+ return { valid: false, reason: 'wrong' };
46
+ }
47
+ return verifyToken(token, `${decoded.salt}.${decoded.difficulty}`, storage);
48
+ }
49
+ //# sourceMappingURL=pow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pow.js","sourceRoot":"","sources":["../../../src/modules/v5/pow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEtD,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAGhF,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAW7E,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,KAAa,EAAU,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAErH;;;;;;;;GAQG;AACH,MAAM,CAAC,OAAO,UAAU,GAAG,CAAC,aAAqB,sBAAsB;IACnE,IAAI,KAAK,CAAC,UAAU,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACtE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC,IAAI,UAAU,GAAG,kBAAkB,EAAE,CAAC;QACrF,MAAM,IAAI,KAAK,CAAC,oCAAoC,kBAAkB,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC5C,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,EAAE,GAAG,IAAI,IAAI,UAAU,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;IAE9E,OAAO;QACH,SAAS,EAAE,QAAQ;QACnB,IAAI;QACJ,UAAU;QACV,OAAO,EAAE,SAAS,CAAC,KAAK,CAAE,CAAC,GAAG;QAC9B,KAAK;QACL,YAAY,EAAE,uDAAuD,UAAU,YAAY;KAC9F,CAAC;AACN,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS,CAAC,KAAa,EAAE,KAAa,EAAE,OAAyB;IAC7E,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;QAC7E,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAC/C,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;QAC1E,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IAC7C,CAAC;IAED,OAAO,WAAW,CAAC,KAAK,EAAE,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,UAAU,EAAE,EAAE,OAAO,CAAC,CAAC;AAChF,CAAC"}
@@ -0,0 +1,20 @@
1
+ export interface ReadResult {
2
+ lang: string;
3
+ words: number;
4
+ sentences: number;
5
+ syllables: number;
6
+ fleschReadingEase: number;
7
+ fleschKincaidGrade: number | null;
8
+ readingTime: string;
9
+ }
10
+ /**
11
+ * Computes Flesch readability scores on a text. English uses the original
12
+ * Flesch coefficients; French uses the Kandel & Moles adaptation, which has no
13
+ * grade-level counterpart, so fleschKincaidGrade is null for French.
14
+ *
15
+ * @param text - The text to analyze
16
+ * @param lang - Language of the text: en (default) or fr
17
+ * @returns Word, sentence and syllable counts, Flesch scores and estimated reading time
18
+ * @throws Error if the text is missing or too long, or if the language is unsupported
19
+ */
20
+ export default function read(text: string, lang?: string): ReadResult;
@@ -0,0 +1,59 @@
1
+ import { MAX_READ_LENGTH } from '../../constants.js';
2
+ const LANGUAGES = ['en', 'fr'];
3
+ // English heuristic: vowel groups minus silent trailing "e", at least one syllable.
4
+ function countSyllablesEn(word) {
5
+ const groups = word
6
+ .toLowerCase()
7
+ .replace(/[^a-z]/g, '')
8
+ .replace(/e$/, '')
9
+ .match(/[aeiouy]+/g);
10
+ return Math.max(1, groups ? groups.length : 1);
11
+ }
12
+ // French heuristic: accented vowels count as vowels, a trailing "e"/"es" is silent.
13
+ function countSyllablesFr(word) {
14
+ const groups = word
15
+ .toLowerCase()
16
+ .replace(/[^a-zàâäéèêëîïôöùûüÿç]/g, '')
17
+ .replace(/es?$/, '')
18
+ .match(/[aeiouyàâäéèêëîïôöùûüÿ]+/g);
19
+ return Math.max(1, groups ? groups.length : 1);
20
+ }
21
+ const round2 = (n) => Math.round(n * 100) / 100;
22
+ /**
23
+ * Computes Flesch readability scores on a text. English uses the original
24
+ * Flesch coefficients; French uses the Kandel & Moles adaptation, which has no
25
+ * grade-level counterpart, so fleschKincaidGrade is null for French.
26
+ *
27
+ * @param text - The text to analyze
28
+ * @param lang - Language of the text: en (default) or fr
29
+ * @returns Word, sentence and syllable counts, Flesch scores and estimated reading time
30
+ * @throws Error if the text is missing or too long, or if the language is unsupported
31
+ */
32
+ export default function read(text, lang = 'en') {
33
+ if (!text || !text.trim())
34
+ throw new Error('Please provide a text');
35
+ if (text.length > MAX_READ_LENGTH)
36
+ throw new Error(`Text must be ${MAX_READ_LENGTH} characters or fewer`);
37
+ if (!LANGUAGES.includes(lang))
38
+ throw new Error(`Language must be one of: ${LANGUAGES.join(', ')}`);
39
+ const wordList = text
40
+ .trim()
41
+ .split(/\s+/)
42
+ .filter((w) => /[\p{L}\p{N}]/u.test(w));
43
+ const words = wordList.length;
44
+ if (words === 0)
45
+ throw new Error('Please provide a text');
46
+ const sentences = text.split(/[.!?…]+/).filter((s) => s.trim()).length || 1;
47
+ const countSyllables = lang === 'fr' ? countSyllablesFr : countSyllablesEn;
48
+ const syllables = wordList.reduce((sum, word) => sum + countSyllables(word), 0);
49
+ const wordsPerSentence = words / sentences;
50
+ const syllablesPerWord = syllables / words;
51
+ const fleschReadingEase = lang === 'fr'
52
+ ? round2(207 - 1.015 * wordsPerSentence - 73.6 * syllablesPerWord)
53
+ : round2(206.835 - 1.015 * wordsPerSentence - 84.6 * syllablesPerWord);
54
+ const fleschKincaidGrade = lang === 'fr' ? null : round2(0.39 * wordsPerSentence + 11.8 * syllablesPerWord - 15.59);
55
+ const minutes = words / 200;
56
+ const readingTime = minutes < 1 ? `${Math.ceil(minutes * 60)}s` : `${Math.round(minutes)}min`;
57
+ return { lang, words, sentences, syllables, fleschReadingEase, fleschKincaidGrade, readingTime };
58
+ }
59
+ //# sourceMappingURL=read.js.map