@tbela99/css-parser 0.3.0 → 0.4.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 (61) hide show
  1. package/{LICENSE → LICENSE.md} +1 -1
  2. package/README.md +191 -80
  3. package/dist/config.json.js +20 -1
  4. package/dist/index-umd-web.js +3210 -1352
  5. package/dist/index.cjs +3211 -1353
  6. package/dist/index.d.ts +910 -0
  7. package/dist/lib/ast/expand.js +1 -1
  8. package/dist/lib/ast/features/calc.js +1 -2
  9. package/dist/lib/ast/features/inlinecssvariables.js +1 -1
  10. package/dist/lib/ast/features/shorthand.js +1 -1
  11. package/dist/lib/ast/math/expression.js +38 -3
  12. package/dist/lib/ast/math/math.js +2 -2
  13. package/dist/lib/ast/minify.js +0 -1
  14. package/dist/lib/ast/types.js +1 -0
  15. package/dist/lib/ast/utils/minifyfeature.js +4 -3
  16. package/dist/lib/parser/declaration/list.js +1 -1
  17. package/dist/lib/parser/declaration/map.js +129 -26
  18. package/dist/lib/parser/declaration/set.js +1 -1
  19. package/dist/lib/parser/parse.js +325 -303
  20. package/dist/lib/parser/tokenize.js +220 -223
  21. package/dist/lib/parser/utils/declaration.js +1 -1
  22. package/dist/lib/parser/utils/syntax.js +159 -23
  23. package/dist/lib/parser/utils/type.js +2 -2
  24. package/dist/lib/renderer/color/a98rgb.js +64 -0
  25. package/dist/lib/renderer/color/color.js +521 -0
  26. package/dist/lib/renderer/color/colormix.js +337 -0
  27. package/dist/lib/renderer/color/hex.js +92 -0
  28. package/dist/lib/renderer/color/hsl.js +118 -0
  29. package/dist/lib/renderer/color/hsv.js +20 -0
  30. package/dist/lib/renderer/color/hwb.js +101 -0
  31. package/dist/lib/renderer/color/lab.js +136 -0
  32. package/dist/lib/renderer/color/lch.js +79 -0
  33. package/dist/lib/renderer/color/oklab.js +121 -0
  34. package/dist/lib/renderer/color/oklch.js +65 -0
  35. package/dist/lib/renderer/color/p3.js +57 -0
  36. package/dist/lib/renderer/color/prophotorgb.js +56 -0
  37. package/dist/lib/renderer/color/rec2020.js +70 -0
  38. package/dist/lib/renderer/color/relativecolor.js +152 -0
  39. package/dist/lib/renderer/color/rgb.js +44 -0
  40. package/dist/lib/renderer/color/srgb.js +261 -0
  41. package/dist/lib/renderer/color/utils/components.js +20 -0
  42. package/dist/lib/renderer/color/utils/constants.js +191 -0
  43. package/dist/lib/renderer/color/utils/matrix.js +35 -0
  44. package/dist/lib/renderer/color/xyz.js +64 -0
  45. package/dist/lib/renderer/color/xyzd50.js +33 -0
  46. package/dist/lib/renderer/render.js +61 -32
  47. package/dist/node/index.js +1 -1
  48. package/dist/node/load.js +1 -1
  49. package/dist/web/index.js +1 -1
  50. package/package.json +15 -14
  51. package/quickjs.sh +1 -0
  52. package/dist/lib/ast/features/utils/math.js +0 -95
  53. package/dist/lib/iterable/set.js +0 -48
  54. package/dist/lib/iterable/weakmap.js +0 -53
  55. package/dist/lib/renderer/utils/calccolor.js +0 -238
  56. package/dist/lib/renderer/utils/color.js +0 -371
  57. package/dist/lib/renderer/utils/hex.js +0 -124
  58. package/dist/lib/renderer/utils/hsl.js +0 -49
  59. package/dist/lib/renderer/utils/hsv.js +0 -15
  60. package/dist/lib/renderer/utils/hwb.js +0 -50
  61. package/dist/lib/renderer/utils/rgb.js +0 -66
@@ -0,0 +1,35 @@
1
+ // from https://www.w3.org/TR/css-color-4/multiply-matrices.js
2
+ /**
3
+ * Simple matrix (and vector) multiplication
4
+ * Warning: No error handling for incompatible dimensions!
5
+ * @author Lea Verou 2020 MIT License
6
+ */
7
+ // A is m x n. B is n x p. product is m x p.
8
+ function multiplyMatrices(A, B) {
9
+ let m = A.length;
10
+ if (!Array.isArray(A[0])) {
11
+ // A is vector, convert to [[a, b, c, ...]]
12
+ A = [A];
13
+ }
14
+ if (!Array.isArray(B[0])) {
15
+ // B is vector, convert to [[a], [b], [c], ...]]
16
+ B = B.map((x) => [x]);
17
+ }
18
+ let p = B[0].length;
19
+ let B_cols = B[0].map((_, i) => B.map((x) => x[i])); // transpose B
20
+ let product = A.map((row) => B_cols.map((col) => {
21
+ if (!Array.isArray(row)) {
22
+ return col.reduce((a, c) => a + c * row, 0);
23
+ }
24
+ return row.reduce((a, c, i) => a + c * (col[i] || 0), 0);
25
+ }));
26
+ if (m === 1) {
27
+ product = product[0]; // Avoid [[a, b, c, ...]]
28
+ }
29
+ if (p === 1) {
30
+ return product.map((x) => x[0]); // Avoid [[a], [b], [c], ...]]
31
+ }
32
+ return product;
33
+ }
34
+
35
+ export { multiplyMatrices };
@@ -0,0 +1,64 @@
1
+ import { multiplyMatrices } from './utils/matrix.js';
2
+ import './utils/constants.js';
3
+ import '../../ast/types.js';
4
+ import '../../ast/minify.js';
5
+ import '../../parser/parse.js';
6
+ import { lsrgb2srgbvalues, srgb2lsrgbvalues } from './srgb.js';
7
+ import '../sourcemap/lib/encode.js';
8
+
9
+ function xyzd502srgb(x, y, z) {
10
+ // @ts-ignore
11
+ return lsrgb2srgbvalues(
12
+ /* r: */
13
+ x * 3.1341359569958707 -
14
+ y * 1.6173863321612538 -
15
+ 0.4906619460083532 * z,
16
+ /* g: */
17
+ x * -0.978795502912089 +
18
+ y * 1.916254567259524 +
19
+ 0.03344273116131949 * z,
20
+ /* b: */
21
+ x * 0.07195537988411677 -
22
+ y * 0.2289768264158322 +
23
+ 1.405386058324125 * z);
24
+ }
25
+ function XYZ_to_lin_sRGB(x, y, z) {
26
+ // convert XYZ to linear-light sRGB
27
+ const M = [
28
+ [12831 / 3959, -329 / 214, -1974 / 3959],
29
+ [-851781 / 878810, 1648619 / 878810, 36519 / 878810],
30
+ [705 / 12673, -2585 / 12673, 705 / 667],
31
+ ];
32
+ const XYZ = [x, y, z]; // convert to XYZ
33
+ return multiplyMatrices(M, XYZ).map((v) => v);
34
+ }
35
+ function XYZ_D50_to_D65(x, y, z) {
36
+ // Bradford chromatic adaptation from D50 to D65
37
+ const M = [
38
+ [0.9554734527042182, -0.023098536874261423, 0.0632593086610217],
39
+ [-0.028369706963208136, 1.0099954580058226, 0.021041398966943008],
40
+ [0.012314001688319899, -0.020507696433477912, 1.3303659366080753]
41
+ ];
42
+ const XYZ = [x, y, z];
43
+ return multiplyMatrices(M, XYZ); //.map((v: number) => v);
44
+ }
45
+ function srgb2xyz(r, g, b, alpha) {
46
+ [r, g, b] = srgb2lsrgbvalues(r, g, b);
47
+ const rgb = [
48
+ 0.436065742824811 * r +
49
+ 0.3851514688337912 * g +
50
+ 0.14307845442264197 * b,
51
+ 0.22249319175623702 * r +
52
+ 0.7168870538238823 * g +
53
+ 0.06061979053616537 * b,
54
+ 0.013923904500943465 * r +
55
+ 0.09708128566574634 * g +
56
+ 0.7140993584005155 * b
57
+ ];
58
+ if (alpha != null && alpha != 1) {
59
+ rgb.push(alpha);
60
+ }
61
+ return rgb;
62
+ }
63
+
64
+ export { XYZ_D50_to_D65, XYZ_to_lin_sRGB, srgb2xyz, xyzd502srgb };
@@ -0,0 +1,33 @@
1
+ import { multiplyMatrices } from './utils/matrix.js';
2
+ import './utils/constants.js';
3
+ import '../../ast/types.js';
4
+ import '../../ast/minify.js';
5
+ import '../../parser/parse.js';
6
+ import { xyz2lab } from './lab.js';
7
+ import { lab2lchvalues } from './lch.js';
8
+ import { XYZ_D50_to_D65 } from './xyz.js';
9
+ import '../sourcemap/lib/encode.js';
10
+
11
+ function xyzd502lch(x, y, z, alpha) {
12
+ // @ts-ignore
13
+ const [l, a, b] = xyz2lab(...XYZ_D50_to_D65(x, y, z));
14
+ // L in range [0,100]. For use in CSS, add a percent
15
+ // @ts-ignore
16
+ return lab2lchvalues(l, a, b, alpha);
17
+ }
18
+ function XYZ_D65_to_D50(x, y, z) {
19
+ // Bradford chromatic adaptation from D65 to D50
20
+ // The matrix below is the result of three operations:
21
+ // - convert from XYZ to retinal cone domain
22
+ // - scale components from one reference white to another
23
+ // - convert back to XYZ
24
+ // see https://github.com/LeaVerou/color.js/pull/354/files
25
+ var M = [
26
+ [1.0479297925449969, 0.022946870601609652, -0.05019226628920524],
27
+ [0.02962780877005599, 0.9904344267538799, -0.017073799063418826],
28
+ [-0.009243040646204504, 0.015055191490298152, 0.7518742814281371]
29
+ ];
30
+ return multiplyMatrices(M, [x, y, z]);
31
+ }
32
+
33
+ export { XYZ_D65_to_D50, xyzd502lch };
@@ -1,14 +1,17 @@
1
- import { getAngle, clamp, COLORS_NAMES, NAMES_COLORS } from './utils/color.js';
2
- import { rgb2Hex, hsl2Hex, hwb2hex, cmyk2hex } from './utils/hex.js';
1
+ import { getAngle, color2srgbvalues, clamp } from './color/color.js';
2
+ import { colorFuncColorSpace, COLORS_NAMES } from './color/utils/constants.js';
3
+ import { getComponents } from './color/utils/components.js';
4
+ import { reduceHexValue, srgb2hexvalues, rgb2hex, hsl2hex, hwb2hex, cmyk2hex, oklab2hex, oklch2hex, lab2hex, lch2hex } from './color/hex.js';
3
5
  import { EnumToken } from '../ast/types.js';
4
6
  import '../ast/minify.js';
5
7
  import { expand } from '../ast/expand.js';
8
+ import { colorMix } from './color/colormix.js';
9
+ import { parseRelativeColor } from './color/relativecolor.js';
6
10
  import { SourceMap } from './sourcemap/sourcemap.js';
7
11
  import '../parser/parse.js';
8
12
  import { isColor, isNewLine } from '../parser/utils/syntax.js';
9
- import { parseRelativeColor } from './utils/calccolor.js';
10
13
 
11
- const colorsFunc = ['rgb', 'rgba', 'hsl', 'hsla', 'hwb', 'device-cmyk'];
14
+ const colorsFunc = ['rgb', 'rgba', 'hsl', 'hsla', 'hwb', 'device-cmyk', 'color-mix', 'color', 'oklab', 'lab', 'oklch', 'lch'];
12
15
  function reduceNumber(val) {
13
16
  val = String(+val);
14
17
  if (val === '0') {
@@ -85,12 +88,10 @@ function updateSourceMap(node, options, cache, sourcemap, position, str) {
85
88
  if ([EnumToken.RuleNodeType, EnumToken.AtRuleNodeType].includes(node.typ)) {
86
89
  let src = node.loc?.src ?? '';
87
90
  let output = options.output ?? '';
88
- // if (src !== '') {
89
91
  if (!(src in cache)) {
90
92
  // @ts-ignore
91
93
  cache[src] = options.resolve(src, options.cwd ?? '').relative;
92
94
  }
93
- // }
94
95
  if (!(output in cache)) {
95
96
  // @ts-ignore
96
97
  cache[output] = options.resolve(output, options.cwd).relative;
@@ -209,7 +210,15 @@ function renderToken(token, options = {}, cache = Object.create(null), reducer,
209
210
  // @ts-ignore
210
211
  token.cal = 'rel';
211
212
  }
213
+ else if (token.val == 'color-mix' && token.chi[0].typ == EnumToken.IdenTokenType && token.chi[0].val == 'in') {
214
+ // @ts-ignore
215
+ token.cal = 'mix';
216
+ }
212
217
  else {
218
+ if (token.val == 'color') {
219
+ // @ts-ignore
220
+ token.cal = 'col';
221
+ }
213
222
  token.chi = token.chi.filter((t) => ![EnumToken.WhitespaceTokenType, EnumToken.CommaTokenType, EnumToken.CommentTokenType].includes(t.typ));
214
223
  }
215
224
  }
@@ -257,17 +266,41 @@ function renderToken(token, options = {}, cache = Object.create(null), reducer,
257
266
  return '/';
258
267
  case EnumToken.ColorTokenType:
259
268
  if (options.convertColor) {
260
- if (token.cal == 'rel' && ['rgb', 'hsl', 'hwb'].includes(token.val)) {
261
- const chi = token.chi.filter(x => ![
262
- EnumToken.LiteralTokenType, EnumToken.CommaTokenType, EnumToken.WhitespaceTokenType, EnumToken.CommentTokenType
263
- ].includes(x.typ));
264
- const components = parseRelativeColor(token.val.split(''), chi[1], chi[2], chi[3], chi[4], chi[5]);
269
+ if (token.cal == 'mix' && token.val == 'color-mix') {
270
+ const children = token.chi.reduce((acc, t) => {
271
+ if (t.typ == EnumToken.ColorTokenType) {
272
+ acc.push([t]);
273
+ }
274
+ else {
275
+ if (![EnumToken.WhitespaceTokenType, EnumToken.CommentTokenType].includes(t.typ)) {
276
+ acc[acc.length - 1].push(t);
277
+ }
278
+ }
279
+ return acc;
280
+ }, [[]]);
281
+ const value = colorMix(children[0][1], children[0][2], children[1][0], children[1][1], children[2][0], children[2][1]);
282
+ if (value != null) {
283
+ token = value;
284
+ }
285
+ }
286
+ if (token.cal == 'rel' && ['rgb', 'hsl', 'hwb', 'lab', 'lch', 'oklab', 'oklch', 'color'].includes(token.val)) {
287
+ const chi = getComponents(token);
288
+ const offset = token.val == 'color' ? 2 : 1;
289
+ // @ts-ignore
290
+ const color = chi[1];
291
+ const components = parseRelativeColor(token.val == 'color' ? chi[offset].val : token.val, color, chi[offset + 1], chi[offset + 2], chi[offset + 3], chi[offset + 4]);
265
292
  if (components != null) {
266
- token.chi = Object.values(components);
293
+ token.chi = [...(token.val == 'color' ? [chi[offset]] : []), ...Object.values(components)];
267
294
  delete token.cal;
268
295
  }
269
296
  }
270
- if (token.cal) {
297
+ if (token.val == 'color') {
298
+ if (token.chi[0].typ == EnumToken.IdenTokenType && colorFuncColorSpace.includes(token.chi[0].val.toLowerCase())) {
299
+ // @ts-ignore
300
+ return reduceHexValue(srgb2hexvalues(...color2srgbvalues(token)));
301
+ }
302
+ }
303
+ if (token.cal != null) {
271
304
  let slice = false;
272
305
  if (token.cal == 'rel') {
273
306
  const last = token.chi.at(-1);
@@ -298,10 +331,10 @@ function renderToken(token, options = {}, cache = Object.create(null), reducer,
298
331
  }
299
332
  let value = token.kin == 'hex' ? token.val.toLowerCase() : (token.kin == 'lit' ? COLORS_NAMES[token.val.toLowerCase()] : '');
300
333
  if (token.val == 'rgb' || token.val == 'rgba') {
301
- value = rgb2Hex(token);
334
+ value = rgb2hex(token);
302
335
  }
303
336
  else if (token.val == 'hsl' || token.val == 'hsla') {
304
- value = hsl2Hex(token);
337
+ value = hsl2hex(token);
305
338
  }
306
339
  else if (token.val == 'hwb') {
307
340
  value = hwb2hex(token);
@@ -309,24 +342,20 @@ function renderToken(token, options = {}, cache = Object.create(null), reducer,
309
342
  else if (token.val == 'device-cmyk') {
310
343
  value = cmyk2hex(token);
311
344
  }
312
- const named_color = NAMES_COLORS[value];
345
+ else if (token.val == 'oklab') {
346
+ value = oklab2hex(token);
347
+ }
348
+ else if (token.val == 'oklch') {
349
+ value = oklch2hex(token);
350
+ }
351
+ else if (token.val == 'lab') {
352
+ value = lab2hex(token);
353
+ }
354
+ else if (token.val == 'lch') {
355
+ value = lch2hex(token);
356
+ }
313
357
  if (value !== '') {
314
- if (value.length == 7) {
315
- if (value[1] == value[2] &&
316
- value[3] == value[4] &&
317
- value[5] == value[6]) {
318
- value = `#${value[1]}${value[3]}${value[5]}`;
319
- }
320
- }
321
- else if (value.length == 9) {
322
- if (value[1] == value[2] &&
323
- value[3] == value[4] &&
324
- value[5] == value[6] &&
325
- value[7] == value[8]) {
326
- value = `#${value[1]}${value[3]}${value[5]}${value[7]}`;
327
- }
328
- }
329
- return named_color != null && named_color.length <= value.length ? named_color : value;
358
+ return reduceHexValue(value);
330
359
  }
331
360
  }
332
361
  if (token.kin == 'hex' || token.kin == 'lit') {
@@ -6,7 +6,7 @@ import { doRender } from '../lib/renderer/render.js';
6
6
  export { renderToken } from '../lib/renderer/render.js';
7
7
  import { doParse } from '../lib/parser/parse.js';
8
8
  export { parseString, parseTokens } from '../lib/parser/parse.js';
9
- import '../lib/renderer/utils/color.js';
9
+ import '../lib/renderer/color/utils/constants.js';
10
10
  import { resolve, dirname } from '../lib/fs/resolve.js';
11
11
  import { load } from './load.js';
12
12
 
package/dist/node/load.js CHANGED
@@ -1,4 +1,4 @@
1
- import { readFile } from 'fs/promises';
1
+ import { readFile } from 'node:fs/promises';
2
2
  import { resolve, matchUrl } from '../lib/fs/resolve.js';
3
3
 
4
4
  function parseResponse(response) {
package/dist/web/index.js CHANGED
@@ -6,7 +6,7 @@ import { doRender } from '../lib/renderer/render.js';
6
6
  export { renderToken } from '../lib/renderer/render.js';
7
7
  import { doParse } from '../lib/parser/parse.js';
8
8
  export { parseString, parseTokens } from '../lib/parser/parse.js';
9
- import '../lib/renderer/utils/color.js';
9
+ import '../lib/renderer/color/utils/constants.js';
10
10
  import { resolve, dirname } from '../lib/fs/resolve.js';
11
11
  import { load } from './load.js';
12
12
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tbela99/css-parser",
3
3
  "description": "CSS parser for node and the browser",
4
- "version": "0.3.0",
4
+ "version": "0.4.0",
5
5
  "exports": {
6
6
  ".": "./dist/node/index.js",
7
7
  "./umd": "./dist/index-umd-web.js",
@@ -45,19 +45,20 @@
45
45
  "homepage": "https://github.com/tbela99/css-parser#readme",
46
46
  "devDependencies": {
47
47
  "@esm-bundle/chai": "^4.3.4-fix.0",
48
- "@rollup/plugin-commonjs": "^25.0.4",
49
- "@rollup/plugin-json": "^6.0.0",
50
- "@rollup/plugin-node-resolve": "^15.1.0",
51
- "@rollup/plugin-typescript": "^11.1.2",
52
- "@types/chai": "^4.3.5",
53
- "@types/mocha": "^10.0.1",
54
- "@types/node": "^20.4.10",
55
- "@web/test-runner": "^0.17.0",
48
+ "@rollup/plugin-commonjs": "^25.0.7",
49
+ "@rollup/plugin-json": "^6.1.0",
50
+ "@rollup/plugin-node-resolve": "^15.2.3",
51
+ "@rollup/plugin-typescript": "^11.1.6",
52
+ "@types/chai": "^4.3.12",
53
+ "@types/mocha": "^10.0.6",
54
+ "@types/node": "^20.11.25",
55
+ "@web/test-runner": "^0.18.1",
56
56
  "@web/test-runner-playwright": "^0.11.0",
57
- "c8": "^8.0.1",
58
- "mocha": "^10.2.0",
59
- "rollup": "^3.28.0",
60
- "rollup-plugin-dts": "^5.3.1",
61
- "tslib": "^2.6.1"
57
+ "c8": "^9.1.0",
58
+ "mocha": "^10.4.0",
59
+ "playwright": "^1.42.1",
60
+ "rollup": "^4.13.0",
61
+ "rollup-plugin-dts": "^6.1.0",
62
+ "tslib": "^2.6.2"
62
63
  }
63
64
  }
package/quickjs.sh ADDED
@@ -0,0 +1 @@
1
+ qjsc -e -o c/css.c dist/index-umd-web.js
@@ -1,95 +0,0 @@
1
- import { EnumToken } from '../../types.js';
2
- import { reduceNumber } from '../../../renderer/render.js';
3
-
4
- const gcd = (x, y) => {
5
- x = Math.abs(x);
6
- y = Math.abs(y);
7
- let t;
8
- if (x == 0 || y == 0) {
9
- return 1;
10
- }
11
- while (y) {
12
- t = y;
13
- y = x % y;
14
- x = t;
15
- }
16
- return x;
17
- };
18
- function compute(a, b, op) {
19
- if (typeof a == 'number' && typeof b == 'number') {
20
- switch (op) {
21
- case EnumToken.Add:
22
- return a + b;
23
- case EnumToken.Sub:
24
- return a - b;
25
- case EnumToken.Mul:
26
- return a * b;
27
- case EnumToken.Div:
28
- const r = simplify(a, b);
29
- if (r[1] == 1) {
30
- return r[0];
31
- }
32
- const result = a / b;
33
- const r2 = reduceNumber(r[0]) + '/' + reduceNumber(r[1]);
34
- return reduceNumber(result).length <= r2.length ? result : {
35
- typ: EnumToken.FractionTokenType,
36
- l: { typ: EnumToken.NumberTokenType, val: reduceNumber(r[0]) },
37
- r: { typ: EnumToken.NumberTokenType, val: reduceNumber(r[1]) }
38
- };
39
- }
40
- }
41
- let l1 = typeof a == 'number' ? {
42
- typ: EnumToken.FractionTokenType,
43
- l: { typ: EnumToken.NumberTokenType, val: reduceNumber(a) },
44
- r: { typ: EnumToken.NumberTokenType, val: '1' }
45
- } : a;
46
- let r1 = typeof b == 'number' ? {
47
- typ: EnumToken.FractionTokenType,
48
- l: { typ: EnumToken.NumberTokenType, val: reduceNumber(b) },
49
- r: { typ: EnumToken.NumberTokenType, val: '1' }
50
- } : b;
51
- let l2;
52
- let r2;
53
- switch (op) {
54
- case EnumToken.Add:
55
- // @ts-ignore
56
- l2 = l1.l.val * r1.r.val + l1.r.val * r1.l.val;
57
- // @ts-ignore
58
- r2 = l1.r.val * r1.r.val;
59
- break;
60
- case EnumToken.Sub:
61
- // @ts-ignore
62
- l2 = l1.l.val * r1.r.val - l1.r.val * r1.l.val;
63
- // @ts-ignore
64
- r2 = l1.r.val * r1.r.val;
65
- break;
66
- case EnumToken.Mul:
67
- // @ts-ignore
68
- l2 = l1.l.val * r1.l.val;
69
- // @ts-ignore
70
- r2 = l1.r.val * r1.r.val;
71
- break;
72
- case EnumToken.Div:
73
- // @ts-ignore
74
- l2 = l1.l.val * r1.r.val;
75
- // @ts-ignore
76
- r2 = l1.r.val * r1.l.val;
77
- break;
78
- }
79
- const a2 = simplify(l2, r2);
80
- if (a2[1] == 1) {
81
- return a2[0];
82
- }
83
- const result = a2[0] / a2[1];
84
- return reduceNumber(result).length <= reduceNumber(a2[0]).length + 1 + reduceNumber(a2[1]).length ? result : {
85
- typ: EnumToken.FractionTokenType,
86
- l: { typ: EnumToken.NumberTokenType, val: reduceNumber(a2[0]) },
87
- r: { typ: EnumToken.NumberTokenType, val: reduceNumber(a2[1]) }
88
- };
89
- }
90
- function simplify(a, b) {
91
- const g = gcd(a, b);
92
- return g > 1 ? [a / g, b / g] : [a, b];
93
- }
94
-
95
- export { compute, gcd, simplify };
@@ -1,48 +0,0 @@
1
- class IterableWeakSet {
2
- #weakset = new WeakSet;
3
- #set = new Set;
4
- constructor(iterable) {
5
- if (iterable) {
6
- for (const value of iterable) {
7
- const ref = new WeakRef(value);
8
- this.#weakset.add(value);
9
- this.#set.add(ref);
10
- }
11
- }
12
- }
13
- has(value) {
14
- return this.#weakset.has(value);
15
- }
16
- delete(value) {
17
- if (this.#weakset.has(value)) {
18
- for (const ref of this.#set) {
19
- if (ref.deref() === value) {
20
- this.#set.delete(ref);
21
- break;
22
- }
23
- }
24
- return this.#weakset.delete(value);
25
- }
26
- return false;
27
- }
28
- add(value) {
29
- if (!this.#weakset.has(value)) {
30
- this.#weakset.add(value);
31
- this.#set.add(new WeakRef(value));
32
- }
33
- return this;
34
- }
35
- *[Symbol.iterator]() {
36
- for (const ref of new Set(this.#set)) {
37
- const key = ref.deref();
38
- if (key != null) {
39
- yield key;
40
- }
41
- else {
42
- this.#set.delete(ref);
43
- }
44
- }
45
- }
46
- }
47
-
48
- export { IterableWeakSet };
@@ -1,53 +0,0 @@
1
- class IterableWeakMap {
2
- #map;
3
- #set;
4
- constructor(iterable) {
5
- this.#map = new WeakMap;
6
- this.#set = new Set;
7
- if (iterable) {
8
- for (const [key, value] of iterable) {
9
- const ref = new WeakRef(key);
10
- this.#set.add(ref);
11
- this.#map.set(key, value);
12
- }
13
- }
14
- }
15
- has(key) {
16
- return this.#map.has(key);
17
- }
18
- set(key, value) {
19
- if (!this.#map.has(key)) {
20
- this.#set.add(new WeakRef(key));
21
- }
22
- this.#map.set(key, value);
23
- return this;
24
- }
25
- get(key) {
26
- return this.#map.get(key);
27
- }
28
- delete(key) {
29
- if (this.#map.has(key)) {
30
- for (const ref of this.#set) {
31
- if (ref.deref() === key) {
32
- this.#set.delete(ref);
33
- break;
34
- }
35
- }
36
- return this.#map.delete(key);
37
- }
38
- return false;
39
- }
40
- *[Symbol.iterator]() {
41
- for (const ref of new Set(this.#set)) {
42
- const key = ref.deref();
43
- if (key == null) {
44
- this.#set.delete(ref);
45
- continue;
46
- }
47
- // @ts-ignore
48
- yield [key, this.#map.get(key)];
49
- }
50
- }
51
- }
52
-
53
- export { IterableWeakMap };