es6-fuzz 7.0.1 → 7.1.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.
@@ -1 +1 @@
1
- {"version":3,"file":"fuzzy-function.d.ts","sourceRoot":"","sources":["../../src/curve/fuzzy-function.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,0CAA0C;AAC1C,qBAAa,aAAc,YAAW,SAAS;IAC7C,OAAO,CAAC,QAAQ,CAAC,EAAE,CAA0B;IAE7C;;;OAGG;gBACS,EAAE,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM;IAGvC;;;OAGG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;CAO7B"}
1
+ {"version":3,"file":"fuzzy-function.d.ts","sourceRoot":"","sources":["../../src/curve/fuzzy-function.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,0CAA0C;AAC1C,qBAAa,aAAc,YAAW,SAAS;IAC7C,OAAO,CAAC,QAAQ,CAAC,EAAE,CAA0B;IAE7C;;;OAGG;gBACS,EAAE,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM;IAGvC;;;OAGG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;CAU7B"}
@@ -17,7 +17,10 @@ class FuzzyFunction {
17
17
  */
18
18
  fuzzify(val) {
19
19
  const res = this.cb(val);
20
- if (res >= 0 && res <= 1) {
20
+ // The relational checks coerce their operands, so a non-number (string,
21
+ // boolean, null, array) could pass `res >= 0 && res <= 1` and be returned
22
+ // verbatim, breaking the `number` contract. Require an actual number.
23
+ if (typeof res === 'number' && res >= 0 && res <= 1) {
21
24
  return res;
22
25
  }
23
26
  throw Error('fuzzified result must be between 0 and 1 but is ' + res);
@@ -1 +1 @@
1
- {"version":3,"file":"fuzzy-function.js","sourceRoot":"","sources":["../../src/curve/fuzzy-function.ts"],"names":[],"mappings":";;;AACA,0CAA0C;AAC1C,MAAa,aAAa;IACP,EAAE,CAA0B;IAE7C;;;OAGG;IACH,YAAY,EAA2B;QACrC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;IACf,CAAC;IACD;;;OAGG;IACH,OAAO,CAAC,GAAW;QACjB,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;QACzB,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;YACzB,OAAO,GAAG,CAAC;QACb,CAAC;QACD,MAAM,KAAK,CAAC,kDAAkD,GAAG,GAAG,CAAC,CAAC;IACxE,CAAC;CACF;AArBD,sCAqBC"}
1
+ {"version":3,"file":"fuzzy-function.js","sourceRoot":"","sources":["../../src/curve/fuzzy-function.ts"],"names":[],"mappings":";;;AACA,0CAA0C;AAC1C,MAAa,aAAa;IACP,EAAE,CAA0B;IAE7C;;;OAGG;IACH,YAAY,EAA2B;QACrC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;IACf,CAAC;IACD;;;OAGG;IACH,OAAO,CAAC,GAAW;QACjB,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;QACzB,wEAAwE;QACxE,0EAA0E;QAC1E,sEAAsE;QACtE,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;YACpD,OAAO,GAAG,CAAC;QACb,CAAC;QACD,MAAM,KAAK,CAAC,kDAAkD,GAAG,GAAG,CAAC,CAAC;IACxE,CAAC;CACF;AAxBD,sCAwBC"}
@@ -1 +1 @@
1
- {"version":3,"file":"grade.d.ts","sourceRoot":"","sources":["../../src/curve/grade.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC;;;;GAIG;AACH,qBAAa,KAAM,SAAQ,KAAK;IAC9B;;;;OAIG;gBACS,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAGlC;;;;OAIG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;CAqB7B"}
1
+ {"version":3,"file":"grade.d.ts","sourceRoot":"","sources":["../../src/curve/grade.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC;;;;GAIG;AACH,qBAAa,KAAM,SAAQ,KAAK;IAC9B;;;;OAIG;gBACS,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAUlC;;;;OAIG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;CA2B7B"}
@@ -15,6 +15,13 @@ class Grade extends shape_1.Shape {
15
15
  */
16
16
  constructor(x0, x1) {
17
17
  super(x0, x1, x1, x1);
18
+ // Reject reversed finite params: with x0 > x1 the `x <= x0` guard swallows
19
+ // the whole interior, so the ramp collapses into a hard step and the linear
20
+ // branch becomes dead code. NaN/Infinity are left untouched (handled at
21
+ // fuzzify time and relied on by callers passing open-ended bounds).
22
+ if (Number.isFinite(x0) && Number.isFinite(x1) && x0 > x1) {
23
+ throw Error('Grade requires x0 <= x1 but got x0=' + x0 + ', x1=' + x1);
24
+ }
18
25
  }
19
26
  /**
20
27
  * Fuzzify
@@ -24,6 +31,9 @@ class Grade extends shape_1.Shape {
24
31
  fuzzify(val) {
25
32
  let result = 0;
26
33
  const x = val;
34
+ // NaN has no meaningful membership; treat it as outside the ramp (0).
35
+ if (Number.isNaN(x))
36
+ return 0;
27
37
  // Handle case where x0 = x1 (vertical grade/step function).
28
38
  // Treat it as the limit of the ramp: the foot at x0 is 0, like the normal
29
39
  // grade below, so behaviour stays continuous as x1 approaches x0.
@@ -39,7 +49,10 @@ class Grade extends shape_1.Shape {
39
49
  result = 1;
40
50
  }
41
51
  else {
42
- result = x / (this.x1 - this.x0) - this.x0 / (this.x1 - this.x0);
52
+ // Algebraically equal to x/(x1-x0) - x0/(x1-x0) but numerically stable:
53
+ // the split form subtracts two large nearly-equal quotients and loses
54
+ // significance for large coordinates (see Grade large-coordinate bug).
55
+ result = (x - this.x0) / (this.x1 - this.x0);
43
56
  }
44
57
  return result;
45
58
  }
@@ -1 +1 @@
1
- {"version":3,"file":"grade.js","sourceRoot":"","sources":["../../src/curve/grade.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;AACb,mCAAgC;AAChC;;;;GAIG;AACH,MAAa,KAAM,SAAQ,aAAK;IAC9B;;;;OAIG;IACH,YAAY,EAAU,EAAE,EAAU;QAChC,KAAK,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IACxB,CAAC;IACD;;;;OAIG;IACH,OAAO,CAAC,GAAW;QACjB,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,MAAM,CAAC,GAAG,GAAG,CAAC;QAEd,4DAA4D;QAC5D,0EAA0E;QAC1E,kEAAkE;QAClE,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC;YACxB,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE;gBAAE,OAAO,CAAC,CAAC;YAC3B,OAAO,CAAC,CAAC,CAAC,SAAS;QACrB,CAAC;QAED,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,GAAG,CAAC,CAAC;QACb,CAAC;aAAM,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACxB,MAAM,GAAG,CAAC,CAAC;QACb,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;QACnE,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AAnCD,sBAmCC"}
1
+ {"version":3,"file":"grade.js","sourceRoot":"","sources":["../../src/curve/grade.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;AACb,mCAAgC;AAChC;;;;GAIG;AACH,MAAa,KAAM,SAAQ,aAAK;IAC9B;;;;OAIG;IACH,YAAY,EAAU,EAAE,EAAU;QAChC,KAAK,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QACtB,2EAA2E;QAC3E,4EAA4E;QAC5E,wEAAwE;QACxE,oEAAoE;QACpE,IAAI,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC;YAC1D,MAAM,KAAK,CAAC,qCAAqC,GAAG,EAAE,GAAG,OAAO,GAAG,EAAE,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;IACD;;;;OAIG;IACH,OAAO,CAAC,GAAW;QACjB,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,MAAM,CAAC,GAAG,GAAG,CAAC;QAEd,sEAAsE;QACtE,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;QAE9B,4DAA4D;QAC5D,0EAA0E;QAC1E,kEAAkE;QAClE,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC;YACxB,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE;gBAAE,OAAO,CAAC,CAAC;YAC3B,OAAO,CAAC,CAAC,CAAC,SAAS;QACrB,CAAC;QAED,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,GAAG,CAAC,CAAC;QACb,CAAC;aAAM,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACxB,MAAM,GAAG,CAAC,CAAC;QACb,CAAC;aAAM,CAAC;YACN,wEAAwE;YACxE,sEAAsE;YACtE,uEAAuE;YACvE,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/C,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AAhDD,sBAgDC"}
@@ -1 +1 @@
1
- {"version":3,"file":"reverse-grade.d.ts","sourceRoot":"","sources":["../../src/curve/reverse-grade.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC;;;;GAIG;AACH,qBAAa,YAAa,SAAQ,KAAK;IACrC;;;;OAIG;gBACS,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAGlC;;;;OAIG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;CAe7B"}
1
+ {"version":3,"file":"reverse-grade.d.ts","sourceRoot":"","sources":["../../src/curve/reverse-grade.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC;;;;GAIG;AACH,qBAAa,YAAa,SAAQ,KAAK;IACrC;;;;OAIG;gBACS,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IASlC;;;;OAIG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;CAqB7B"}
@@ -15,6 +15,12 @@ class ReverseGrade extends shape_1.Shape {
15
15
  */
16
16
  constructor(x0, x1) {
17
17
  super(x0, x1, x1, x1);
18
+ // Reject reversed finite params: with x0 > x1 the falling edge collapses
19
+ // into a hard step and the linear branch becomes dead code. NaN/Infinity
20
+ // are left untouched (handled at fuzzify time).
21
+ if (Number.isFinite(x0) && Number.isFinite(x1) && x0 > x1) {
22
+ throw Error('ReverseGrade requires x0 <= x1 but got x0=' + x0 + ', x1=' + x1);
23
+ }
18
24
  }
19
25
  /**
20
26
  * Fuzzify
@@ -23,6 +29,9 @@ class ReverseGrade extends shape_1.Shape {
23
29
  */
24
30
  fuzzify(val) {
25
31
  const x = val;
32
+ // NaN has no meaningful membership; treat it as outside the ramp (0).
33
+ if (Number.isNaN(x))
34
+ return 0;
26
35
  // Vertical reverse grade (x0 = x1): step down, the mirror of Grade.
27
36
  // (The previous inline x0 === x1 handling sat in an unreachable branch:
28
37
  // when x0 === x1 every value is caught by x <= x0 or x >= x1 first.)
@@ -35,7 +44,10 @@ class ReverseGrade extends shape_1.Shape {
35
44
  return 1;
36
45
  if (x >= this.x1)
37
46
  return 0;
38
- return -x / (this.x1 - this.x0) + this.x1 / (this.x1 - this.x0);
47
+ // Algebraically equal to -x/(x1-x0) + x1/(x1-x0) but numerically stable:
48
+ // the split form adds two large nearly-equal quotients and loses
49
+ // significance for large coordinates.
50
+ return (this.x1 - x) / (this.x1 - this.x0);
39
51
  }
40
52
  }
41
53
  exports.ReverseGrade = ReverseGrade;
@@ -1 +1 @@
1
- {"version":3,"file":"reverse-grade.js","sourceRoot":"","sources":["../../src/curve/reverse-grade.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;AACb,mCAAgC;AAChC;;;;GAIG;AACH,MAAa,YAAa,SAAQ,aAAK;IACrC;;;;OAIG;IACH,YAAY,EAAU,EAAE,EAAU;QAChC,KAAK,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IACxB,CAAC;IACD;;;;OAIG;IACH,OAAO,CAAC,GAAW;QACjB,MAAM,CAAC,GAAG,GAAG,CAAC;QAEd,oEAAoE;QACpE,wEAAwE;QACxE,qEAAqE;QACrE,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC;YACxB,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE;gBAAE,OAAO,CAAC,CAAC;YAC3B,OAAO,CAAC,CAAC,CAAC,SAAS;QACrB,CAAC;QAED,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE;YAAE,OAAO,CAAC,CAAC;QAC3B,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE;YAAE,OAAO,CAAC,CAAC;QAC3B,OAAO,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;IAClE,CAAC;CACF;AA7BD,oCA6BC"}
1
+ {"version":3,"file":"reverse-grade.js","sourceRoot":"","sources":["../../src/curve/reverse-grade.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;AACb,mCAAgC;AAChC;;;;GAIG;AACH,MAAa,YAAa,SAAQ,aAAK;IACrC;;;;OAIG;IACH,YAAY,EAAU,EAAE,EAAU;QAChC,KAAK,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QACtB,yEAAyE;QACzE,yEAAyE;QACzE,gDAAgD;QAChD,IAAI,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC;YAC1D,MAAM,KAAK,CAAC,4CAA4C,GAAG,EAAE,GAAG,OAAO,GAAG,EAAE,CAAC,CAAC;QAChF,CAAC;IACH,CAAC;IACD;;;;OAIG;IACH,OAAO,CAAC,GAAW;QACjB,MAAM,CAAC,GAAG,GAAG,CAAC;QAEd,sEAAsE;QACtE,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;QAE9B,oEAAoE;QACpE,wEAAwE;QACxE,qEAAqE;QACrE,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC;YACxB,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE;gBAAE,OAAO,CAAC,CAAC;YAC3B,OAAO,CAAC,CAAC,CAAC,SAAS;QACrB,CAAC;QAED,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE;YAAE,OAAO,CAAC,CAAC;QAC3B,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE;YAAE,OAAO,CAAC,CAAC;QAC3B,yEAAyE;QACzE,iEAAiE;QACjE,sCAAsC;QACtC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7C,CAAC;CACF;AAzCD,oCAyCC"}
@@ -1 +1 @@
1
- {"version":3,"file":"shape.d.ts","sourceRoot":"","sources":["../../src/curve/shape.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,uCAAuC;AACvC,8BAAsB,KAAM,YAAW,SAAS;IAC9C,QAAQ,CAAC,EAAE,EAAG,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,EAAG,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,EAAG,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,EAAG,MAAM,CAAC;IAErB;;;;;;OAMG;gBACS,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAmB1D;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;CACtC"}
1
+ {"version":3,"file":"shape.d.ts","sourceRoot":"","sources":["../../src/curve/shape.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,uCAAuC;AACvC,8BAAsB,KAAM,YAAW,SAAS;IAC9C,QAAQ,CAAC,EAAE,EAAG,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,EAAG,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,EAAG,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,EAAG,MAAM,CAAC;IAErB;;;;;;OAMG;gBACS,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAuB1D;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;CACtC"}
@@ -15,22 +15,26 @@ class Shape {
15
15
  * @param {number} x3 - x3
16
16
  */
17
17
  constructor(x0, x1, x2, x3) {
18
- Object.defineProperty(this, 'x0', {
19
- value: x0,
20
- writable: false,
21
- });
22
- Object.defineProperty(this, 'x1', {
23
- value: x1,
24
- writable: false,
25
- });
26
- Object.defineProperty(this, 'x2', {
27
- value: x2,
28
- writable: false,
29
- });
30
- Object.defineProperty(this, 'x3', {
31
- value: x3,
32
- writable: false,
33
- });
18
+ // Define the coordinates as truly immutable: not writable AND not
19
+ // configurable, so they can't be reassigned, deleted or redefined. With
20
+ // useDefineForClassFields the field declarations above otherwise leave them
21
+ // configurable:true, letting `delete shape.x0` or a redefine defeat the
22
+ // read-only intent. They stay enumerable so they remain visible as the
23
+ // documented public properties (e.g. in JSON.stringify).
24
+ const coords = [
25
+ ['x0', x0],
26
+ ['x1', x1],
27
+ ['x2', x2],
28
+ ['x3', x3],
29
+ ];
30
+ for (const [name, value] of coords) {
31
+ Object.defineProperty(this, name, {
32
+ value,
33
+ writable: false,
34
+ enumerable: true,
35
+ configurable: false,
36
+ });
37
+ }
34
38
  }
35
39
  }
36
40
  exports.Shape = Shape;
@@ -1 +1 @@
1
- {"version":3,"file":"shape.js","sourceRoot":"","sources":["../../src/curve/shape.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;AAEb,uCAAuC;AACvC,MAAsB,KAAK;IAChB,EAAE,CAAU;IACZ,EAAE,CAAU;IACZ,EAAE,CAAU;IACZ,EAAE,CAAU;IAErB;;;;;;OAMG;IACH,YAAY,EAAU,EAAE,EAAU,EAAE,EAAU,EAAE,EAAU;QACxD,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE;YAChC,KAAK,EAAE,EAAE;YACT,QAAQ,EAAE,KAAK;SAChB,CAAC,CAAC;QACH,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE;YAChC,KAAK,EAAE,EAAE;YACT,QAAQ,EAAE,KAAK;SAChB,CAAC,CAAC;QACH,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE;YAChC,KAAK,EAAE,EAAE;YACT,QAAQ,EAAE,KAAK;SAChB,CAAC,CAAC;QACH,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE;YAChC,KAAK,EAAE,EAAE;YACT,QAAQ,EAAE,KAAK;SAChB,CAAC,CAAC;IACL,CAAC;CAQF;AAtCD,sBAsCC"}
1
+ {"version":3,"file":"shape.js","sourceRoot":"","sources":["../../src/curve/shape.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;AAEb,uCAAuC;AACvC,MAAsB,KAAK;IAChB,EAAE,CAAU;IACZ,EAAE,CAAU;IACZ,EAAE,CAAU;IACZ,EAAE,CAAU;IAErB;;;;;;OAMG;IACH,YAAY,EAAU,EAAE,EAAU,EAAE,EAAU,EAAE,EAAU;QACxD,kEAAkE;QAClE,wEAAwE;QACxE,4EAA4E;QAC5E,wEAAwE;QACxE,uEAAuE;QACvE,yDAAyD;QACzD,MAAM,MAAM,GAA4B;YACtC,CAAC,IAAI,EAAE,EAAE,CAAC;YACV,CAAC,IAAI,EAAE,EAAE,CAAC;YACV,CAAC,IAAI,EAAE,EAAE,CAAC;YACV,CAAC,IAAI,EAAE,EAAE,CAAC;SACX,CAAC;QACF,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,EAAE,CAAC;YACnC,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE;gBAChC,KAAK;gBACL,QAAQ,EAAE,KAAK;gBACf,UAAU,EAAE,IAAI;gBAChB,YAAY,EAAE,KAAK;aACpB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;CAQF;AA1CD,sBA0CC"}
@@ -11,10 +11,14 @@ export declare class Sigmoid implements Fuzzifier {
11
11
  private readonly slope;
12
12
  /**
13
13
  * Create a Sigmoid Function.
14
- * @param {number} center - The center point of the sigmoid curve (where it outputs 0.5)
14
+ * @param {number} center - The center point of the sigmoid curve (where it outputs 0.5).
15
+ * Must be finite.
15
16
  * @param {number} slope - Width of the transition: it appears in the denominator
16
- * as 1 / (1 + exp(-(x - center) / slope)), so a smaller slope means a steeper
17
- * transition and a larger slope a gentler one.
17
+ * as 1 / (1 + exp(-(x - center) / slope)), so a smaller magnitude means a steeper
18
+ * transition and a larger magnitude a gentler one. A **negative** slope inverts the
19
+ * curve into a decreasing S (high membership below the center, low above). A slope of
20
+ * `0` degenerates to an increasing step at the center (0.5 exactly at the center).
21
+ * Must be finite; non-finite center/slope throw.
18
22
  */
19
23
  constructor(center?: number, slope?: number);
20
24
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"sigmoid.d.ts","sourceRoot":"","sources":["../../src/curve/sigmoid.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC;;;;;;GAMG;AACH,qBAAa,OAAQ,YAAW,SAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAE/B;;;;;;OAMG;gBACS,MAAM,GAAE,MAAU,EAAE,KAAK,GAAE,MAAU;IAIjD;;;;OAIG;IACH,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM;CAS3B"}
1
+ {"version":3,"file":"sigmoid.d.ts","sourceRoot":"","sources":["../../src/curve/sigmoid.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC;;;;;;GAMG;AACH,qBAAa,OAAQ,YAAW,SAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAE/B;;;;;;;;;;OAUG;gBACS,MAAM,GAAE,MAAU,EAAE,KAAK,GAAE,MAAU;IAajD;;;;OAIG;IACH,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM;CAW3B"}
@@ -13,12 +13,25 @@ class Sigmoid {
13
13
  slope;
14
14
  /**
15
15
  * Create a Sigmoid Function.
16
- * @param {number} center - The center point of the sigmoid curve (where it outputs 0.5)
16
+ * @param {number} center - The center point of the sigmoid curve (where it outputs 0.5).
17
+ * Must be finite.
17
18
  * @param {number} slope - Width of the transition: it appears in the denominator
18
- * as 1 / (1 + exp(-(x - center) / slope)), so a smaller slope means a steeper
19
- * transition and a larger slope a gentler one.
19
+ * as 1 / (1 + exp(-(x - center) / slope)), so a smaller magnitude means a steeper
20
+ * transition and a larger magnitude a gentler one. A **negative** slope inverts the
21
+ * curve into a decreasing S (high membership below the center, low above). A slope of
22
+ * `0` degenerates to an increasing step at the center (0.5 exactly at the center).
23
+ * Must be finite; non-finite center/slope throw.
20
24
  */
21
25
  constructor(center = 0, slope = 1) {
26
+ // Validate up front (like Constant/FuzzyFunction): a non-finite center or
27
+ // slope makes fuzzify return NaN, breaking the documented 0..1 contract and
28
+ // making defuzzify report no winner ('none') for an otherwise valid rule.
29
+ if (!Number.isFinite(center)) {
30
+ throw Error('Sigmoid center must be a finite number but is ' + center);
31
+ }
32
+ if (!Number.isFinite(slope)) {
33
+ throw Error('Sigmoid slope must be a finite number but is ' + slope);
34
+ }
22
35
  this.center = center;
23
36
  this.slope = slope;
24
37
  }
@@ -28,6 +41,9 @@ class Sigmoid {
28
41
  * @return {number} fuzzy output 0..1
29
42
  */
30
43
  fuzzify(x) {
44
+ // NaN has no meaningful membership; treat it as 0 instead of returning NaN.
45
+ if (Number.isNaN(x))
46
+ return 0;
31
47
  if (this.slope === 0) {
32
48
  // When slope is 0, sigmoid becomes a step function
33
49
  if (x < this.center)
@@ -1 +1 @@
1
- {"version":3,"file":"sigmoid.js","sourceRoot":"","sources":["../../src/curve/sigmoid.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;AAEb;;;;;;GAMG;AACH,MAAa,OAAO;IACD,MAAM,CAAS;IACf,KAAK,CAAS;IAE/B;;;;;;OAMG;IACH,YAAY,SAAiB,CAAC,EAAE,QAAgB,CAAC;QAC/C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IACD;;;;OAIG;IACH,OAAO,CAAC,CAAS;QACf,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;YACrB,mDAAmD;YACnD,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM;gBAAE,OAAO,CAAC,CAAC;YAC9B,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM;gBAAE,OAAO,CAAC,CAAC;YAC9B,OAAO,GAAG,CAAC,CAAC,kBAAkB;QAChC,CAAC;QACD,OAAO,GAAG,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IACjE,CAAC;CACF;AA7BD,0BA6BC"}
1
+ {"version":3,"file":"sigmoid.js","sourceRoot":"","sources":["../../src/curve/sigmoid.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;AAEb;;;;;;GAMG;AACH,MAAa,OAAO;IACD,MAAM,CAAS;IACf,KAAK,CAAS;IAE/B;;;;;;;;;;OAUG;IACH,YAAY,SAAiB,CAAC,EAAE,QAAgB,CAAC;QAC/C,0EAA0E;QAC1E,4EAA4E;QAC5E,0EAA0E;QAC1E,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7B,MAAM,KAAK,CAAC,gDAAgD,GAAG,MAAM,CAAC,CAAC;QACzE,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,KAAK,CAAC,+CAA+C,GAAG,KAAK,CAAC,CAAC;QACvE,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IACD;;;;OAIG;IACH,OAAO,CAAC,CAAS;QACf,4EAA4E;QAC5E,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;QAC9B,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;YACrB,mDAAmD;YACnD,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM;gBAAE,OAAO,CAAC,CAAC;YAC9B,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM;gBAAE,OAAO,CAAC,CAAC;YAC9B,OAAO,GAAG,CAAC,CAAC,kBAAkB;QAChC,CAAC;QACD,OAAO,GAAG,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IACjE,CAAC;CACF;AA5CD,0BA4CC"}
@@ -5,6 +5,14 @@ import { Shape } from './shape';
5
5
  * new Trapezoid(0, 10, 15, 20)
6
6
  */
7
7
  export declare class Trapezoid extends Shape {
8
+ /**
9
+ * Create a Trapezoid.
10
+ * @param {number} x0 - left foot (membership 0)
11
+ * @param {number} x1 - start of the plateau (membership 1)
12
+ * @param {number} x2 - end of the plateau (membership 1)
13
+ * @param {number} x3 - right foot (membership 0)
14
+ */
15
+ constructor(x0: number, x1: number, x2: number, x3: number);
8
16
  /**
9
17
  * Fuzzify
10
18
  * @param {number} val - Point on X axis
@@ -1 +1 @@
1
- {"version":3,"file":"trapezoid.d.ts","sourceRoot":"","sources":["../../src/curve/trapezoid.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC;;;;GAIG;AACH,qBAAa,SAAU,SAAQ,KAAK;IAClC;;;;OAIG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;CAwC7B"}
1
+ {"version":3,"file":"trapezoid.d.ts","sourceRoot":"","sources":["../../src/curve/trapezoid.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC;;;;GAIG;AACH,qBAAa,SAAU,SAAQ,KAAK;IAClC;;;;;;OAMG;gBACS,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAmB1D;;;;OAIG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;CAwC7B"}
@@ -8,6 +8,28 @@ const shape_1 = require("./shape");
8
8
  * new Trapezoid(0, 10, 15, 20)
9
9
  */
10
10
  class Trapezoid extends shape_1.Shape {
11
+ /**
12
+ * Create a Trapezoid.
13
+ * @param {number} x0 - left foot (membership 0)
14
+ * @param {number} x1 - start of the plateau (membership 1)
15
+ * @param {number} x2 - end of the plateau (membership 1)
16
+ * @param {number} x3 - right foot (membership 0)
17
+ */
18
+ constructor(x0, x1, x2, x3) {
19
+ super(x0, x1, x2, x3);
20
+ // Reject out-of-order finite params. In particular an inverted plateau
21
+ // (x1 > x2) makes the plateau branch unsatisfiable, so the curve never
22
+ // reaches membership 1 and develops a discontinuity. NaN/Infinity, and the
23
+ // 3-argument form (x3 === undefined), are left untouched.
24
+ if (Number.isFinite(x0) &&
25
+ Number.isFinite(x1) &&
26
+ Number.isFinite(x2) &&
27
+ Number.isFinite(x3) &&
28
+ !(x0 <= x1 && x1 <= x2 && x2 <= x3)) {
29
+ throw Error('Trapezoid requires x0 <= x1 <= x2 <= x3 but got x0=' +
30
+ x0 + ', x1=' + x1 + ', x2=' + x2 + ', x3=' + x3);
31
+ }
32
+ }
11
33
  /**
12
34
  * Fuzzify
13
35
  * @param {number} val - Point on X axis
@@ -16,6 +38,10 @@ class Trapezoid extends shape_1.Shape {
16
38
  fuzzify(val) {
17
39
  let result = 0;
18
40
  const x = val;
41
+ // NaN has no meaningful membership; treat it as outside the support (0)
42
+ // instead of letting it propagate through the edge arithmetic.
43
+ if (Number.isNaN(x))
44
+ return 0;
19
45
  // Special case: all points equal (spike at single point)
20
46
  if (this.x0 === this.x1 && this.x1 === this.x2 && this.x2 === this.x3) {
21
47
  return x === this.x0 ? 1 : 0;
@@ -30,32 +56,26 @@ class Trapezoid extends shape_1.Shape {
30
56
  return 0;
31
57
  return 0;
32
58
  }
33
- if (x <= this.x0) {
59
+ if (x >= this.x1 && x <= this.x2) {
60
+ // Plateau, corners included. When a single edge is vertical (x0===x1 or
61
+ // x2===x3) the corner must read 1 — consistent with the rectangle case
62
+ // above and with Triangle. Evaluating the plateau before the x<=x0 / x>=x3
63
+ // zero guards is what makes those corners correct instead of dropping to 0.
64
+ result = 1;
65
+ }
66
+ else if (x <= this.x0) {
34
67
  result = 0;
35
68
  }
36
69
  else if (x >= this.x3) {
37
70
  result = 0;
38
71
  }
39
- else if (x >= this.x1 && x <= this.x2) {
40
- result = 1;
41
- }
42
72
  else if (x > this.x0 && x < this.x1) {
43
- // Handle case where x0 = x1 (vertical left edge)
44
- if (this.x1 === this.x0) {
45
- result = 1;
46
- }
47
- else {
48
- result = x / (this.x1 - this.x0) - this.x0 / (this.x1 - this.x0);
49
- }
73
+ // Rising edge only reached when x0 < x1, so the divisor is never 0.
74
+ result = x / (this.x1 - this.x0) - this.x0 / (this.x1 - this.x0);
50
75
  }
51
76
  else {
52
- // Handle case where x2 = x3 (vertical right edge)
53
- if (this.x3 === this.x2) {
54
- result = 1;
55
- }
56
- else {
57
- result = -x / (this.x3 - this.x2) + this.x3 / (this.x3 - this.x2);
58
- }
77
+ // Falling edge only reached when x2 < x3, so the divisor is never 0.
78
+ result = -x / (this.x3 - this.x2) + this.x3 / (this.x3 - this.x2);
59
79
  }
60
80
  return result;
61
81
  }
@@ -1 +1 @@
1
- {"version":3,"file":"trapezoid.js","sourceRoot":"","sources":["../../src/curve/trapezoid.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;AACb,mCAAgC;AAChC;;;;GAIG;AACH,MAAa,SAAU,SAAQ,aAAK;IAClC;;;;OAIG;IACH,OAAO,CAAC,GAAW;QACjB,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,MAAM,CAAC,GAAG,GAAG,CAAC;QAEd,yDAAyD;QACzD,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC;YACtE,OAAO,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/B,CAAC;QAED,4CAA4C;QAC5C,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC;YAC/C,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE;gBAAE,OAAO,CAAC,CAAC;YAC1B,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE;gBAAE,OAAO,CAAC,CAAC;YAC3C,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE;gBAAE,OAAO,CAAC,CAAC;YAC1B,OAAO,CAAC,CAAC;QACX,CAAC;QAED,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,GAAG,CAAC,CAAC;QACb,CAAC;aAAM,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACxB,MAAM,GAAG,CAAC,CAAC;QACb,CAAC;aAAM,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACxC,MAAM,GAAG,CAAC,CAAC;QACb,CAAC;aAAM,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;YACtC,iDAAiD;YACjD,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC;gBACxB,MAAM,GAAG,CAAC,CAAC;YACb,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;YACnE,CAAC;QACH,CAAC;aAAM,CAAC;YACN,kDAAkD;YAClD,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC;gBACxB,MAAM,GAAG,CAAC,CAAC;YACb,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;YACpE,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AA9CD,8BA8CC"}
1
+ {"version":3,"file":"trapezoid.js","sourceRoot":"","sources":["../../src/curve/trapezoid.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"triangle.d.ts","sourceRoot":"","sources":["../../src/curve/triangle.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC;;;;GAIG;AACH,qBAAa,QAAS,SAAQ,KAAK;IACjC;;;;;OAKG;gBACS,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAG9C;;;;OAIG;IACH,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM;CAwC3B"}
1
+ {"version":3,"file":"triangle.d.ts","sourceRoot":"","sources":["../../src/curve/triangle.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC;;;;GAIG;AACH,qBAAa,QAAS,SAAQ,KAAK;IACjC;;;;;OAKG;gBACS,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAiB9C;;;;OAIG;IACH,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM;CAwC3B"}
@@ -16,6 +16,16 @@ class Triangle extends shape_1.Shape {
16
16
  */
17
17
  constructor(x0, x1, x2) {
18
18
  super(x0, x1, x2, x2);
19
+ // Reject out-of-order finite params. With x0 > x1 or x1 > x2 the branch
20
+ // guards make whole edges unreachable, so the peak (x1) never reaches 1 and
21
+ // the curve is discontinuous or collapses to the empty set. NaN/Infinity are
22
+ // left untouched (handled at fuzzify time, relied on for open-ended shapes).
23
+ if (Number.isFinite(x0) &&
24
+ Number.isFinite(x1) &&
25
+ Number.isFinite(x2) &&
26
+ !(x0 <= x1 && x1 <= x2)) {
27
+ throw Error('Triangle requires x0 <= x1 <= x2 but got x0=' + x0 + ', x1=' + x1 + ', x2=' + x2);
28
+ }
19
29
  }
20
30
  /**
21
31
  * Fuzzify
@@ -1 +1 @@
1
- {"version":3,"file":"triangle.js","sourceRoot":"","sources":["../../src/curve/triangle.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;AACb,mCAAgC;AAChC;;;;GAIG;AACH,MAAa,QAAS,SAAQ,aAAK;IACjC;;;;;OAKG;IACH,YAAY,EAAU,EAAE,EAAU,EAAE,EAAU;QAC5C,KAAK,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IACxB,CAAC;IACD;;;;OAIG;IACH,OAAO,CAAC,CAAS;QACf,IAAI,MAAM,GAAG,CAAC,CAAC;QAEf,yDAAyD;QACzD,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC;YAC/C,OAAO,CAAC,KAAK,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/B,CAAC;QAED,6CAA6C;QAC7C,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC;YACxB,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE;gBAAE,OAAO,CAAC,CAAC;YAC1B,IAAI,CAAC,KAAK,IAAI,CAAC,EAAE;gBAAE,OAAO,CAAC,CAAC;YAC5B,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE;gBAAE,OAAO,CAAC,CAAC;YAC3B,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;gBAChB,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC;QAED,8CAA8C;QAC9C,IAAI,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC;YACxB,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE;gBAAE,OAAO,CAAC,CAAC;YAC3B,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;gBAC/B,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;YAC7C,CAAC;YACD,IAAI,CAAC,KAAK,IAAI,CAAC,EAAE;gBAAE,OAAO,CAAC,CAAC;YAC5B,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE;gBAAE,OAAO,CAAC,CAAC;QAC5B,CAAC;QAED,kBAAkB;QAClB,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,GAAG,CAAC,CAAC;QACb,CAAC;aAAM,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACxB,MAAM,GAAG,CAAC,CAAC;QACb,CAAC;aAAM,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACvC,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/C,CAAC;aAAM,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;YACtC,MAAM,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/C,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AAvDD,4BAuDC"}
1
+ {"version":3,"file":"triangle.js","sourceRoot":"","sources":["../../src/curve/triangle.ts"],"names":[],"mappings":"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"}
package/lib/logic.d.ts CHANGED
@@ -30,8 +30,10 @@ export declare class Logic {
30
30
  private checkInitCalled;
31
31
  private checkOutputName;
32
32
  /**
33
- * Registers the first rule. Must be called before {@link and}, {@link or},
34
- * {@link not} or {@link defuzzify}.
33
+ * Registers a rule and marks the logic chain as started; one `init` call must
34
+ * precede {@link and}, {@link or}, {@link not} or {@link defuzzify}. It may be
35
+ * called more than once — a later `init` just adds another rule that starts a
36
+ * fresh membership, which is the same effect as {@link or}.
35
37
  *
36
38
  * Rule composition is sequential and order-dependent: at {@link defuzzify}
37
39
  * time each rule's membership is folded into a single value that is carried
@@ -1 +1 @@
1
- {"version":3,"file":"logic.d.ts","sourceRoot":"","sources":["../src/logic.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AA8B1C,qCAAqC;AACrC,qBAAa,KAAK;IAChB,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,KAAK,CAAc;IAE3B;;;;OAIG;IACI,CAAC,EAAE;QACR,KAAK,EAAE,OAAO,KAAK,CAAC;QACpB,KAAK,EAAE,OAAO,KAAK,CAAC;QACpB,YAAY,EAAE,OAAO,YAAY,CAAC;QAClC,SAAS,EAAE,OAAO,SAAS,CAAC;QAC5B,QAAQ,EAAE,OAAO,QAAQ,CAAC;QAC1B,QAAQ,EAAE,OAAO,QAAQ,CAAC;QAC1B,aAAa,EAAE,OAAO,aAAa,CAAC;QACpC,OAAO,EAAE,OAAO,OAAO,CAAC;KACzB,CAAC;;IAeF,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,eAAe;IAYvB;;;;;;;;;;;OAWG;IACH,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI;IAQ5C;;;;;;;;OAQG;IACH,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI;IAQ3C;;;;;;;OAOG;IACH,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI;IAQ1C;;;;;;OAMG;IACH,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI;IAQ3C;;;;;;;;;;;;;;OAcG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,eAAe;CA+C7D;AAED,yBAAiB,KAAK,CAAC;IACrB,KAAY,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,CAAC;IAErD,UAAiB,IAAI;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,SAAS,CAAC;QACjB,IAAI,EAAE,QAAQ,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB;IAED,UAAiB,eAAe;QAC9B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACtC,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,IAAI,EAAE,CAAC;QACd,OAAO,IAAI,MAAM,CAAC;QAClB,QAAQ,IAAI,MAAM,CAAC;KACpB;CACF"}
1
+ {"version":3,"file":"logic.d.ts","sourceRoot":"","sources":["../src/logic.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AA8B1C,qCAAqC;AACrC,qBAAa,KAAK;IAChB,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,KAAK,CAAc;IAE3B;;;;OAIG;IACI,CAAC,EAAE;QACR,KAAK,EAAE,OAAO,KAAK,CAAC;QACpB,KAAK,EAAE,OAAO,KAAK,CAAC;QACpB,YAAY,EAAE,OAAO,YAAY,CAAC;QAClC,SAAS,EAAE,OAAO,SAAS,CAAC;QAC5B,QAAQ,EAAE,OAAO,QAAQ,CAAC;QAC1B,QAAQ,EAAE,OAAO,QAAQ,CAAC;QAC1B,aAAa,EAAE,OAAO,aAAa,CAAC;QACpC,OAAO,EAAE,OAAO,OAAO,CAAC;KACzB,CAAC;;IAeF,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,eAAe;IAevB;;;;;;;;;;;;;OAaG;IACH,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI;IAQ5C;;;;;;;;OAQG;IACH,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI;IAQ3C;;;;;;;OAOG;IACH,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI;IAQ1C;;;;;;OAMG;IACH,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,IAAI;IAQ3C;;;;;;;;;;;;;;OAcG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,eAAe;CAkE7D;AAED,yBAAiB,KAAK,CAAC;IACrB,KAAY,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,CAAC;IAErD,UAAiB,IAAI;QACnB,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,SAAS,CAAC;QACjB,IAAI,EAAE,QAAQ,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB;IAED,UAAiB,eAAe;QAC9B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACtC,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,IAAI,EAAE,CAAC;QACd,OAAO,IAAI,MAAM,CAAC;QAClB,QAAQ,IAAI,MAAM,CAAC;KACpB;CACF"}
package/lib/logic.js CHANGED
@@ -60,17 +60,22 @@ class Logic {
60
60
  }
61
61
  }
62
62
  checkOutputName(name) {
63
+ // ASCII letters only — the keys end up as boon-js identifiers, which are
64
+ // not Unicode-aware, so non-ASCII letters (e.g. "ÜberHeiss") are rejected
65
+ // by design rather than silently producing an unusable boon-js input.
63
66
  const reg = /^[a-z]+$/i;
64
67
  if (!reg.test(name)) {
65
- throw Error('Output names can only be strings without space, without numbers and without special chars');
68
+ throw Error('Output names can only be strings without space, without numbers and without special chars (ASCII letters a-z only)');
66
69
  }
67
70
  if (this.rules.some((rule) => rule.output === name)) {
68
71
  throw Error('Output name "' + name + '" is already in use');
69
72
  }
70
73
  }
71
74
  /**
72
- * Registers the first rule. Must be called before {@link and}, {@link or},
73
- * {@link not} or {@link defuzzify}.
75
+ * Registers a rule and marks the logic chain as started; one `init` call must
76
+ * precede {@link and}, {@link or}, {@link not} or {@link defuzzify}. It may be
77
+ * called more than once — a later `init` just adds another rule that starts a
78
+ * fresh membership, which is the same effect as {@link or}.
74
79
  *
75
80
  * Rule composition is sequential and order-dependent: at {@link defuzzify}
76
81
  * time each rule's membership is folded into a single value that is carried
@@ -151,13 +156,22 @@ class Logic {
151
156
  this.checkInitCalled();
152
157
  let defuzzified = 'none';
153
158
  let fuzzified = 0;
154
- let best = -Infinity;
159
+ // Seed at 0, not -Infinity: a rule only wins with membership strictly above
160
+ // 0. When no rule fires (every membership is 0) there is genuinely no winner,
161
+ // so 'none' is returned instead of the first rule being reported with a
162
+ // membership of 0 (which also kept its boonJsInputs entry wrongly true).
163
+ let best = 0;
155
164
  // membership carried along the chain, used by AND to narrow the result
156
165
  let running = 0;
166
+ // Defend against fuzzifiers that violate the 0..1 contract: clamp the raw
167
+ // value (and map NaN to 0) before composing. Otherwise a rogue shape — or
168
+ // `not` computing 1 - raw on it — could make the winner's fuzzified value
169
+ // fall outside 0..1.
170
+ const clamp = (v) => Number.isNaN(v) ? 0 : Math.min(1, Math.max(0, v));
157
171
  // Evaluate into fresh rule copies so the engine's internal state is never
158
172
  // mutated or handed out to the caller.
159
173
  const rules = this.rules.map((rule) => {
160
- const raw = rule.shape.fuzzify(value);
174
+ const raw = clamp(rule.shape.fuzzify(value));
161
175
  const membership = ruleEngine[rule.type](running, raw);
162
176
  running = membership;
163
177
  // max-membership defuzzification: highest membership wins, ties keep
@@ -170,7 +184,13 @@ class Logic {
170
184
  return { ...rule, fuzzy: membership };
171
185
  });
172
186
  let namePrefix = '';
173
- if (as && typeof as === 'string') {
187
+ if (as) {
188
+ // Validate the namespace prefix with the same rule as output names, so it
189
+ // can't inject spaces, dots or other characters into the boonJsInputs keys
190
+ // (which are meant to be valid boon-js identifiers).
191
+ if (typeof as !== 'string' || !/^[a-z]+$/i.test(as)) {
192
+ throw Error('The "as" namespace prefix can only be letters without space, without numbers and without special chars');
193
+ }
174
194
  namePrefix = as + '.';
175
195
  }
176
196
  const boonJsInputs = {};
package/lib/logic.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"logic.js","sourceRoot":"","sources":["../src/logic.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"logic.js","sourceRoot":"","sources":["../src/logic.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;AACb,yCAAsC;AAEtC,yCAAsC;AACtC,yDAAqD;AACrD,+CAA4C;AAC5C,iDAA8C;AAC9C,+CAA4C;AAC5C,2DAAuD;AACvD,6CAA0C;AAE1C,MAAM,SAAS,GAAG,MAAM,CAAC;AACzB,MAAM,QAAQ,GAAG,KAAK,CAAC;AACvB,MAAM,OAAO,GAAG,IAAI,CAAC;AACrB,MAAM,QAAQ,GAAG,KAAK,CAAC;AAKvB;;;;GAIG;AACH,MAAM,UAAU,GAAkE;IAChF,IAAI,CAAC,KAAa,EAAE,GAAW;QAC7B,OAAO,GAAG,CAAC;IACb,CAAC;IACD,EAAE,CAAC,KAAa,EAAE,GAAW;QAC3B,OAAO,GAAG,CAAC;IACb,CAAC;IACD,GAAG,CAAC,IAAY,EAAE,GAAW;QAC3B,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC7B,CAAC;IACD,GAAG,CAAC,KAAa,EAAE,GAAW;QAC5B,OAAO,CAAC,GAAG,GAAG,CAAC;IACjB,CAAC;CACF,CAAC;AAEF,qCAAqC;AACrC,MAAa,KAAK;IACR,UAAU,GAAY,KAAK,CAAC;IAC5B,KAAK,GAAW,EAAE,CAAC;IAE3B;;;;OAIG;IACI,CAAC,CASN;IAEF;QACE,IAAI,CAAC,CAAC,GAAG;YACP,KAAK,EAAL,aAAK;YACL,KAAK,EAAL,aAAK;YACL,YAAY,EAAZ,4BAAY;YACZ,SAAS,EAAT,qBAAS;YACT,QAAQ,EAAR,mBAAQ;YACR,QAAQ,EAAR,mBAAQ;YACR,aAAa,EAAb,8BAAa;YACb,OAAO,EAAP,iBAAO;SACR,CAAC;IACJ,CAAC;IAEO,eAAe;QACrB,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,MAAM,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;IAEO,eAAe,CAAC,IAAY;QAClC,yEAAyE;QACzE,0EAA0E;QAC1E,sEAAsE;QACtE,MAAM,GAAG,GAAG,WAAW,CAAC;QACxB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACpB,MAAM,KAAK,CACT,oHAAoH,CACrH,CAAC;QACJ,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,EAAE,CAAC;YACpD,MAAM,KAAK,CAAC,eAAe,GAAG,IAAI,GAAG,qBAAqB,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,IAAI,CAAC,MAAc,EAAE,KAAgB;QACnC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QAC7B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,MAAM,IAAI,GAAG,SAAS,CAAC;QACvB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;OAQG;IACH,GAAG,CAAC,MAAc,EAAE,KAAgB;QAClC,IAAI,CAAC,eAAe,EAAE,CAAC;QACvB,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QAC7B,MAAM,IAAI,GAAG,QAAQ,CAAC;QACtB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;OAOG;IACH,EAAE,CAAC,MAAc,EAAE,KAAgB;QACjC,IAAI,CAAC,eAAe,EAAE,CAAC;QACvB,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QAC7B,MAAM,IAAI,GAAG,OAAO,CAAC;QACrB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;OAMG;IACH,GAAG,CAAC,MAAc,EAAE,KAAgB;QAClC,IAAI,CAAC,eAAe,EAAE,CAAC;QACvB,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QAC7B,MAAM,IAAI,GAAG,QAAQ,CAAC;QACtB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACH,SAAS,CAAC,KAAa,EAAE,EAAW;QAClC,IAAI,CAAC,eAAe,EAAE,CAAC;QACvB,IAAI,WAAW,GAAG,MAAM,CAAC;QACzB,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,4EAA4E;QAC5E,8EAA8E;QAC9E,wEAAwE;QACxE,yEAAyE;QACzE,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,uEAAuE;QACvE,IAAI,OAAO,GAAG,CAAC,CAAC;QAEhB,0EAA0E;QAC1E,0EAA0E;QAC1E,0EAA0E;QAC1E,qBAAqB;QACrB,MAAM,KAAK,GAAG,CAAC,CAAS,EAAU,EAAE,CAClC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAEpD,0EAA0E;QAC1E,uCAAuC;QACvC,MAAM,KAAK,GAAW,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YAC5C,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;YAC7C,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;YACvD,OAAO,GAAG,UAAU,CAAC;YACrB,qEAAqE;YACrE,0CAA0C;YAC1C,IAAI,UAAU,GAAG,IAAI,EAAE,CAAC;gBACtB,IAAI,GAAG,UAAU,CAAC;gBAClB,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC;gBAC1B,SAAS,GAAG,UAAU,CAAC;YACzB,CAAC;YACD,OAAO,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,IAAI,UAAU,GAAG,EAAE,CAAC;QACpB,IAAI,EAAE,EAAE,CAAC;YACP,0EAA0E;YAC1E,2EAA2E;YAC3E,qDAAqD;YACrD,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;gBACpD,MAAM,KAAK,CACT,wGAAwG,CACzG,CAAC;YACJ,CAAC;YACD,UAAU,GAAG,EAAE,GAAG,GAAG,CAAC;QACxB,CAAC;QAED,MAAM,YAAY,GAA4B,EAAE,CAAC;QACjD,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YACrB,YAAY,CAAC,GAAG,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,KAAK,WAAW,CAAC;QAC5E,CAAC,CAAC,CAAC;QAEH,OAAO;YACL,YAAY;YACZ,SAAS,EAAE,SAAS;YACpB,WAAW,EAAE,WAAW;YACxB,KAAK;YACL,OAAO;gBACL,OAAO,SAAS,CAAC;YACnB,CAAC;YACD,QAAQ;gBACN,OAAO,WAAW,CAAC;YACrB,CAAC;SACF,CAAC;IACJ,CAAC;CACF;AA7MD,sBA6MC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "es6-fuzz",
3
3
  "description": "fuzzy logic with and for typescript and javascript",
4
- "version": "7.0.1",
4
+ "version": "7.1.0",
5
5
  "type": "commonjs",
6
6
  "main": "lib/index.js",
7
7
  "types": "lib/index.d.ts",