Date: Mon, 21 Oct 2024 17:58:19 +0200
Subject: [PATCH 20/31] fix: Rename Ten-Year to Multi-Year
---
src/pages/policy/input/ParameterEditor.jsx | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/src/pages/policy/input/ParameterEditor.jsx b/src/pages/policy/input/ParameterEditor.jsx
index 60c722b5c..f99438138 100644
--- a/src/pages/policy/input/ParameterEditor.jsx
+++ b/src/pages/policy/input/ParameterEditor.jsx
@@ -45,7 +45,7 @@ const DATE_INPUT_MODES = {
DEFAULT: "default",
YEARLY: "yearly",
DATE: "date",
- TEN_YEAR: "ten-year"
+ MULTI_YEAR: "multi-year"
};
export default function ParameterEditor(props) {
@@ -109,7 +109,7 @@ export default function ParameterEditor(props) {
description = "";
}
- const gridColumns = dateInputMode === DATE_INPUT_MODES.TEN_YEAR ? "auto min-content" : "auto min-content min-content";
+ const gridColumns = dateInputMode === DATE_INPUT_MODES.MULTI_YEAR ? "auto min-content" : "auto min-content min-content";
return (
{
- dateInputMode !== DATE_INPUT_MODES.TEN_YEAR && (
+ dateInputMode !== DATE_INPUT_MODES.MULTI_YEAR && (
;
case DATE_INPUT_MODES.DATE:
return
;
- case DATE_INPUT_MODES.TEN_YEAR:
- return
;
+ case DATE_INPUT_MODES.MULTI_YEAR:
+ return
;
default:
return
;
}
@@ -395,7 +395,7 @@ function DatePeriodSetter(props) {
);
}
-function TenYearPeriodSetter(props) {
+function MultiYearPeriodSetter(props) {
const { startDate, endDate, setStartDate, setEndDate, possibleYears, FOREVER_DATE, parameterName, baseMap, reformMap, metadata, policy } = props;
const NUMBER_OF_YEARS = 10;
@@ -416,7 +416,7 @@ function TenYearPeriodSetter(props) {
return valueMap;
}
- // This is necessary because technically, TenYearPeriodSetter does not
+ // This is necessary because technically, MultiYearPeriodSetter does not
// unmount when we change between parameters, leading to the possibility
// for a stale "value" state in this controlled component
useEffect(() => {
@@ -855,8 +855,8 @@ function SettingsPanel(props) {
value: DATE_INPUT_MODES.DATE
},
{
- label: "10-Year",
- value: DATE_INPUT_MODES.TEN_YEAR
+ label: "Multi-Year",
+ value: DATE_INPUT_MODES.MULTI_YEAR
}
]
From bbadc8de9cb89f1375f3d6801bd67dec8e007520 Mon Sep 17 00:00:00 2001
From: Anthony Volk
Date: Mon, 21 Oct 2024 18:00:51 +0200
Subject: [PATCH 21/31] fix: Change case of labels
---
src/pages/policy/input/ParameterEditor.jsx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/pages/policy/input/ParameterEditor.jsx b/src/pages/policy/input/ParameterEditor.jsx
index f99438138..b8eb20123 100644
--- a/src/pages/policy/input/ParameterEditor.jsx
+++ b/src/pages/policy/input/ParameterEditor.jsx
@@ -855,7 +855,7 @@ function SettingsPanel(props) {
value: DATE_INPUT_MODES.DATE
},
{
- label: "Multi-Year",
+ label: "Multi-year",
value: DATE_INPUT_MODES.MULTI_YEAR
}
]
@@ -877,7 +877,7 @@ function SettingsPanel(props) {
paddingBottom: 0,
color: style.colors.DARK_GRAY
}}
- >Input Mode
+ >Input mode
Date: Mon, 21 Oct 2024 18:13:19 +0200
Subject: [PATCH 22/31] fix: Improve spacing
---
src/pages/policy/input/ParameterEditor.jsx | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/src/pages/policy/input/ParameterEditor.jsx b/src/pages/policy/input/ParameterEditor.jsx
index b8eb20123..c8958c776 100644
--- a/src/pages/policy/input/ParameterEditor.jsx
+++ b/src/pages/policy/input/ParameterEditor.jsx
@@ -109,7 +109,7 @@ export default function ParameterEditor(props) {
description = "";
}
- const gridColumns = dateInputMode === DATE_INPUT_MODES.MULTI_YEAR ? "auto min-content" : "auto min-content min-content";
+ const gridColumns = dateInputMode === DATE_INPUT_MODES.MULTI_YEAR ? "auto min-content" : "auto auto min-content";
return (
@@ -505,14 +503,13 @@ function MultiYearPeriodSetter(props) {
style={{
display: "flex",
flexDirection: "column",
- paddingLeft: "12px",
gap: "10px",
}}
>
Date: Mon, 21 Oct 2024 20:03:28 +0200
Subject: [PATCH 23/31] fix: Remove deprecated key in TypeScript setup
---
src/__tests__/algorithms/Bisection.test.js | 135 +---
src/__tests__/algorithms/IntervalMap.test.js | 708 +++++++++----------
src/algorithms/Bisection.js | 44 +-
src/algorithms/IntervalMap.js | 281 ++++----
tsconfig.json | 1 -
5 files changed, 509 insertions(+), 660 deletions(-)
diff --git a/src/__tests__/algorithms/Bisection.test.js b/src/__tests__/algorithms/Bisection.test.js
index c02ae90c9..ea9434f42 100644
--- a/src/__tests__/algorithms/Bisection.test.js
+++ b/src/__tests__/algorithms/Bisection.test.js
@@ -1,110 +1,31 @@
import { bisect } from "algorithms/Bisection";
describe("bisection", function () {
- test("small cases", function () {
- expect(
- bisect([], 1, function (a) {
- return a - 1;
- }),
- ).toBe(0);
- expect(
- bisect([1], 1, function (a) {
- return a - 1;
- }),
- ).toBe(0);
- expect(
- bisect([1], 2, function (a) {
- return a - 2;
- }),
- ).toBe(1);
- expect(
- bisect(
- [1],
- 1,
- function (a) {
- return a - 1;
- },
- 0,
- 1,
- true,
- ),
- ).toBe(1);
- });
- var a = [0, 1, 2, 3, 4, 5];
- test.each(a)("identity", function (e) {
- expect(
- bisect(a, e, function (o) {
- return o - e;
- }),
- ).toBe(e);
- });
- test.each(a)("successor 1", function (e) {
- expect(
- bisect(a, e + 0.5, function (o) {
- return o - e - 0.5;
- }),
- ).toBe(e + 1);
- });
- test.each(a)("successor 2", function (e) {
- expect(
- bisect(
- a,
- e,
- function (o) {
- return o - e;
- },
- 0,
- a.length,
- true,
- ),
- ).toBe(e + 1);
- });
- test.each(a)("successor 3", function (e) {
- expect(
- bisect(
- a,
- e + 0.5,
- function (o) {
- return o - e - 0.5;
- },
- 0,
- a.length,
- true,
- ),
- ).toBe(e + 1);
- });
- test("duplicates", function () {
- var a = [0, 1, 2, 3, 3, 3, 6, 7];
- expect(
- bisect(a, 3, function (e) {
- return e - 3;
- }),
- ).toBe(3);
- expect(
- bisect(
- a,
- 3,
- function (e) {
- return e - 3;
- },
- 0,
- a.length,
- true,
- ),
- ).toBe(6);
- });
- test("unknown", function () {
- var a = [-2, -1];
- expect(
- bisect(
- a,
- 1,
- function (e) {
- return e - 1;
- },
- 0,
- a.length,
- false,
- ),
- ).toBe(a.length);
- });
+ test("small cases", function () {
+ expect(bisect([], 1, function (a) { return a - 1; })).toBe(0);
+ expect(bisect([1], 1, function (a) { return a - 1; })).toBe(0);
+ expect(bisect([1], 2, function (a) { return a - 2; })).toBe(1);
+ expect(bisect([1], 1, function (a) { return a - 1; }, 0, 1, true)).toBe(1);
+ });
+ var a = [0, 1, 2, 3, 4, 5];
+ test.each(a)("identity", function (e) {
+ expect(bisect(a, e, function (o) { return o - e; })).toBe(e);
+ });
+ test.each(a)("successor 1", function (e) {
+ expect(bisect(a, e + 0.5, function (o) { return o - e - 0.5; })).toBe(e + 1);
+ });
+ test.each(a)("successor 2", function (e) {
+ expect(bisect(a, e, function (o) { return o - e; }, 0, a.length, true)).toBe(e + 1);
+ });
+ test.each(a)("successor 3", function (e) {
+ expect(bisect(a, e + 0.5, function (o) { return o - e - 0.5; }, 0, a.length, true)).toBe(e + 1);
+ });
+ test("duplicates", function () {
+ var a = [0, 1, 2, 3, 3, 3, 6, 7];
+ expect(bisect(a, 3, function (e) { return e - 3; })).toBe(3);
+ expect(bisect(a, 3, function (e) { return e - 3; }, 0, a.length, true)).toBe(6);
+ });
+ test("unknown", function () {
+ var a = [-2, -1];
+ expect(bisect(a, 1, function (e) { return e - 1; }, 0, a.length, false)).toBe(a.length);
+ });
});
diff --git a/src/__tests__/algorithms/IntervalMap.test.js b/src/__tests__/algorithms/IntervalMap.test.js
index cfd6a6473..e72de2775 100644
--- a/src/__tests__/algorithms/IntervalMap.test.js
+++ b/src/__tests__/algorithms/IntervalMap.test.js
@@ -1,392 +1,364 @@
import { IntervalMap } from "algorithms/IntervalMap";
-var keyCmp = function (x, y) {
- return x - y;
-};
-var valueEq = function (x, y) {
- return x === y;
-};
+var keyCmp = function (x, y) { return x - y; };
+var valueEq = function (x, y) { return x === y; };
function f(i) {
- return String.fromCharCode(97 + i);
+ return String.fromCharCode(97 + i);
}
function array(n) {
- var a = [];
- for (var i = 0; i < n; i++) {
- a.push([i, f(i)]);
- }
- return a;
+ var a = [];
+ for (var i = 0; i < n; i++) {
+ a.push([i, f(i)]);
+ }
+ return a;
}
function randArray(n, m) {
- var rand = function () {
- return Math.floor(Math.random() * m);
- };
- var a = [];
- for (var i = 0; i < n; i++) {
- a.push([i, f(rand())]);
- }
- return a;
+ var rand = function () { return Math.floor(Math.random() * m); };
+ var a = [];
+ for (var i = 0; i < n; i++) {
+ a.push([i, f(rand())]);
+ }
+ return a;
}
function keys(n) {
- var a = [];
- for (var i = 0; i < n; i++) {
- a.push(i);
- }
- return a;
+ var a = [];
+ for (var i = 0; i < n; i++) {
+ a.push(i);
+ }
+ return a;
}
function hasDuplicates(a) {
- var s = new Set(a);
- return s.size < a.length;
+ var s = new Set(a);
+ return s.size < a.length;
}
function hasConsecutiveDuplicates(a) {
- for (var i = 0; i + 1 < a.length; i++) {
- if (a[i] === a[i + 1]) return true;
- }
- return false;
+ for (var i = 0; i + 1 < a.length; i++) {
+ if (a[i] === a[i + 1])
+ return true;
+ }
+ return false;
}
function isSorted(a) {
- for (var i = 0; i + 1 < a.length; i++) {
- if (a[i] > a[i + 1]) return false;
- }
- return true;
+ for (var i = 0; i + 1 < a.length; i++) {
+ if (a[i] > a[i + 1])
+ return false;
+ }
+ return true;
}
describe("construct", function () {
- test("an empty map", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- expect(m.size()).toBe(0);
- expect(m.keys()).toStrictEqual([]);
- expect(m.values()).toStrictEqual([]);
- expect(m.toArray()).toStrictEqual([]);
- });
- test.concurrent.each([5, 25, 125])(
- "nonempty maps without repeated keys or values in initializer",
- function (size) {
- var a = array(size);
- var m = new IntervalMap(a, keyCmp, valueEq);
- expect(m.size()).toBe(size);
- expect(m.toArray()).toStrictEqual(a);
- },
- );
- test.concurrent.each([5, 25, 125])(
- "nonempty maps with repeated keys in initializer",
- function (size) {
- var a = array(size);
- a.concat(a);
- var m = new IntervalMap(a, keyCmp, valueEq);
- expect(hasDuplicates(m.keys())).toBe(false);
- expect(m.size()).toBe(size);
- },
- );
- test.concurrent.each([
- [5, 2],
- [5, 5],
- [25, 5],
- [25, 25],
- [125, 5],
- ])(
- "nonempty maps with repeated values in initializer",
- function (size, numValues) {
- var a = randArray(size, numValues);
- var m = new IntervalMap(a, keyCmp, valueEq);
- expect(hasConsecutiveDuplicates(m.values())).toBe(false);
- expect(m.size()).toBeLessThanOrEqual(size);
- },
- );
- test.concurrent.each([5, 25, 125])(
- "nonempty maps without unsorted initializer",
- function (size) {
- var a = array(size);
- a.reverse();
- var m = new IntervalMap(a, keyCmp, valueEq);
- expect(isSorted(m.keys())).toBe(true);
- expect(m.size()).toBe(size);
- },
- );
+ test("an empty map", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ expect(m.size()).toBe(0);
+ expect(m.keys()).toStrictEqual([]);
+ expect(m.values()).toStrictEqual([]);
+ expect(m.toArray()).toStrictEqual([]);
+ });
+ test.concurrent.each([5, 25, 125])("nonempty maps without repeated keys or values in initializer", function (size) {
+ var a = array(size);
+ var m = new IntervalMap(a, keyCmp, valueEq);
+ expect(m.size()).toBe(size);
+ expect(m.toArray()).toStrictEqual(a);
+ });
+ test.concurrent.each([5, 25, 125])("nonempty maps with repeated keys in initializer", function (size) {
+ var a = array(size);
+ a.concat(a);
+ var m = new IntervalMap(a, keyCmp, valueEq);
+ expect(hasDuplicates(m.keys())).toBe(false);
+ expect(m.size()).toBe(size);
+ });
+ test.concurrent.each([
+ [5, 2],
+ [5, 5],
+ [25, 5],
+ [25, 25],
+ [125, 5],
+ ])("nonempty maps with repeated values in initializer", function (size, numValues) {
+ var a = randArray(size, numValues);
+ var m = new IntervalMap(a, keyCmp, valueEq);
+ expect(hasConsecutiveDuplicates(m.values())).toBe(false);
+ expect(m.size()).toBeLessThanOrEqual(size);
+ });
+ test.concurrent.each([5, 25, 125])("nonempty maps without unsorted initializer", function (size) {
+ var a = array(size);
+ a.reverse();
+ var m = new IntervalMap(a, keyCmp, valueEq);
+ expect(isSorted(m.keys())).toBe(true);
+ expect(m.size()).toBe(size);
+ });
});
-describe("get values from", function () {
- var n = 10;
- var a = array(n);
- test("empty map", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- expect(m.get(0)).toBeUndefined();
- });
- test.each(keys(n))("nonempty map", function (key) {
- var m = new IntervalMap(a, keyCmp, valueEq);
- expect(m.get(key)).toBe(f(key));
- expect(m.get(key + 0.5)).toBe(f(key));
- });
+describe("get values from ", function () {
+ var n = 10;
+ var a = array(n);
+ test("empty map", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ expect(m.get(0)).toBeUndefined();
+ });
+ test.each(keys(n))("nonempty map", function (key) {
+ var m = new IntervalMap(a, keyCmp, valueEq);
+ expect(m.get(key)).toBe(f(key));
+ expect(m.get(key + 0.5)).toBe(f(key));
+ });
});
describe("set", function () {
- test("empty intervals", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- expect(m.set(0, 0, "a").toArray()).toStrictEqual([]);
- expect(m.set(0, -1, "a").toArray()).toStrictEqual([]);
- });
- test("one interval", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- expect(m.set(-1, 1, "a").toArray()).toStrictEqual([
- [-1, "a"],
- [1, undefined],
- ]);
- });
- test("disjoint intervals", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(-2, -1, "a").set(1, 2, "b");
- expect(m.toArray()).toStrictEqual([
- [-2, "a"],
- [-1, undefined],
- [1, "b"],
- [2, undefined],
- ]);
- });
- test("disjoint intervals in reverse order", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(1, 2, "b").set(-2, -1, "a");
- expect(m.toArray()).toStrictEqual([
- [-2, "a"],
- [-1, undefined],
- [1, "b"],
- [2, undefined],
- ]);
- });
- test("disjoint intervals in reverse order with an undefined value", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(1, 2, "b").set(-2, -1, undefined);
- expect(m.toArray()).toStrictEqual([
- [1, "b"],
- [2, undefined],
- ]);
- });
- test("adjacent intervals", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(-1, 0, "a").set(0, 1, "b");
- expect(m.toArray()).toStrictEqual([
- [-1, "a"],
- [0, "b"],
- [1, undefined],
- ]);
- });
- test("adjacent intervals in reverse order", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(0, 1, "b").set(-1, 0, "a");
- expect(m.toArray()).toStrictEqual([
- [-1, "a"],
- [0, "b"],
- [1, undefined],
- ]);
- });
- test("adjacent intervals with same value", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(-1, 0, "a").set(0, 1, "a");
- expect(m.toArray()).toStrictEqual([
- [-1, "a"],
- [1, undefined],
- ]);
- });
- test("adjacent intervals with same value in reverse order", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(0, 1, "a").set(-1, 0, "a");
- expect(m.toArray()).toStrictEqual([
- [-1, "a"],
- [1, undefined],
- ]);
- });
- test("intersecting intervals", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(-2, 1, "a").set(-1, 2, "b");
- expect(m.toArray()).toStrictEqual([
- [-2, "a"],
- [-1, "b"],
- [2, undefined],
- ]);
- });
- test("intersecting intervals in reverse order", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(-1, 2, "b").set(-2, 1, "a");
- expect(m.toArray()).toStrictEqual([
- [-2, "a"],
- [1, "b"],
- [2, undefined],
- ]);
- });
- test("intersecting intervals with same value", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(-2, 1, "a").set(-1, 2, "a");
- expect(m.toArray()).toStrictEqual([
- [-2, "a"],
- [2, undefined],
- ]);
- });
- test("intersecting intervals with same value in reverse order", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(-1, 2, "a").set(-2, 1, "a");
- expect(m.toArray()).toStrictEqual([
- [-2, "a"],
- [2, undefined],
- ]);
- });
- test("nested intervals", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(-2, 2, "a").set(-1, 1, "b");
- expect(m.toArray()).toStrictEqual([
- [-2, "a"],
- [-1, "b"],
- [1, "a"],
- [2, undefined],
- ]);
- });
- test("nested intervals in reverse order", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(-1, 1, "b").set(-2, 2, "a");
- expect(m.toArray()).toStrictEqual([
- [-2, "a"],
- [2, undefined],
- ]);
- });
- test("nested intervals with same value", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(-3, 3, "a").set(-2, 2, "a").set(-1, 1, "a");
- expect(m.toArray()).toStrictEqual([
- [-3, "a"],
- [3, undefined],
- ]);
- });
- test("nested intervals with same value in reverse order", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(-1, 1, "a").set(-2, 2, "a").set(-3, 3, "a");
- expect(m.toArray()).toStrictEqual([
- [-3, "a"],
- [3, undefined],
- ]);
- });
- test("nested intervals with same value in third order", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(-1, 1, "a").set(-3, 3, "a").set(-2, 2, "a");
- expect(m.toArray()).toStrictEqual([
- [-3, "a"],
- [3, undefined],
- ]);
- });
- test("overwrite many intervals", function () {
- var a = array(10).concat([[10, "a"]]);
- var m = new IntervalMap(a, keyCmp, valueEq);
- m.set(0.5, 10.5, "a");
- expect(m.toArray()).toStrictEqual([[0, "a"]]);
- });
+ test("empty intervals", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ expect(m.set(0, 0, "a").toArray()).toStrictEqual([]);
+ expect(m.set(0, -1, "a").toArray()).toStrictEqual([]);
+ });
+ test("one interval", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ expect(m.set(-1, 1, "a").toArray()).toStrictEqual([
+ [-1, "a"],
+ [1, undefined],
+ ]);
+ });
+ test("disjoint intervals", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(-2, -1, "a").set(1, 2, "b");
+ expect(m.toArray()).toStrictEqual([
+ [-2, "a"],
+ [-1, undefined],
+ [1, "b"],
+ [2, undefined],
+ ]);
+ });
+ test("disjoint intervals in reverse order", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(1, 2, "b").set(-2, -1, "a");
+ expect(m.toArray()).toStrictEqual([
+ [-2, "a"],
+ [-1, undefined],
+ [1, "b"],
+ [2, undefined],
+ ]);
+ });
+ test("disjoint intervals in reverse order with an undefined value", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(1, 2, "b").set(-2, -1, undefined);
+ expect(m.toArray()).toStrictEqual([
+ [1, "b"],
+ [2, undefined],
+ ]);
+ });
+ test("adjacent intervals", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(-1, 0, "a").set(0, 1, "b");
+ expect(m.toArray()).toStrictEqual([
+ [-1, "a"],
+ [0, "b"],
+ [1, undefined],
+ ]);
+ });
+ test("adjacent intervals in reverse order", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(0, 1, "b").set(-1, 0, "a");
+ expect(m.toArray()).toStrictEqual([
+ [-1, "a"],
+ [0, "b"],
+ [1, undefined],
+ ]);
+ });
+ test("adjacent intervals with same value", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(-1, 0, "a").set(0, 1, "a");
+ expect(m.toArray()).toStrictEqual([
+ [-1, "a"],
+ [1, undefined],
+ ]);
+ });
+ test("adjacent intervals with same value in reverse order", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(0, 1, "a").set(-1, 0, "a");
+ expect(m.toArray()).toStrictEqual([
+ [-1, "a"],
+ [1, undefined],
+ ]);
+ });
+ test("intersecting intervals", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(-2, 1, "a").set(-1, 2, "b");
+ expect(m.toArray()).toStrictEqual([
+ [-2, "a"],
+ [-1, "b"],
+ [2, undefined],
+ ]);
+ });
+ test("intersecting intervals in reverse order", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(-1, 2, "b").set(-2, 1, "a");
+ expect(m.toArray()).toStrictEqual([
+ [-2, "a"],
+ [1, "b"],
+ [2, undefined],
+ ]);
+ });
+ test("intersecting intervals with same value", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(-2, 1, "a").set(-1, 2, "a");
+ expect(m.toArray()).toStrictEqual([
+ [-2, "a"],
+ [2, undefined],
+ ]);
+ });
+ test("intersecting intervals with same value in reverse order", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(-1, 2, "a").set(-2, 1, "a");
+ expect(m.toArray()).toStrictEqual([
+ [-2, "a"],
+ [2, undefined],
+ ]);
+ });
+ test("nested intervals", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(-2, 2, "a").set(-1, 1, "b");
+ expect(m.toArray()).toStrictEqual([
+ [-2, "a"],
+ [-1, "b"],
+ [1, "a"],
+ [2, undefined],
+ ]);
+ });
+ test("nested intervals in reverse order", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(-1, 1, "b").set(-2, 2, "a");
+ expect(m.toArray()).toStrictEqual([
+ [-2, "a"],
+ [2, undefined],
+ ]);
+ });
+ test("nested intervals with same value", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(-3, 3, "a").set(-2, 2, "a").set(-1, 1, "a");
+ expect(m.toArray()).toStrictEqual([
+ [-3, "a"],
+ [3, undefined],
+ ]);
+ });
+ test("nested intervals with same value in reverse order", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(-1, 1, "a").set(-2, 2, "a").set(-3, 3, "a");
+ expect(m.toArray()).toStrictEqual([
+ [-3, "a"],
+ [3, undefined],
+ ]);
+ });
+ test("nested intervals with same value in third order", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(-1, 1, "a").set(-3, 3, "a").set(-2, 2, "a");
+ expect(m.toArray()).toStrictEqual([
+ [-3, "a"],
+ [3, undefined],
+ ]);
+ });
+ test("overwrite many intervals", function () {
+ var a = array(10).concat([[10, "a"]]);
+ var m = new IntervalMap(a, keyCmp, valueEq);
+ m.set(0.5, 10.5, "a");
+ expect(m.toArray()).toStrictEqual([[0, "a"]]);
+ });
});
describe("copy", function () {
- test("an empty map and check independence", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- var copy = m.copy();
- m.set(0, 1, "a");
- copy.set(0, 1, "b");
- expect(m.get(0.5)).toBe("a");
- expect(copy.get(0.5)).toBe("b");
- expect(m.size()).toStrictEqual(2);
- expect(copy.size()).toStrictEqual(2);
- });
+ test("an empty map and check independence", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ var copy = m.copy();
+ m.set(0, 1, "a");
+ copy.set(0, 1, "b");
+ expect(m.get(0.5)).toBe("a");
+ expect(copy.get(0.5)).toBe("b");
+ expect(m.size()).toStrictEqual(2);
+ expect(copy.size()).toStrictEqual(2);
+ });
});
describe("compute difference for", function () {
- test("one set op", function () {
- var m1 = new IntervalMap([], keyCmp, valueEq);
- var m2 = m1.copy().set(0, 1, "a");
- expect(m2.minus(m1)).toStrictEqual([[0, 1, "a"]]);
- });
- test("two disjoint set ops", function () {
- var m1 = new IntervalMap([], keyCmp, valueEq);
- var m2 = m1.copy().set(-2, -1, "a").set(1, 2, "b");
- expect(m2.minus(m1)).toStrictEqual([
- [-2, -1, "a"],
- [1, 2, "b"],
- ]);
- });
- test("two adjacent set ops", function () {
- var m1 = new IntervalMap([], keyCmp, valueEq);
- var m2 = m1.copy().set(-1, 0, "a").set(0, 1, "b");
- expect(m2.minus(m1)).toStrictEqual([
- [-1, 0, "a"],
- [0, 1, "b"],
- ]);
- });
- test("two adjacent set ops with the same value", function () {
- var m1 = new IntervalMap([], keyCmp, valueEq);
- var m2 = m1.copy().set(-1, 0, "a").set(0, 1, "a");
- expect(m2.minus(m1)).toStrictEqual([[-1, 1, "a"]]);
- });
- test("two intersecting set ops", function () {
- var m1 = new IntervalMap([], keyCmp, valueEq);
- var m2 = m1.copy().set(-2, 1, "a").set(-1, 2, "b");
- expect(m2.minus(m1)).toStrictEqual([
- [-2, -1, "a"],
- [-1, 2, "b"],
- ]);
- });
- test("two intersecting set ops in reverse order", function () {
- var m1 = new IntervalMap([], keyCmp, valueEq);
- var m2 = m1.copy().set(-1, 2, "b").set(-2, 1, "a");
- expect(m2.minus(m1)).toStrictEqual([
- [-2, 1, "a"],
- [1, 2, "b"],
- ]);
- });
- test("two intersecting set ops with same value", function () {
- var m1 = new IntervalMap([], keyCmp, valueEq);
- var m2 = m1.copy().set(-2, 1, "a").set(-1, 2, "a");
- expect(m2.minus(m1)).toStrictEqual([[-2, 2, "a"]]);
- });
- test("two intersecting set ops with same value in reverse order", function () {
- var m1 = new IntervalMap([], keyCmp, valueEq);
- var m2 = m1.copy().set(-1, 2, "a").set(-2, 1, "a");
- expect(m2.minus(m1)).toStrictEqual([[-2, 2, "a"]]);
- });
- test("set ops with no effect", function () {
- var m1 = new IntervalMap(
- [
- [1, "a"],
- [2, "b"],
- ],
- keyCmp,
- valueEq,
- );
- var m2 = m1.copy().set(1, 1.5, "a").set(3, 4, "b");
- expect(m2.minus(m1)).toStrictEqual([]);
- });
- test("one inexact set op", function () {
- var m1 = new IntervalMap(
- [
- [1, "a"],
- [2, "b"],
- ],
- keyCmp,
- valueEq,
- );
- var m2 = m1.copy().set(0, 1.5, "a");
- expect(m2.minus(m1)).toStrictEqual([[0, 1, "a"]]);
- });
- test("another inexact set op", function () {
- var m1 = new IntervalMap(
- [
- [1, "a"],
- [2, "b"],
- ],
- keyCmp,
- valueEq,
- );
- var m2 = m1.copy().set(1.5, 3, "b");
- expect(m2.minus(m1)).toStrictEqual([[1.5, 2, "b"]]);
- });
- test("one set on a base map with many steps", function () {
- var a = array(10);
- var m1 = new IntervalMap(a, keyCmp, valueEq);
- var m2 = m1.copy().set(0.5, 9, "a");
- expect(m2.minus(m1)).toStrictEqual([[1, 9, "a"]]);
- });
- test("multiple sets overwritten by a final set", function () {
- var m1 = new IntervalMap([[1, "a"]], keyCmp, valueEq);
- var m2 = m1
- .copy()
- .set(2, 3, "b")
- .set(3, 4, "c")
- .set(4, 5, "d")
- .set(1.5, 4, "a");
- expect(m2.minus(m1)).toStrictEqual([[4, 5, "d"]]);
- });
+ test("one set op", function () {
+ var m1 = new IntervalMap([], keyCmp, valueEq);
+ var m2 = m1.copy().set(0, 1, "a");
+ expect(m2.minus(m1)).toStrictEqual([[0, 1, "a"]]);
+ });
+ test("two disjoint set ops", function () {
+ var m1 = new IntervalMap([], keyCmp, valueEq);
+ var m2 = m1.copy().set(-2, -1, "a").set(1, 2, "b");
+ expect(m2.minus(m1)).toStrictEqual([
+ [-2, -1, "a"],
+ [1, 2, "b"],
+ ]);
+ });
+ test("two adjacent set ops", function () {
+ var m1 = new IntervalMap([], keyCmp, valueEq);
+ var m2 = m1.copy().set(-1, 0, "a").set(0, 1, "b");
+ expect(m2.minus(m1)).toStrictEqual([
+ [-1, 0, "a"],
+ [0, 1, "b"],
+ ]);
+ });
+ test("two adjacent set ops with the same value", function () {
+ var m1 = new IntervalMap([], keyCmp, valueEq);
+ var m2 = m1.copy().set(-1, 0, "a").set(0, 1, "a");
+ expect(m2.minus(m1)).toStrictEqual([[-1, 1, "a"]]);
+ });
+ test("two intersecting set ops", function () {
+ var m1 = new IntervalMap([], keyCmp, valueEq);
+ var m2 = m1.copy().set(-2, 1, "a").set(-1, 2, "b");
+ expect(m2.minus(m1)).toStrictEqual([
+ [-2, -1, "a"],
+ [-1, 2, "b"],
+ ]);
+ });
+ test("two intersecting set ops in reverse order", function () {
+ var m1 = new IntervalMap([], keyCmp, valueEq);
+ var m2 = m1.copy().set(-1, 2, "b").set(-2, 1, "a");
+ expect(m2.minus(m1)).toStrictEqual([
+ [-2, 1, "a"],
+ [1, 2, "b"],
+ ]);
+ });
+ test("two intersecting set ops with same value", function () {
+ var m1 = new IntervalMap([], keyCmp, valueEq);
+ var m2 = m1.copy().set(-2, 1, "a").set(-1, 2, "a");
+ expect(m2.minus(m1)).toStrictEqual([[-2, 2, "a"]]);
+ });
+ test("two intersecting set ops with same value in reverse order", function () {
+ var m1 = new IntervalMap([], keyCmp, valueEq);
+ var m2 = m1.copy().set(-1, 2, "a").set(-2, 1, "a");
+ expect(m2.minus(m1)).toStrictEqual([[-2, 2, "a"]]);
+ });
+ test("set ops with no effect", function () {
+ var m1 = new IntervalMap([
+ [1, "a"],
+ [2, "b"],
+ ], keyCmp, valueEq);
+ var m2 = m1.copy().set(1, 1.5, "a").set(3, 4, "b");
+ expect(m2.minus(m1)).toStrictEqual([]);
+ });
+ test("one inexact set op", function () {
+ var m1 = new IntervalMap([
+ [1, "a"],
+ [2, "b"],
+ ], keyCmp, valueEq);
+ var m2 = m1.copy().set(0, 1.5, "a");
+ expect(m2.minus(m1)).toStrictEqual([[0, 1, "a"]]);
+ });
+ test("another inexact set op", function () {
+ var m1 = new IntervalMap([
+ [1, "a"],
+ [2, "b"],
+ ], keyCmp, valueEq);
+ var m2 = m1.copy().set(1.5, 3, "b");
+ expect(m2.minus(m1)).toStrictEqual([[1.5, 2, "b"]]);
+ });
+ test("one set on a base map with many steps", function () {
+ var a = array(10);
+ var m1 = new IntervalMap(a, keyCmp, valueEq);
+ var m2 = m1.copy().set(0.5, 9, "a");
+ expect(m2.minus(m1)).toStrictEqual([[1, 9, "a"]]);
+ });
+ test("multiple sets overwritten by a final set", function () {
+ var m1 = new IntervalMap([[1, "a"]], keyCmp, valueEq);
+ var m2 = m1
+ .copy()
+ .set(2, 3, "b")
+ .set(3, 4, "c")
+ .set(4, 5, "d")
+ .set(1.5, 4, "a");
+ expect(m2.minus(m1)).toStrictEqual([[4, 5, "d"]]);
+ });
});
diff --git a/src/algorithms/Bisection.js b/src/algorithms/Bisection.js
index ec9eaf3ec..ecfd5ccf7 100644
--- a/src/algorithms/Bisection.js
+++ b/src/algorithms/Bisection.js
@@ -1,25 +1,23 @@
export function bisect(a, x, cmpToX, lo, hi, findRightMost) {
- if (lo === void 0) {
- lo = 0;
- }
- if (hi === void 0) {
- hi = a.length;
- }
- if (findRightMost === void 0) {
- findRightMost = false;
- }
- if (hi <= lo) return lo;
- if (hi === lo + 1) {
- var c_1 = cmpToX(a[lo]);
- if (c_1 < 0) return hi;
- if (c_1 > 0) return lo;
- if (c_1 === 0 && findRightMost) return hi;
- return lo;
- }
- var mid = Math.floor((lo + hi) / 2.0);
- var c = cmpToX(a[mid]);
- if (c < 0 || (c === 0 && findRightMost)) {
- return bisect(a, x, cmpToX, mid + 1, hi, findRightMost);
- }
- return bisect(a, x, cmpToX, lo, mid, findRightMost);
+ if (lo === void 0) { lo = 0; }
+ if (hi === void 0) { hi = a.length; }
+ if (findRightMost === void 0) { findRightMost = false; }
+ if (hi <= lo)
+ return lo;
+ if (hi === lo + 1) {
+ var c_1 = cmpToX(a[lo]);
+ if (c_1 < 0)
+ return hi;
+ if (c_1 > 0)
+ return lo;
+ if (c_1 === 0 && findRightMost)
+ return hi;
+ return lo;
+ }
+ var mid = Math.floor((lo + hi) / 2.0);
+ var c = cmpToX(a[mid]);
+ if (c < 0 || (c === 0 && findRightMost)) {
+ return bisect(a, x, cmpToX, mid + 1, hi, findRightMost);
+ }
+ return bisect(a, x, cmpToX, lo, mid, findRightMost);
}
diff --git a/src/algorithms/IntervalMap.js b/src/algorithms/IntervalMap.js
index 3e67ec8d9..14fa45d19 100644
--- a/src/algorithms/IntervalMap.js
+++ b/src/algorithms/IntervalMap.js
@@ -1,167 +1,126 @@
import { bisect } from "./Bisection";
function copyArray(array) {
- return array.map(function (element) {
- return [element[0], element[1]];
- });
+ return array.map(function (element) { return [element[0], element[1]]; });
}
var IntervalMap = (function () {
- function IntervalMap(array, keyCmp, valueEq) {
- this.array = [];
- var copy = copyArray(array);
- copy.sort(function (a, b) {
- return keyCmp(a[0], b[0]);
- });
- var prevValue;
- for (var _i = 0, copy_1 = copy; _i < copy_1.length; _i++) {
- var _a = copy_1[_i],
- key = _a[0],
- value = _a[1];
- if (!valueEq(value, prevValue)) {
- this.array.push([key, value]);
- prevValue = value;
- }
+ function IntervalMap(array, keyCmp, valueEq) {
+ this.array = [];
+ var copy = copyArray(array);
+ copy.sort(function (a, b) { return keyCmp(a[0], b[0]); });
+ var prevValue;
+ for (var _i = 0, copy_1 = copy; _i < copy_1.length; _i++) {
+ var _a = copy_1[_i], key = _a[0], value = _a[1];
+ if (!valueEq(value, prevValue)) {
+ this.array.push([key, value]);
+ prevValue = value;
+ }
+ }
+ this.keyCmp = keyCmp;
+ this.valueEq = valueEq;
}
- this.keyCmp = keyCmp;
- this.valueEq = valueEq;
- }
- IntervalMap.prototype.size = function () {
- return this.array.length;
- };
- IntervalMap.prototype.get = function (key) {
- var array = this.array;
- var n = array.length;
- var keyCmp = this.keyCmp;
- if (n === 0) return;
- var idx = bisect(
- array,
- key,
- function (a) {
- return keyCmp(a[0], key);
- },
- 0,
- n,
- false,
- );
- if (idx === n) {
- return array[idx - 1][1];
- }
- if (keyCmp(array[idx][0], key) === 0) {
- return array[idx][1];
- }
- if (idx > 0) {
- return array[idx - 1][1];
- }
- return;
- };
- IntervalMap.prototype.set = function (key1, key2, value) {
- var array = this.array;
- var n = array.length;
- var keyCmp = this.keyCmp;
- var valueEq = this.valueEq;
- if (keyCmp(key1, key2) >= 0) return this;
- if (n === 0) {
- array.push([key1, value], [key2, undefined]);
- return this;
- }
- var idx1 = bisect(
- array,
- key1,
- function (a) {
- return keyCmp(a[0], key1);
- },
- 0,
- array.length,
- false,
- );
- if (idx1 === n) {
- var v = array[n - 1][1];
- if (!valueEq(value, v)) {
- array.push([key1, value], [key2, v]);
- }
- return this;
- }
- var idx2 =
- bisect(
- array,
- key2,
- function (a) {
- return keyCmp(a[0], key2);
- },
- 0,
- array.length,
- true,
- ) - 1;
- if (idx2 === -1) {
- if (!valueEq(value, undefined)) {
- array.splice(0, 0, [key1, value], [key2, undefined]);
- }
- return this;
- }
- var insert1 = !(idx1 > 0 && valueEq(array[idx1 - 1][1], value));
- var insert2 = !valueEq(array[idx2][1], value);
- if (insert1 && insert2) {
- array.splice(
- idx1,
- idx2 - idx1 + 1,
- [key1, value],
- [key2, array[idx2][1]],
- );
- } else if (insert1) {
- array.splice(idx1, idx2 - idx1 + 1, [key1, value]);
- } else if (insert2) {
- array.splice(idx1, idx2 - idx1 + 1, [key2, array[idx2][1]]);
- } else {
- array.splice(idx1, idx2 - idx1 + 1);
- }
- return this;
- };
- IntervalMap.prototype.keys = function () {
- return this.array.map(function (element) {
- return element[0];
- });
- };
- IntervalMap.prototype.values = function () {
- return this.array.map(function (element) {
- return element[1];
- });
- };
- IntervalMap.prototype.toArray = function () {
- return copyArray(this.array);
- };
- IntervalMap.prototype.copy = function () {
- return new IntervalMap(this.array, this.keyCmp, this.valueEq);
- };
- IntervalMap.prototype.minus = function (baseMap) {
- var _this = this;
- var keys = this.keys().concat(baseMap.keys());
- keys.sort(this.keyCmp);
- var equalValues = keys.map(function (key) {
- return _this.valueEq(_this.get(key), baseMap.get(key));
- });
- var idx = 0;
- var diff = [];
- while (idx + 1 < keys.length) {
- if (!equalValues[idx]) {
- diff.push([keys[idx], keys[idx + 1], this.get(keys[idx])]);
- }
- idx += 1;
- }
- var i = 0;
- var mergedDiff = [];
- while (i < diff.length) {
- var _a = diff[i],
- st = _a[0],
- en = _a[1],
- val = _a[2];
- while (i + 1 < diff.length && this.valueEq(diff[i][2], diff[i + 1][2])) {
- en = diff[i + 1][1];
- i += 1;
- }
- mergedDiff.push([st, en, val]);
- i += 1;
- }
- return mergedDiff;
- };
- return IntervalMap;
-})();
+ IntervalMap.prototype.size = function () {
+ return this.array.length;
+ };
+ IntervalMap.prototype.get = function (key) {
+ var array = this.array;
+ var n = array.length;
+ var keyCmp = this.keyCmp;
+ if (n === 0)
+ return;
+ var idx = bisect(array, key, function (a) { return keyCmp(a[0], key); }, 0, n, false);
+ if (idx === n) {
+ return array[idx - 1][1];
+ }
+ if (keyCmp(array[idx][0], key) === 0) {
+ return array[idx][1];
+ }
+ if (idx > 0) {
+ return array[idx - 1][1];
+ }
+ return;
+ };
+ IntervalMap.prototype.set = function (key1, key2, value) {
+ var array = this.array;
+ var n = array.length;
+ var keyCmp = this.keyCmp;
+ var valueEq = this.valueEq;
+ if (keyCmp(key1, key2) >= 0)
+ return this;
+ if (n === 0) {
+ array.push([key1, value], [key2, undefined]);
+ return this;
+ }
+ var idx1 = bisect(array, key1, function (a) { return keyCmp(a[0], key1); }, 0, array.length, false);
+ if (idx1 === n) {
+ var v = array[n - 1][1];
+ if (!valueEq(value, v)) {
+ array.push([key1, value], [key2, v]);
+ }
+ return this;
+ }
+ var idx2 = bisect(array, key2, function (a) { return keyCmp(a[0], key2); }, 0, array.length, true) - 1;
+ if (idx2 === -1) {
+ if (!valueEq(value, undefined)) {
+ array.splice(0, 0, [key1, value], [key2, undefined]);
+ }
+ return this;
+ }
+ var insert1 = !(idx1 > 0 && valueEq(array[idx1 - 1][1], value));
+ var insert2 = !valueEq(array[idx2][1], value);
+ if (insert1 && insert2) {
+ array.splice(idx1, idx2 - idx1 + 1, [key1, value], [key2, array[idx2][1]]);
+ }
+ else if (insert1) {
+ array.splice(idx1, idx2 - idx1 + 1, [key1, value]);
+ }
+ else if (insert2) {
+ array.splice(idx1, idx2 - idx1 + 1, [key2, array[idx2][1]]);
+ }
+ else {
+ array.splice(idx1, idx2 - idx1 + 1);
+ }
+ return this;
+ };
+ IntervalMap.prototype.keys = function () {
+ return this.array.map(function (element) { return element[0]; });
+ };
+ IntervalMap.prototype.values = function () {
+ return this.array.map(function (element) { return element[1]; });
+ };
+ IntervalMap.prototype.toArray = function () {
+ return copyArray(this.array);
+ };
+ IntervalMap.prototype.copy = function () {
+ return new IntervalMap(this.array, this.keyCmp, this.valueEq);
+ };
+ IntervalMap.prototype.minus = function (baseMap) {
+ var _this = this;
+ var keys = this.keys().concat(baseMap.keys());
+ keys.sort(this.keyCmp);
+ var equalValues = keys.map(function (key) {
+ return _this.valueEq(_this.get(key), baseMap.get(key));
+ });
+ var idx = 0;
+ var diff = [];
+ while (idx + 1 < keys.length) {
+ if (!equalValues[idx]) {
+ diff.push([keys[idx], keys[idx + 1], this.get(keys[idx])]);
+ }
+ idx += 1;
+ }
+ var i = 0;
+ var mergedDiff = [];
+ while (i < diff.length) {
+ var _a = diff[i], st = _a[0], en = _a[1], val = _a[2];
+ while (i + 1 < diff.length && this.valueEq(diff[i][2], diff[i + 1][2])) {
+ en = diff[i + 1][1];
+ i += 1;
+ }
+ mergedDiff.push([st, en, val]);
+ i += 1;
+ }
+ return mergedDiff;
+ };
+ return IntervalMap;
+}());
export { IntervalMap };
diff --git a/tsconfig.json b/tsconfig.json
index a3c6d968f..bd14625d5 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -17,7 +17,6 @@
"strictNullChecks": true,
"strictPropertyInitialization": true,
"useUnknownInCatchVariables": true,
- "noImplicitUseStrict": true,
"ignoreDeprecations": "5.0"
},
"include": ["src/**/*.ts"]
From 9a5013b8e0d171585d43931c597206d124956091 Mon Sep 17 00:00:00 2001
From: Anthony Volk
Date: Mon, 21 Oct 2024 20:08:17 +0200
Subject: [PATCH 24/31] fix: Prevent null value from crashing
OneYearValueSetter
---
src/pages/policy/input/ParameterEditor.jsx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/pages/policy/input/ParameterEditor.jsx b/src/pages/policy/input/ParameterEditor.jsx
index c8958c776..9b98805bc 100644
--- a/src/pages/policy/input/ParameterEditor.jsx
+++ b/src/pages/policy/input/ParameterEditor.jsx
@@ -609,9 +609,9 @@ function OneYearValueSetter(props) {
maximumFractionDigits: userTyping ? 16 : maximumFractionDigits,
});
}}
- defaultValue={startValue * scale}
+ defaultValue={Number(startValue) * scale}
value={valueMap.get(year) * scale}
- onChange={changeHandler}
+ onChange={(value) => changeHandler(Number(value))}
/>
{!isPercent && (
Date: Mon, 21 Oct 2024 20:43:59 +0200
Subject: [PATCH 25/31] fix: Remove unused code
---
src/pages/policy/input/ParameterEditor.jsx | 52 +---------------------
1 file changed, 2 insertions(+), 50 deletions(-)
diff --git a/src/pages/policy/input/ParameterEditor.jsx b/src/pages/policy/input/ParameterEditor.jsx
index 9b98805bc..98e63537b 100644
--- a/src/pages/policy/input/ParameterEditor.jsx
+++ b/src/pages/policy/input/ParameterEditor.jsx
@@ -26,7 +26,7 @@ import {
import { IntervalMap } from "algorithms/IntervalMap";
import { cmpDates, nextDay, prevDay } from "lang/stringDates";
import moment from "dayjs";
-import { DownOutlined, EllipsisOutlined, FunctionOutlined, LeftOutlined, RightOutlined, SettingOutlined, UndoOutlined, UpOutlined } from "@ant-design/icons";
+import { EllipsisOutlined, SettingOutlined } from "@ant-design/icons";
import style from "../../../style";
import { defaultYear } from "../../../data/constants";
const { RangePicker } = DatePicker;
@@ -394,7 +394,7 @@ function DatePeriodSetter(props) {
}
function MultiYearPeriodSetter(props) {
- const { startDate, endDate, setStartDate, setEndDate, possibleYears, FOREVER_DATE, parameterName, baseMap, reformMap, metadata, policy } = props;
+ const { possibleYears, parameterName, baseMap, reformMap, metadata, policy } = props;
const NUMBER_OF_YEARS = 10;
const [valueMap, setValueMap] = useState(populateValueMap());
@@ -903,52 +903,4 @@ function SettingsPanel(props) {
);
}
-/**
- * Checks whether or not an input date is a boundary date -
- * the first or last day of a fixed period (e.g., Jan. 1 or
- * Dec. 31)
- * @param {String} date
- * @param {("start"|"end")} variant The date type - either a
- * period's start or its end date
- * @returns {Boolean} Whether or not the date is a boundary date
- */
-function checkBoundaryDate(date, variant) {
- // Define boundary dates and types
- // Note that month is 0-indexed in moment
- const boundaries = [
- {
- type: "start",
- month: 0,
- date: 1,
- },
- {
- type: "end",
- month: 11,
- date: 31,
- },
- ];
-
- // Take the date and define it in terms of moment package
- const momentDate = moment(date);
-
- // Duplicate its year for testing purposes
- const testYear = momentDate.year();
-
- // For each boundary defined above
- for (const boundary of boundaries) {
- // Set up a test date using the test year and the boundary's defined
- // month and date
- const testDate = moment()
- .year(testYear)
- .month(boundary.month)
- .date(boundary.date);
- // If the date is a boundary date, return true
- if (boundary.type === variant && testDate.isSame(momentDate, "date")) {
- return true;
- }
- }
- // If we've found no boundary dates, return false
- return false;
-}
-
export const ParamChartWidthContext = createContext((obj) => obj);
From 2af3528cd2e2a26994c23897bd09811388c83935 Mon Sep 17 00:00:00 2001
From: Anthony Volk
Date: Mon, 21 Oct 2024 20:44:53 +0200
Subject: [PATCH 26/31] fix: Remove unsafe data declaration
---
src/pages/policy/input/ParameterEditor.jsx | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/pages/policy/input/ParameterEditor.jsx b/src/pages/policy/input/ParameterEditor.jsx
index 98e63537b..ae1b2119e 100644
--- a/src/pages/policy/input/ParameterEditor.jsx
+++ b/src/pages/policy/input/ParameterEditor.jsx
@@ -425,27 +425,28 @@ function MultiYearPeriodSetter(props) {
// all values are valid, then updates each value one by one
function handleSubmit() {
- let data = {}
+ let allData = {};
for (const [year, value] of valueMap) {
const startDate = String(year).concat("-01-01");
const endDate = String(year).concat("-12-31");
reformMap.set(startDate, nextDay(endDate), value);
- data = {};
+ let data = {};
reformMap.minus(baseMap).forEach(([k1, k2, v]) => {
data[`${k1}.${prevDay(k2)}`] = v;
});
+ allData = { ...allData, ...data };
}
const newReforms = { ...policy.reform.data };
if (
- Object.keys(data).length === 0 &&
+ Object.keys(allData).length === 0 &&
Object.keys(newReforms).length === 1
) {
let newSearch = copySearchParams(searchParams);
newSearch.delete("reform");
setSearchParams(newSearch);
} else {
- newReforms[parameterName] = data;
+ newReforms[parameterName] = allData;
getNewPolicyId(metadata.countryId, newReforms).then((result) => {
if (result.status !== "ok") {
console.error(
From 5ffe4de3dbcb9c920041a9edc13dbf81505d1658 Mon Sep 17 00:00:00 2001
From: Anthony Volk
Date: Mon, 21 Oct 2024 20:56:42 +0200
Subject: [PATCH 27/31] fix: Properly pass callback of populateValueMap
---
src/pages/policy/input/ParameterEditor.jsx | 32 ++++++++++++++++------
1 file changed, 23 insertions(+), 9 deletions(-)
diff --git a/src/pages/policy/input/ParameterEditor.jsx b/src/pages/policy/input/ParameterEditor.jsx
index ae1b2119e..8e6c54f1b 100644
--- a/src/pages/policy/input/ParameterEditor.jsx
+++ b/src/pages/policy/input/ParameterEditor.jsx
@@ -13,7 +13,7 @@ import {
Tooltip,
} from "antd";
import { getNewPolicyId } from "../../../api/parameters";
-import { createContext, useEffect, useRef, useState } from "react";
+import { createContext, useCallback, useEffect, useRef, useState } from "react";
import { useSearchParams } from "react-router-dom";
import { copySearchParams } from "../../../api/call";
import { capitalize, localeCode } from "../../../lang/format";
@@ -396,12 +396,9 @@ function DatePeriodSetter(props) {
function MultiYearPeriodSetter(props) {
const { possibleYears, parameterName, baseMap, reformMap, metadata, policy } = props;
- const NUMBER_OF_YEARS = 10;
- const [valueMap, setValueMap] = useState(populateValueMap());
- const [searchParams, setSearchParams] = useSearchParams();
-
// Populate map before rendering anything
- function populateValueMap() {
+ // function populateValueMap() {
+ const populateValueMap = useCallback(() => {
const valueMap = new Map();
possibleYears.forEach((year) => {
@@ -412,14 +409,31 @@ function MultiYearPeriodSetter(props) {
}
});
return valueMap;
- }
+ }, [possibleYears, reformMap]);
+
+ const NUMBER_OF_YEARS = 10;
+ const [valueMap, setValueMap] = useState(populateValueMap());
+ const [searchParams, setSearchParams] = useSearchParams();
+ const paramRef = useRef(parameterName);
+
// This is necessary because technically, MultiYearPeriodSetter does not
// unmount when we change between parameters, leading to the possibility
// for a stale "value" state in this controlled component
+
+ // We're using a ref here because each time the changeHandler is called,
+ // it updates reformMap. This then re-renders the callback above, causing
+ // valueMap to be re-populated with stale data, creating a visual bug.
+ // All of this wouldn't be necessary if we either 1. didn't add populateValueMap
+ // as an effect hook dep (but then we'd be overriding linting) or 2. fully
+ // unmounted the component when we changed pages (but that'd require far
+ // more work)
useEffect(() => {
- setValueMap(populateValueMap());
- }, [parameterName]);
+ if (paramRef.current !== parameterName) {
+ setValueMap(populateValueMap());
+ paramRef.current = parameterName;
+ }
+ }, [parameterName, populateValueMap]);
// Handler that iterates over each entry, validates that
// all values are valid, then updates each value one by one
From a01a299a17948d7ae0e31e0e9a87991d01a7e8cd Mon Sep 17 00:00:00 2001
From: Anthony Volk
Date: Mon, 21 Oct 2024 21:03:59 +0200
Subject: [PATCH 28/31] chore: Lint
---
src/__tests__/algorithms/Bisection.test.js | 135 +++-
src/__tests__/algorithms/IntervalMap.test.js | 708 ++++++++++---------
src/algorithms/Bisection.js | 44 +-
src/algorithms/IntervalMap.js | 281 ++++----
src/pages/policy/input/ParameterEditor.jsx | 173 ++---
5 files changed, 747 insertions(+), 594 deletions(-)
diff --git a/src/__tests__/algorithms/Bisection.test.js b/src/__tests__/algorithms/Bisection.test.js
index ea9434f42..c02ae90c9 100644
--- a/src/__tests__/algorithms/Bisection.test.js
+++ b/src/__tests__/algorithms/Bisection.test.js
@@ -1,31 +1,110 @@
import { bisect } from "algorithms/Bisection";
describe("bisection", function () {
- test("small cases", function () {
- expect(bisect([], 1, function (a) { return a - 1; })).toBe(0);
- expect(bisect([1], 1, function (a) { return a - 1; })).toBe(0);
- expect(bisect([1], 2, function (a) { return a - 2; })).toBe(1);
- expect(bisect([1], 1, function (a) { return a - 1; }, 0, 1, true)).toBe(1);
- });
- var a = [0, 1, 2, 3, 4, 5];
- test.each(a)("identity", function (e) {
- expect(bisect(a, e, function (o) { return o - e; })).toBe(e);
- });
- test.each(a)("successor 1", function (e) {
- expect(bisect(a, e + 0.5, function (o) { return o - e - 0.5; })).toBe(e + 1);
- });
- test.each(a)("successor 2", function (e) {
- expect(bisect(a, e, function (o) { return o - e; }, 0, a.length, true)).toBe(e + 1);
- });
- test.each(a)("successor 3", function (e) {
- expect(bisect(a, e + 0.5, function (o) { return o - e - 0.5; }, 0, a.length, true)).toBe(e + 1);
- });
- test("duplicates", function () {
- var a = [0, 1, 2, 3, 3, 3, 6, 7];
- expect(bisect(a, 3, function (e) { return e - 3; })).toBe(3);
- expect(bisect(a, 3, function (e) { return e - 3; }, 0, a.length, true)).toBe(6);
- });
- test("unknown", function () {
- var a = [-2, -1];
- expect(bisect(a, 1, function (e) { return e - 1; }, 0, a.length, false)).toBe(a.length);
- });
+ test("small cases", function () {
+ expect(
+ bisect([], 1, function (a) {
+ return a - 1;
+ }),
+ ).toBe(0);
+ expect(
+ bisect([1], 1, function (a) {
+ return a - 1;
+ }),
+ ).toBe(0);
+ expect(
+ bisect([1], 2, function (a) {
+ return a - 2;
+ }),
+ ).toBe(1);
+ expect(
+ bisect(
+ [1],
+ 1,
+ function (a) {
+ return a - 1;
+ },
+ 0,
+ 1,
+ true,
+ ),
+ ).toBe(1);
+ });
+ var a = [0, 1, 2, 3, 4, 5];
+ test.each(a)("identity", function (e) {
+ expect(
+ bisect(a, e, function (o) {
+ return o - e;
+ }),
+ ).toBe(e);
+ });
+ test.each(a)("successor 1", function (e) {
+ expect(
+ bisect(a, e + 0.5, function (o) {
+ return o - e - 0.5;
+ }),
+ ).toBe(e + 1);
+ });
+ test.each(a)("successor 2", function (e) {
+ expect(
+ bisect(
+ a,
+ e,
+ function (o) {
+ return o - e;
+ },
+ 0,
+ a.length,
+ true,
+ ),
+ ).toBe(e + 1);
+ });
+ test.each(a)("successor 3", function (e) {
+ expect(
+ bisect(
+ a,
+ e + 0.5,
+ function (o) {
+ return o - e - 0.5;
+ },
+ 0,
+ a.length,
+ true,
+ ),
+ ).toBe(e + 1);
+ });
+ test("duplicates", function () {
+ var a = [0, 1, 2, 3, 3, 3, 6, 7];
+ expect(
+ bisect(a, 3, function (e) {
+ return e - 3;
+ }),
+ ).toBe(3);
+ expect(
+ bisect(
+ a,
+ 3,
+ function (e) {
+ return e - 3;
+ },
+ 0,
+ a.length,
+ true,
+ ),
+ ).toBe(6);
+ });
+ test("unknown", function () {
+ var a = [-2, -1];
+ expect(
+ bisect(
+ a,
+ 1,
+ function (e) {
+ return e - 1;
+ },
+ 0,
+ a.length,
+ false,
+ ),
+ ).toBe(a.length);
+ });
});
diff --git a/src/__tests__/algorithms/IntervalMap.test.js b/src/__tests__/algorithms/IntervalMap.test.js
index e72de2775..cfd6a6473 100644
--- a/src/__tests__/algorithms/IntervalMap.test.js
+++ b/src/__tests__/algorithms/IntervalMap.test.js
@@ -1,364 +1,392 @@
import { IntervalMap } from "algorithms/IntervalMap";
-var keyCmp = function (x, y) { return x - y; };
-var valueEq = function (x, y) { return x === y; };
+var keyCmp = function (x, y) {
+ return x - y;
+};
+var valueEq = function (x, y) {
+ return x === y;
+};
function f(i) {
- return String.fromCharCode(97 + i);
+ return String.fromCharCode(97 + i);
}
function array(n) {
- var a = [];
- for (var i = 0; i < n; i++) {
- a.push([i, f(i)]);
- }
- return a;
+ var a = [];
+ for (var i = 0; i < n; i++) {
+ a.push([i, f(i)]);
+ }
+ return a;
}
function randArray(n, m) {
- var rand = function () { return Math.floor(Math.random() * m); };
- var a = [];
- for (var i = 0; i < n; i++) {
- a.push([i, f(rand())]);
- }
- return a;
+ var rand = function () {
+ return Math.floor(Math.random() * m);
+ };
+ var a = [];
+ for (var i = 0; i < n; i++) {
+ a.push([i, f(rand())]);
+ }
+ return a;
}
function keys(n) {
- var a = [];
- for (var i = 0; i < n; i++) {
- a.push(i);
- }
- return a;
+ var a = [];
+ for (var i = 0; i < n; i++) {
+ a.push(i);
+ }
+ return a;
}
function hasDuplicates(a) {
- var s = new Set(a);
- return s.size < a.length;
+ var s = new Set(a);
+ return s.size < a.length;
}
function hasConsecutiveDuplicates(a) {
- for (var i = 0; i + 1 < a.length; i++) {
- if (a[i] === a[i + 1])
- return true;
- }
- return false;
+ for (var i = 0; i + 1 < a.length; i++) {
+ if (a[i] === a[i + 1]) return true;
+ }
+ return false;
}
function isSorted(a) {
- for (var i = 0; i + 1 < a.length; i++) {
- if (a[i] > a[i + 1])
- return false;
- }
- return true;
+ for (var i = 0; i + 1 < a.length; i++) {
+ if (a[i] > a[i + 1]) return false;
+ }
+ return true;
}
describe("construct", function () {
- test("an empty map", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- expect(m.size()).toBe(0);
- expect(m.keys()).toStrictEqual([]);
- expect(m.values()).toStrictEqual([]);
- expect(m.toArray()).toStrictEqual([]);
- });
- test.concurrent.each([5, 25, 125])("nonempty maps without repeated keys or values in initializer", function (size) {
- var a = array(size);
- var m = new IntervalMap(a, keyCmp, valueEq);
- expect(m.size()).toBe(size);
- expect(m.toArray()).toStrictEqual(a);
- });
- test.concurrent.each([5, 25, 125])("nonempty maps with repeated keys in initializer", function (size) {
- var a = array(size);
- a.concat(a);
- var m = new IntervalMap(a, keyCmp, valueEq);
- expect(hasDuplicates(m.keys())).toBe(false);
- expect(m.size()).toBe(size);
- });
- test.concurrent.each([
- [5, 2],
- [5, 5],
- [25, 5],
- [25, 25],
- [125, 5],
- ])("nonempty maps with repeated values in initializer", function (size, numValues) {
- var a = randArray(size, numValues);
- var m = new IntervalMap(a, keyCmp, valueEq);
- expect(hasConsecutiveDuplicates(m.values())).toBe(false);
- expect(m.size()).toBeLessThanOrEqual(size);
- });
- test.concurrent.each([5, 25, 125])("nonempty maps without unsorted initializer", function (size) {
- var a = array(size);
- a.reverse();
- var m = new IntervalMap(a, keyCmp, valueEq);
- expect(isSorted(m.keys())).toBe(true);
- expect(m.size()).toBe(size);
- });
+ test("an empty map", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ expect(m.size()).toBe(0);
+ expect(m.keys()).toStrictEqual([]);
+ expect(m.values()).toStrictEqual([]);
+ expect(m.toArray()).toStrictEqual([]);
+ });
+ test.concurrent.each([5, 25, 125])(
+ "nonempty maps without repeated keys or values in initializer",
+ function (size) {
+ var a = array(size);
+ var m = new IntervalMap(a, keyCmp, valueEq);
+ expect(m.size()).toBe(size);
+ expect(m.toArray()).toStrictEqual(a);
+ },
+ );
+ test.concurrent.each([5, 25, 125])(
+ "nonempty maps with repeated keys in initializer",
+ function (size) {
+ var a = array(size);
+ a.concat(a);
+ var m = new IntervalMap(a, keyCmp, valueEq);
+ expect(hasDuplicates(m.keys())).toBe(false);
+ expect(m.size()).toBe(size);
+ },
+ );
+ test.concurrent.each([
+ [5, 2],
+ [5, 5],
+ [25, 5],
+ [25, 25],
+ [125, 5],
+ ])(
+ "nonempty maps with repeated values in initializer",
+ function (size, numValues) {
+ var a = randArray(size, numValues);
+ var m = new IntervalMap(a, keyCmp, valueEq);
+ expect(hasConsecutiveDuplicates(m.values())).toBe(false);
+ expect(m.size()).toBeLessThanOrEqual(size);
+ },
+ );
+ test.concurrent.each([5, 25, 125])(
+ "nonempty maps without unsorted initializer",
+ function (size) {
+ var a = array(size);
+ a.reverse();
+ var m = new IntervalMap(a, keyCmp, valueEq);
+ expect(isSorted(m.keys())).toBe(true);
+ expect(m.size()).toBe(size);
+ },
+ );
});
-describe("get values from ", function () {
- var n = 10;
- var a = array(n);
- test("empty map", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- expect(m.get(0)).toBeUndefined();
- });
- test.each(keys(n))("nonempty map", function (key) {
- var m = new IntervalMap(a, keyCmp, valueEq);
- expect(m.get(key)).toBe(f(key));
- expect(m.get(key + 0.5)).toBe(f(key));
- });
+describe("get values from", function () {
+ var n = 10;
+ var a = array(n);
+ test("empty map", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ expect(m.get(0)).toBeUndefined();
+ });
+ test.each(keys(n))("nonempty map", function (key) {
+ var m = new IntervalMap(a, keyCmp, valueEq);
+ expect(m.get(key)).toBe(f(key));
+ expect(m.get(key + 0.5)).toBe(f(key));
+ });
});
describe("set", function () {
- test("empty intervals", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- expect(m.set(0, 0, "a").toArray()).toStrictEqual([]);
- expect(m.set(0, -1, "a").toArray()).toStrictEqual([]);
- });
- test("one interval", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- expect(m.set(-1, 1, "a").toArray()).toStrictEqual([
- [-1, "a"],
- [1, undefined],
- ]);
- });
- test("disjoint intervals", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(-2, -1, "a").set(1, 2, "b");
- expect(m.toArray()).toStrictEqual([
- [-2, "a"],
- [-1, undefined],
- [1, "b"],
- [2, undefined],
- ]);
- });
- test("disjoint intervals in reverse order", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(1, 2, "b").set(-2, -1, "a");
- expect(m.toArray()).toStrictEqual([
- [-2, "a"],
- [-1, undefined],
- [1, "b"],
- [2, undefined],
- ]);
- });
- test("disjoint intervals in reverse order with an undefined value", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(1, 2, "b").set(-2, -1, undefined);
- expect(m.toArray()).toStrictEqual([
- [1, "b"],
- [2, undefined],
- ]);
- });
- test("adjacent intervals", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(-1, 0, "a").set(0, 1, "b");
- expect(m.toArray()).toStrictEqual([
- [-1, "a"],
- [0, "b"],
- [1, undefined],
- ]);
- });
- test("adjacent intervals in reverse order", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(0, 1, "b").set(-1, 0, "a");
- expect(m.toArray()).toStrictEqual([
- [-1, "a"],
- [0, "b"],
- [1, undefined],
- ]);
- });
- test("adjacent intervals with same value", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(-1, 0, "a").set(0, 1, "a");
- expect(m.toArray()).toStrictEqual([
- [-1, "a"],
- [1, undefined],
- ]);
- });
- test("adjacent intervals with same value in reverse order", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(0, 1, "a").set(-1, 0, "a");
- expect(m.toArray()).toStrictEqual([
- [-1, "a"],
- [1, undefined],
- ]);
- });
- test("intersecting intervals", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(-2, 1, "a").set(-1, 2, "b");
- expect(m.toArray()).toStrictEqual([
- [-2, "a"],
- [-1, "b"],
- [2, undefined],
- ]);
- });
- test("intersecting intervals in reverse order", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(-1, 2, "b").set(-2, 1, "a");
- expect(m.toArray()).toStrictEqual([
- [-2, "a"],
- [1, "b"],
- [2, undefined],
- ]);
- });
- test("intersecting intervals with same value", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(-2, 1, "a").set(-1, 2, "a");
- expect(m.toArray()).toStrictEqual([
- [-2, "a"],
- [2, undefined],
- ]);
- });
- test("intersecting intervals with same value in reverse order", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(-1, 2, "a").set(-2, 1, "a");
- expect(m.toArray()).toStrictEqual([
- [-2, "a"],
- [2, undefined],
- ]);
- });
- test("nested intervals", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(-2, 2, "a").set(-1, 1, "b");
- expect(m.toArray()).toStrictEqual([
- [-2, "a"],
- [-1, "b"],
- [1, "a"],
- [2, undefined],
- ]);
- });
- test("nested intervals in reverse order", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(-1, 1, "b").set(-2, 2, "a");
- expect(m.toArray()).toStrictEqual([
- [-2, "a"],
- [2, undefined],
- ]);
- });
- test("nested intervals with same value", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(-3, 3, "a").set(-2, 2, "a").set(-1, 1, "a");
- expect(m.toArray()).toStrictEqual([
- [-3, "a"],
- [3, undefined],
- ]);
- });
- test("nested intervals with same value in reverse order", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(-1, 1, "a").set(-2, 2, "a").set(-3, 3, "a");
- expect(m.toArray()).toStrictEqual([
- [-3, "a"],
- [3, undefined],
- ]);
- });
- test("nested intervals with same value in third order", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- m.set(-1, 1, "a").set(-3, 3, "a").set(-2, 2, "a");
- expect(m.toArray()).toStrictEqual([
- [-3, "a"],
- [3, undefined],
- ]);
- });
- test("overwrite many intervals", function () {
- var a = array(10).concat([[10, "a"]]);
- var m = new IntervalMap(a, keyCmp, valueEq);
- m.set(0.5, 10.5, "a");
- expect(m.toArray()).toStrictEqual([[0, "a"]]);
- });
+ test("empty intervals", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ expect(m.set(0, 0, "a").toArray()).toStrictEqual([]);
+ expect(m.set(0, -1, "a").toArray()).toStrictEqual([]);
+ });
+ test("one interval", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ expect(m.set(-1, 1, "a").toArray()).toStrictEqual([
+ [-1, "a"],
+ [1, undefined],
+ ]);
+ });
+ test("disjoint intervals", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(-2, -1, "a").set(1, 2, "b");
+ expect(m.toArray()).toStrictEqual([
+ [-2, "a"],
+ [-1, undefined],
+ [1, "b"],
+ [2, undefined],
+ ]);
+ });
+ test("disjoint intervals in reverse order", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(1, 2, "b").set(-2, -1, "a");
+ expect(m.toArray()).toStrictEqual([
+ [-2, "a"],
+ [-1, undefined],
+ [1, "b"],
+ [2, undefined],
+ ]);
+ });
+ test("disjoint intervals in reverse order with an undefined value", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(1, 2, "b").set(-2, -1, undefined);
+ expect(m.toArray()).toStrictEqual([
+ [1, "b"],
+ [2, undefined],
+ ]);
+ });
+ test("adjacent intervals", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(-1, 0, "a").set(0, 1, "b");
+ expect(m.toArray()).toStrictEqual([
+ [-1, "a"],
+ [0, "b"],
+ [1, undefined],
+ ]);
+ });
+ test("adjacent intervals in reverse order", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(0, 1, "b").set(-1, 0, "a");
+ expect(m.toArray()).toStrictEqual([
+ [-1, "a"],
+ [0, "b"],
+ [1, undefined],
+ ]);
+ });
+ test("adjacent intervals with same value", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(-1, 0, "a").set(0, 1, "a");
+ expect(m.toArray()).toStrictEqual([
+ [-1, "a"],
+ [1, undefined],
+ ]);
+ });
+ test("adjacent intervals with same value in reverse order", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(0, 1, "a").set(-1, 0, "a");
+ expect(m.toArray()).toStrictEqual([
+ [-1, "a"],
+ [1, undefined],
+ ]);
+ });
+ test("intersecting intervals", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(-2, 1, "a").set(-1, 2, "b");
+ expect(m.toArray()).toStrictEqual([
+ [-2, "a"],
+ [-1, "b"],
+ [2, undefined],
+ ]);
+ });
+ test("intersecting intervals in reverse order", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(-1, 2, "b").set(-2, 1, "a");
+ expect(m.toArray()).toStrictEqual([
+ [-2, "a"],
+ [1, "b"],
+ [2, undefined],
+ ]);
+ });
+ test("intersecting intervals with same value", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(-2, 1, "a").set(-1, 2, "a");
+ expect(m.toArray()).toStrictEqual([
+ [-2, "a"],
+ [2, undefined],
+ ]);
+ });
+ test("intersecting intervals with same value in reverse order", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(-1, 2, "a").set(-2, 1, "a");
+ expect(m.toArray()).toStrictEqual([
+ [-2, "a"],
+ [2, undefined],
+ ]);
+ });
+ test("nested intervals", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(-2, 2, "a").set(-1, 1, "b");
+ expect(m.toArray()).toStrictEqual([
+ [-2, "a"],
+ [-1, "b"],
+ [1, "a"],
+ [2, undefined],
+ ]);
+ });
+ test("nested intervals in reverse order", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(-1, 1, "b").set(-2, 2, "a");
+ expect(m.toArray()).toStrictEqual([
+ [-2, "a"],
+ [2, undefined],
+ ]);
+ });
+ test("nested intervals with same value", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(-3, 3, "a").set(-2, 2, "a").set(-1, 1, "a");
+ expect(m.toArray()).toStrictEqual([
+ [-3, "a"],
+ [3, undefined],
+ ]);
+ });
+ test("nested intervals with same value in reverse order", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(-1, 1, "a").set(-2, 2, "a").set(-3, 3, "a");
+ expect(m.toArray()).toStrictEqual([
+ [-3, "a"],
+ [3, undefined],
+ ]);
+ });
+ test("nested intervals with same value in third order", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ m.set(-1, 1, "a").set(-3, 3, "a").set(-2, 2, "a");
+ expect(m.toArray()).toStrictEqual([
+ [-3, "a"],
+ [3, undefined],
+ ]);
+ });
+ test("overwrite many intervals", function () {
+ var a = array(10).concat([[10, "a"]]);
+ var m = new IntervalMap(a, keyCmp, valueEq);
+ m.set(0.5, 10.5, "a");
+ expect(m.toArray()).toStrictEqual([[0, "a"]]);
+ });
});
describe("copy", function () {
- test("an empty map and check independence", function () {
- var m = new IntervalMap([], keyCmp, valueEq);
- var copy = m.copy();
- m.set(0, 1, "a");
- copy.set(0, 1, "b");
- expect(m.get(0.5)).toBe("a");
- expect(copy.get(0.5)).toBe("b");
- expect(m.size()).toStrictEqual(2);
- expect(copy.size()).toStrictEqual(2);
- });
+ test("an empty map and check independence", function () {
+ var m = new IntervalMap([], keyCmp, valueEq);
+ var copy = m.copy();
+ m.set(0, 1, "a");
+ copy.set(0, 1, "b");
+ expect(m.get(0.5)).toBe("a");
+ expect(copy.get(0.5)).toBe("b");
+ expect(m.size()).toStrictEqual(2);
+ expect(copy.size()).toStrictEqual(2);
+ });
});
describe("compute difference for", function () {
- test("one set op", function () {
- var m1 = new IntervalMap([], keyCmp, valueEq);
- var m2 = m1.copy().set(0, 1, "a");
- expect(m2.minus(m1)).toStrictEqual([[0, 1, "a"]]);
- });
- test("two disjoint set ops", function () {
- var m1 = new IntervalMap([], keyCmp, valueEq);
- var m2 = m1.copy().set(-2, -1, "a").set(1, 2, "b");
- expect(m2.minus(m1)).toStrictEqual([
- [-2, -1, "a"],
- [1, 2, "b"],
- ]);
- });
- test("two adjacent set ops", function () {
- var m1 = new IntervalMap([], keyCmp, valueEq);
- var m2 = m1.copy().set(-1, 0, "a").set(0, 1, "b");
- expect(m2.minus(m1)).toStrictEqual([
- [-1, 0, "a"],
- [0, 1, "b"],
- ]);
- });
- test("two adjacent set ops with the same value", function () {
- var m1 = new IntervalMap([], keyCmp, valueEq);
- var m2 = m1.copy().set(-1, 0, "a").set(0, 1, "a");
- expect(m2.minus(m1)).toStrictEqual([[-1, 1, "a"]]);
- });
- test("two intersecting set ops", function () {
- var m1 = new IntervalMap([], keyCmp, valueEq);
- var m2 = m1.copy().set(-2, 1, "a").set(-1, 2, "b");
- expect(m2.minus(m1)).toStrictEqual([
- [-2, -1, "a"],
- [-1, 2, "b"],
- ]);
- });
- test("two intersecting set ops in reverse order", function () {
- var m1 = new IntervalMap([], keyCmp, valueEq);
- var m2 = m1.copy().set(-1, 2, "b").set(-2, 1, "a");
- expect(m2.minus(m1)).toStrictEqual([
- [-2, 1, "a"],
- [1, 2, "b"],
- ]);
- });
- test("two intersecting set ops with same value", function () {
- var m1 = new IntervalMap([], keyCmp, valueEq);
- var m2 = m1.copy().set(-2, 1, "a").set(-1, 2, "a");
- expect(m2.minus(m1)).toStrictEqual([[-2, 2, "a"]]);
- });
- test("two intersecting set ops with same value in reverse order", function () {
- var m1 = new IntervalMap([], keyCmp, valueEq);
- var m2 = m1.copy().set(-1, 2, "a").set(-2, 1, "a");
- expect(m2.minus(m1)).toStrictEqual([[-2, 2, "a"]]);
- });
- test("set ops with no effect", function () {
- var m1 = new IntervalMap([
- [1, "a"],
- [2, "b"],
- ], keyCmp, valueEq);
- var m2 = m1.copy().set(1, 1.5, "a").set(3, 4, "b");
- expect(m2.minus(m1)).toStrictEqual([]);
- });
- test("one inexact set op", function () {
- var m1 = new IntervalMap([
- [1, "a"],
- [2, "b"],
- ], keyCmp, valueEq);
- var m2 = m1.copy().set(0, 1.5, "a");
- expect(m2.minus(m1)).toStrictEqual([[0, 1, "a"]]);
- });
- test("another inexact set op", function () {
- var m1 = new IntervalMap([
- [1, "a"],
- [2, "b"],
- ], keyCmp, valueEq);
- var m2 = m1.copy().set(1.5, 3, "b");
- expect(m2.minus(m1)).toStrictEqual([[1.5, 2, "b"]]);
- });
- test("one set on a base map with many steps", function () {
- var a = array(10);
- var m1 = new IntervalMap(a, keyCmp, valueEq);
- var m2 = m1.copy().set(0.5, 9, "a");
- expect(m2.minus(m1)).toStrictEqual([[1, 9, "a"]]);
- });
- test("multiple sets overwritten by a final set", function () {
- var m1 = new IntervalMap([[1, "a"]], keyCmp, valueEq);
- var m2 = m1
- .copy()
- .set(2, 3, "b")
- .set(3, 4, "c")
- .set(4, 5, "d")
- .set(1.5, 4, "a");
- expect(m2.minus(m1)).toStrictEqual([[4, 5, "d"]]);
- });
+ test("one set op", function () {
+ var m1 = new IntervalMap([], keyCmp, valueEq);
+ var m2 = m1.copy().set(0, 1, "a");
+ expect(m2.minus(m1)).toStrictEqual([[0, 1, "a"]]);
+ });
+ test("two disjoint set ops", function () {
+ var m1 = new IntervalMap([], keyCmp, valueEq);
+ var m2 = m1.copy().set(-2, -1, "a").set(1, 2, "b");
+ expect(m2.minus(m1)).toStrictEqual([
+ [-2, -1, "a"],
+ [1, 2, "b"],
+ ]);
+ });
+ test("two adjacent set ops", function () {
+ var m1 = new IntervalMap([], keyCmp, valueEq);
+ var m2 = m1.copy().set(-1, 0, "a").set(0, 1, "b");
+ expect(m2.minus(m1)).toStrictEqual([
+ [-1, 0, "a"],
+ [0, 1, "b"],
+ ]);
+ });
+ test("two adjacent set ops with the same value", function () {
+ var m1 = new IntervalMap([], keyCmp, valueEq);
+ var m2 = m1.copy().set(-1, 0, "a").set(0, 1, "a");
+ expect(m2.minus(m1)).toStrictEqual([[-1, 1, "a"]]);
+ });
+ test("two intersecting set ops", function () {
+ var m1 = new IntervalMap([], keyCmp, valueEq);
+ var m2 = m1.copy().set(-2, 1, "a").set(-1, 2, "b");
+ expect(m2.minus(m1)).toStrictEqual([
+ [-2, -1, "a"],
+ [-1, 2, "b"],
+ ]);
+ });
+ test("two intersecting set ops in reverse order", function () {
+ var m1 = new IntervalMap([], keyCmp, valueEq);
+ var m2 = m1.copy().set(-1, 2, "b").set(-2, 1, "a");
+ expect(m2.minus(m1)).toStrictEqual([
+ [-2, 1, "a"],
+ [1, 2, "b"],
+ ]);
+ });
+ test("two intersecting set ops with same value", function () {
+ var m1 = new IntervalMap([], keyCmp, valueEq);
+ var m2 = m1.copy().set(-2, 1, "a").set(-1, 2, "a");
+ expect(m2.minus(m1)).toStrictEqual([[-2, 2, "a"]]);
+ });
+ test("two intersecting set ops with same value in reverse order", function () {
+ var m1 = new IntervalMap([], keyCmp, valueEq);
+ var m2 = m1.copy().set(-1, 2, "a").set(-2, 1, "a");
+ expect(m2.minus(m1)).toStrictEqual([[-2, 2, "a"]]);
+ });
+ test("set ops with no effect", function () {
+ var m1 = new IntervalMap(
+ [
+ [1, "a"],
+ [2, "b"],
+ ],
+ keyCmp,
+ valueEq,
+ );
+ var m2 = m1.copy().set(1, 1.5, "a").set(3, 4, "b");
+ expect(m2.minus(m1)).toStrictEqual([]);
+ });
+ test("one inexact set op", function () {
+ var m1 = new IntervalMap(
+ [
+ [1, "a"],
+ [2, "b"],
+ ],
+ keyCmp,
+ valueEq,
+ );
+ var m2 = m1.copy().set(0, 1.5, "a");
+ expect(m2.minus(m1)).toStrictEqual([[0, 1, "a"]]);
+ });
+ test("another inexact set op", function () {
+ var m1 = new IntervalMap(
+ [
+ [1, "a"],
+ [2, "b"],
+ ],
+ keyCmp,
+ valueEq,
+ );
+ var m2 = m1.copy().set(1.5, 3, "b");
+ expect(m2.minus(m1)).toStrictEqual([[1.5, 2, "b"]]);
+ });
+ test("one set on a base map with many steps", function () {
+ var a = array(10);
+ var m1 = new IntervalMap(a, keyCmp, valueEq);
+ var m2 = m1.copy().set(0.5, 9, "a");
+ expect(m2.minus(m1)).toStrictEqual([[1, 9, "a"]]);
+ });
+ test("multiple sets overwritten by a final set", function () {
+ var m1 = new IntervalMap([[1, "a"]], keyCmp, valueEq);
+ var m2 = m1
+ .copy()
+ .set(2, 3, "b")
+ .set(3, 4, "c")
+ .set(4, 5, "d")
+ .set(1.5, 4, "a");
+ expect(m2.minus(m1)).toStrictEqual([[4, 5, "d"]]);
+ });
});
diff --git a/src/algorithms/Bisection.js b/src/algorithms/Bisection.js
index ecfd5ccf7..ec9eaf3ec 100644
--- a/src/algorithms/Bisection.js
+++ b/src/algorithms/Bisection.js
@@ -1,23 +1,25 @@
export function bisect(a, x, cmpToX, lo, hi, findRightMost) {
- if (lo === void 0) { lo = 0; }
- if (hi === void 0) { hi = a.length; }
- if (findRightMost === void 0) { findRightMost = false; }
- if (hi <= lo)
- return lo;
- if (hi === lo + 1) {
- var c_1 = cmpToX(a[lo]);
- if (c_1 < 0)
- return hi;
- if (c_1 > 0)
- return lo;
- if (c_1 === 0 && findRightMost)
- return hi;
- return lo;
- }
- var mid = Math.floor((lo + hi) / 2.0);
- var c = cmpToX(a[mid]);
- if (c < 0 || (c === 0 && findRightMost)) {
- return bisect(a, x, cmpToX, mid + 1, hi, findRightMost);
- }
- return bisect(a, x, cmpToX, lo, mid, findRightMost);
+ if (lo === void 0) {
+ lo = 0;
+ }
+ if (hi === void 0) {
+ hi = a.length;
+ }
+ if (findRightMost === void 0) {
+ findRightMost = false;
+ }
+ if (hi <= lo) return lo;
+ if (hi === lo + 1) {
+ var c_1 = cmpToX(a[lo]);
+ if (c_1 < 0) return hi;
+ if (c_1 > 0) return lo;
+ if (c_1 === 0 && findRightMost) return hi;
+ return lo;
+ }
+ var mid = Math.floor((lo + hi) / 2.0);
+ var c = cmpToX(a[mid]);
+ if (c < 0 || (c === 0 && findRightMost)) {
+ return bisect(a, x, cmpToX, mid + 1, hi, findRightMost);
+ }
+ return bisect(a, x, cmpToX, lo, mid, findRightMost);
}
diff --git a/src/algorithms/IntervalMap.js b/src/algorithms/IntervalMap.js
index 14fa45d19..3e67ec8d9 100644
--- a/src/algorithms/IntervalMap.js
+++ b/src/algorithms/IntervalMap.js
@@ -1,126 +1,167 @@
import { bisect } from "./Bisection";
function copyArray(array) {
- return array.map(function (element) { return [element[0], element[1]]; });
+ return array.map(function (element) {
+ return [element[0], element[1]];
+ });
}
var IntervalMap = (function () {
- function IntervalMap(array, keyCmp, valueEq) {
- this.array = [];
- var copy = copyArray(array);
- copy.sort(function (a, b) { return keyCmp(a[0], b[0]); });
- var prevValue;
- for (var _i = 0, copy_1 = copy; _i < copy_1.length; _i++) {
- var _a = copy_1[_i], key = _a[0], value = _a[1];
- if (!valueEq(value, prevValue)) {
- this.array.push([key, value]);
- prevValue = value;
- }
- }
- this.keyCmp = keyCmp;
- this.valueEq = valueEq;
+ function IntervalMap(array, keyCmp, valueEq) {
+ this.array = [];
+ var copy = copyArray(array);
+ copy.sort(function (a, b) {
+ return keyCmp(a[0], b[0]);
+ });
+ var prevValue;
+ for (var _i = 0, copy_1 = copy; _i < copy_1.length; _i++) {
+ var _a = copy_1[_i],
+ key = _a[0],
+ value = _a[1];
+ if (!valueEq(value, prevValue)) {
+ this.array.push([key, value]);
+ prevValue = value;
+ }
}
- IntervalMap.prototype.size = function () {
- return this.array.length;
- };
- IntervalMap.prototype.get = function (key) {
- var array = this.array;
- var n = array.length;
- var keyCmp = this.keyCmp;
- if (n === 0)
- return;
- var idx = bisect(array, key, function (a) { return keyCmp(a[0], key); }, 0, n, false);
- if (idx === n) {
- return array[idx - 1][1];
- }
- if (keyCmp(array[idx][0], key) === 0) {
- return array[idx][1];
- }
- if (idx > 0) {
- return array[idx - 1][1];
- }
- return;
- };
- IntervalMap.prototype.set = function (key1, key2, value) {
- var array = this.array;
- var n = array.length;
- var keyCmp = this.keyCmp;
- var valueEq = this.valueEq;
- if (keyCmp(key1, key2) >= 0)
- return this;
- if (n === 0) {
- array.push([key1, value], [key2, undefined]);
- return this;
- }
- var idx1 = bisect(array, key1, function (a) { return keyCmp(a[0], key1); }, 0, array.length, false);
- if (idx1 === n) {
- var v = array[n - 1][1];
- if (!valueEq(value, v)) {
- array.push([key1, value], [key2, v]);
- }
- return this;
- }
- var idx2 = bisect(array, key2, function (a) { return keyCmp(a[0], key2); }, 0, array.length, true) - 1;
- if (idx2 === -1) {
- if (!valueEq(value, undefined)) {
- array.splice(0, 0, [key1, value], [key2, undefined]);
- }
- return this;
- }
- var insert1 = !(idx1 > 0 && valueEq(array[idx1 - 1][1], value));
- var insert2 = !valueEq(array[idx2][1], value);
- if (insert1 && insert2) {
- array.splice(idx1, idx2 - idx1 + 1, [key1, value], [key2, array[idx2][1]]);
- }
- else if (insert1) {
- array.splice(idx1, idx2 - idx1 + 1, [key1, value]);
- }
- else if (insert2) {
- array.splice(idx1, idx2 - idx1 + 1, [key2, array[idx2][1]]);
- }
- else {
- array.splice(idx1, idx2 - idx1 + 1);
- }
- return this;
- };
- IntervalMap.prototype.keys = function () {
- return this.array.map(function (element) { return element[0]; });
- };
- IntervalMap.prototype.values = function () {
- return this.array.map(function (element) { return element[1]; });
- };
- IntervalMap.prototype.toArray = function () {
- return copyArray(this.array);
- };
- IntervalMap.prototype.copy = function () {
- return new IntervalMap(this.array, this.keyCmp, this.valueEq);
- };
- IntervalMap.prototype.minus = function (baseMap) {
- var _this = this;
- var keys = this.keys().concat(baseMap.keys());
- keys.sort(this.keyCmp);
- var equalValues = keys.map(function (key) {
- return _this.valueEq(_this.get(key), baseMap.get(key));
- });
- var idx = 0;
- var diff = [];
- while (idx + 1 < keys.length) {
- if (!equalValues[idx]) {
- diff.push([keys[idx], keys[idx + 1], this.get(keys[idx])]);
- }
- idx += 1;
- }
- var i = 0;
- var mergedDiff = [];
- while (i < diff.length) {
- var _a = diff[i], st = _a[0], en = _a[1], val = _a[2];
- while (i + 1 < diff.length && this.valueEq(diff[i][2], diff[i + 1][2])) {
- en = diff[i + 1][1];
- i += 1;
- }
- mergedDiff.push([st, en, val]);
- i += 1;
- }
- return mergedDiff;
- };
- return IntervalMap;
-}());
+ this.keyCmp = keyCmp;
+ this.valueEq = valueEq;
+ }
+ IntervalMap.prototype.size = function () {
+ return this.array.length;
+ };
+ IntervalMap.prototype.get = function (key) {
+ var array = this.array;
+ var n = array.length;
+ var keyCmp = this.keyCmp;
+ if (n === 0) return;
+ var idx = bisect(
+ array,
+ key,
+ function (a) {
+ return keyCmp(a[0], key);
+ },
+ 0,
+ n,
+ false,
+ );
+ if (idx === n) {
+ return array[idx - 1][1];
+ }
+ if (keyCmp(array[idx][0], key) === 0) {
+ return array[idx][1];
+ }
+ if (idx > 0) {
+ return array[idx - 1][1];
+ }
+ return;
+ };
+ IntervalMap.prototype.set = function (key1, key2, value) {
+ var array = this.array;
+ var n = array.length;
+ var keyCmp = this.keyCmp;
+ var valueEq = this.valueEq;
+ if (keyCmp(key1, key2) >= 0) return this;
+ if (n === 0) {
+ array.push([key1, value], [key2, undefined]);
+ return this;
+ }
+ var idx1 = bisect(
+ array,
+ key1,
+ function (a) {
+ return keyCmp(a[0], key1);
+ },
+ 0,
+ array.length,
+ false,
+ );
+ if (idx1 === n) {
+ var v = array[n - 1][1];
+ if (!valueEq(value, v)) {
+ array.push([key1, value], [key2, v]);
+ }
+ return this;
+ }
+ var idx2 =
+ bisect(
+ array,
+ key2,
+ function (a) {
+ return keyCmp(a[0], key2);
+ },
+ 0,
+ array.length,
+ true,
+ ) - 1;
+ if (idx2 === -1) {
+ if (!valueEq(value, undefined)) {
+ array.splice(0, 0, [key1, value], [key2, undefined]);
+ }
+ return this;
+ }
+ var insert1 = !(idx1 > 0 && valueEq(array[idx1 - 1][1], value));
+ var insert2 = !valueEq(array[idx2][1], value);
+ if (insert1 && insert2) {
+ array.splice(
+ idx1,
+ idx2 - idx1 + 1,
+ [key1, value],
+ [key2, array[idx2][1]],
+ );
+ } else if (insert1) {
+ array.splice(idx1, idx2 - idx1 + 1, [key1, value]);
+ } else if (insert2) {
+ array.splice(idx1, idx2 - idx1 + 1, [key2, array[idx2][1]]);
+ } else {
+ array.splice(idx1, idx2 - idx1 + 1);
+ }
+ return this;
+ };
+ IntervalMap.prototype.keys = function () {
+ return this.array.map(function (element) {
+ return element[0];
+ });
+ };
+ IntervalMap.prototype.values = function () {
+ return this.array.map(function (element) {
+ return element[1];
+ });
+ };
+ IntervalMap.prototype.toArray = function () {
+ return copyArray(this.array);
+ };
+ IntervalMap.prototype.copy = function () {
+ return new IntervalMap(this.array, this.keyCmp, this.valueEq);
+ };
+ IntervalMap.prototype.minus = function (baseMap) {
+ var _this = this;
+ var keys = this.keys().concat(baseMap.keys());
+ keys.sort(this.keyCmp);
+ var equalValues = keys.map(function (key) {
+ return _this.valueEq(_this.get(key), baseMap.get(key));
+ });
+ var idx = 0;
+ var diff = [];
+ while (idx + 1 < keys.length) {
+ if (!equalValues[idx]) {
+ diff.push([keys[idx], keys[idx + 1], this.get(keys[idx])]);
+ }
+ idx += 1;
+ }
+ var i = 0;
+ var mergedDiff = [];
+ while (i < diff.length) {
+ var _a = diff[i],
+ st = _a[0],
+ en = _a[1],
+ val = _a[2];
+ while (i + 1 < diff.length && this.valueEq(diff[i][2], diff[i + 1][2])) {
+ en = diff[i + 1][1];
+ i += 1;
+ }
+ mergedDiff.push([st, en, val]);
+ i += 1;
+ }
+ return mergedDiff;
+ };
+ return IntervalMap;
+})();
export { IntervalMap };
diff --git a/src/pages/policy/input/ParameterEditor.jsx b/src/pages/policy/input/ParameterEditor.jsx
index 8e6c54f1b..326286b36 100644
--- a/src/pages/policy/input/ParameterEditor.jsx
+++ b/src/pages/policy/input/ParameterEditor.jsx
@@ -45,7 +45,7 @@ const DATE_INPUT_MODES = {
DEFAULT: "default",
YEARLY: "yearly",
DATE: "date",
- MULTI_YEAR: "multi-year"
+ MULTI_YEAR: "multi-year",
};
export default function ParameterEditor(props) {
@@ -109,7 +109,10 @@ export default function ParameterEditor(props) {
description = "";
}
- const gridColumns = dateInputMode === DATE_INPUT_MODES.MULTI_YEAR ? "auto min-content" : "auto auto min-content";
+ const gridColumns =
+ dateInputMode === DATE_INPUT_MODES.MULTI_YEAR
+ ? "auto min-content"
+ : "auto auto min-content";
return (
- {
- dateInputMode !== DATE_INPUT_MODES.MULTI_YEAR && (
-
- )
- }
-
+ {dateInputMode !== DATE_INPUT_MODES.MULTI_YEAR && (
+
+ )}
+
{!parameter.economy && (
@@ -233,7 +232,7 @@ export default function ParameterEditor(props) {
}
function PeriodSetter(props) {
- const {
+ const {
inputMode,
metadata,
startDate,
@@ -243,9 +242,9 @@ function PeriodSetter(props) {
parameterName,
baseMap,
reformMap,
- policy
+ policy,
} = props;
-
+
const FOREVER_DATE = String(defaultForeverYear).concat("-12-31");
// Array of selectable years, sorted in ascending order
@@ -267,7 +266,7 @@ function PeriodSetter(props) {
maxPossibleDate,
isEndForever,
possibleYears,
- FOREVER_DATE
+ FOREVER_DATE,
};
const tenYearProps = {
@@ -275,7 +274,7 @@ function PeriodSetter(props) {
metadata,
baseMap,
reformMap,
- policy
+ policy,
};
switch (inputMode) {
@@ -291,13 +290,8 @@ function PeriodSetter(props) {
}
function DefaultPeriodSetter(props) {
- const {
- startDate,
- setStartDate,
- setEndDate,
- possibleYears,
- FOREVER_DATE
- } = props;
+ const { startDate, setStartDate, setEndDate, possibleYears, FOREVER_DATE } =
+ props;
let defaultStartYear = null;
if (startDate) {
@@ -324,7 +318,7 @@ function DefaultPeriodSetter(props) {
const options = possibleYears.map((year) => {
return {
label: year,
- value: year
+ value: year,
};
});
@@ -339,23 +333,30 @@ function DefaultPeriodSetter(props) {
// The below keeps the font in line with
// the selector components
fontSize: "14px",
- gap: "10px"
+ gap: "10px",
}}
>
-