Create interface to govern all Intensity classes
This commit is contained in:
parent
12b848f08d
commit
53344b22ce
|
|
@ -1,4 +1,10 @@
|
||||||
export class Intensity {
|
export interface Intensity {
|
||||||
|
readonly value: number;
|
||||||
|
readonly start: number;
|
||||||
|
readonly end: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ConstantIntensity implements Intensity {
|
||||||
constructor(private _value: number) {}
|
constructor(private _value: number) {}
|
||||||
|
|
||||||
get value() {
|
get value() {
|
||||||
|
|
@ -14,7 +20,7 @@ export class Intensity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class IntensityRange {
|
export class RangeIntensity implements Intensity {
|
||||||
constructor(private _start: number, private _end: number) {}
|
constructor(private _start: number, private _end: number) {}
|
||||||
|
|
||||||
get value() {
|
get value() {
|
||||||
|
|
@ -30,7 +36,7 @@ export class IntensityRange {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class FreeIntensity {
|
export class FreeIntensity implements Intensity {
|
||||||
get value() {
|
get value() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { IntervalType } from "./parser/tokenizer";
|
import { IntervalType } from "./parser/tokenizer";
|
||||||
import { Duration } from "./Duration";
|
import { Duration } from "./Duration";
|
||||||
import { FreeIntensity, Intensity, IntensityRange } from "./Intensity";
|
import { Intensity } from "./Intensity";
|
||||||
|
|
||||||
export type Workout = {
|
export type Workout = {
|
||||||
name: string;
|
name: string;
|
||||||
|
|
@ -12,7 +12,7 @@ export type Workout = {
|
||||||
export type Interval = {
|
export type Interval = {
|
||||||
type: IntervalType;
|
type: IntervalType;
|
||||||
duration: Duration;
|
duration: Duration;
|
||||||
intensity: Intensity | IntensityRange | FreeIntensity;
|
intensity: Intensity;
|
||||||
cadence?: number;
|
cadence?: number;
|
||||||
comments: Comment[];
|
comments: Comment[];
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { Interval } from "./ast";
|
import { Interval } from "./ast";
|
||||||
import { detectRepeats } from "./detectRepeats";
|
import { detectRepeats } from "./detectRepeats";
|
||||||
import { Duration } from "./Duration";
|
import { Duration } from "./Duration";
|
||||||
import { Intensity, IntensityRange } from "./Intensity";
|
import { ConstantIntensity, RangeIntensity } from "./Intensity";
|
||||||
|
|
||||||
describe("detectRepeats()", () => {
|
describe("detectRepeats()", () => {
|
||||||
it("does nothing with empty array", () => {
|
it("does nothing with empty array", () => {
|
||||||
|
|
@ -10,32 +10,32 @@ describe("detectRepeats()", () => {
|
||||||
|
|
||||||
it("does nothing when no interval repeats", () => {
|
it("does nothing when no interval repeats", () => {
|
||||||
const intervals: Interval[] = [
|
const intervals: Interval[] = [
|
||||||
{ type: "Rest", duration: new Duration(60), intensity: new Intensity(0.5), comments: [] },
|
{ type: "Rest", duration: new Duration(60), intensity: new ConstantIntensity(0.5), comments: [] },
|
||||||
{ type: "Interval", duration: new Duration(60), intensity: new Intensity(1), comments: [] },
|
{ type: "Interval", duration: new Duration(60), intensity: new ConstantIntensity(1), comments: [] },
|
||||||
{ type: "Interval", duration: new Duration(30), intensity: new Intensity(1.2), comments: [] },
|
{ type: "Interval", duration: new Duration(30), intensity: new ConstantIntensity(1.2), comments: [] },
|
||||||
{ type: "Cooldown", duration: new Duration(60), intensity: new Intensity(1), comments: [] },
|
{ type: "Cooldown", duration: new Duration(60), intensity: new ConstantIntensity(1), comments: [] },
|
||||||
];
|
];
|
||||||
expect(detectRepeats(intervals)).toEqual(intervals);
|
expect(detectRepeats(intervals)).toEqual(intervals);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("detects whole workout consisting of repetitions", () => {
|
it("detects whole workout consisting of repetitions", () => {
|
||||||
const intervals: Interval[] = [
|
const intervals: Interval[] = [
|
||||||
{ type: "Interval", duration: new Duration(120), intensity: new Intensity(1), comments: [] },
|
{ type: "Interval", duration: new Duration(120), intensity: new ConstantIntensity(1), comments: [] },
|
||||||
{ type: "Rest", duration: new Duration(60), intensity: new Intensity(0.5), comments: [] },
|
{ type: "Rest", duration: new Duration(60), intensity: new ConstantIntensity(0.5), comments: [] },
|
||||||
{ type: "Interval", duration: new Duration(120), intensity: new Intensity(1), comments: [] },
|
{ type: "Interval", duration: new Duration(120), intensity: new ConstantIntensity(1), comments: [] },
|
||||||
{ type: "Rest", duration: new Duration(60), intensity: new Intensity(0.5), comments: [] },
|
{ type: "Rest", duration: new Duration(60), intensity: new ConstantIntensity(0.5), comments: [] },
|
||||||
{ type: "Interval", duration: new Duration(120), intensity: new Intensity(1), comments: [] },
|
{ type: "Interval", duration: new Duration(120), intensity: new ConstantIntensity(1), comments: [] },
|
||||||
{ type: "Rest", duration: new Duration(60), intensity: new Intensity(0.5), comments: [] },
|
{ type: "Rest", duration: new Duration(60), intensity: new ConstantIntensity(0.5), comments: [] },
|
||||||
{ type: "Interval", duration: new Duration(120), intensity: new Intensity(1), comments: [] },
|
{ type: "Interval", duration: new Duration(120), intensity: new ConstantIntensity(1), comments: [] },
|
||||||
{ type: "Rest", duration: new Duration(60), intensity: new Intensity(0.5), comments: [] },
|
{ type: "Rest", duration: new Duration(60), intensity: new ConstantIntensity(0.5), comments: [] },
|
||||||
];
|
];
|
||||||
expect(detectRepeats(intervals)).toEqual([
|
expect(detectRepeats(intervals)).toEqual([
|
||||||
{
|
{
|
||||||
type: "repeat",
|
type: "repeat",
|
||||||
times: 4,
|
times: 4,
|
||||||
intervals: [
|
intervals: [
|
||||||
{ type: "Interval", duration: new Duration(120), intensity: new Intensity(1), comments: [] },
|
{ type: "Interval", duration: new Duration(120), intensity: new ConstantIntensity(1), comments: [] },
|
||||||
{ type: "Rest", duration: new Duration(60), intensity: new Intensity(0.5), comments: [] },
|
{ type: "Rest", duration: new Duration(60), intensity: new ConstantIntensity(0.5), comments: [] },
|
||||||
],
|
],
|
||||||
comments: [],
|
comments: [],
|
||||||
},
|
},
|
||||||
|
|
@ -44,54 +44,54 @@ describe("detectRepeats()", () => {
|
||||||
|
|
||||||
it("detects repetitions in the middle of workout", () => {
|
it("detects repetitions in the middle of workout", () => {
|
||||||
const intervals: Interval[] = [
|
const intervals: Interval[] = [
|
||||||
{ type: "Warmup", duration: new Duration(60), intensity: new IntensityRange(0.5, 1), comments: [] },
|
{ type: "Warmup", duration: new Duration(60), intensity: new RangeIntensity(0.5, 1), comments: [] },
|
||||||
{ type: "Rest", duration: new Duration(120), intensity: new Intensity(0.2), comments: [] },
|
{ type: "Rest", duration: new Duration(120), intensity: new ConstantIntensity(0.2), comments: [] },
|
||||||
{ type: "Interval", duration: new Duration(60), intensity: new Intensity(1), comments: [] },
|
{ type: "Interval", duration: new Duration(60), intensity: new ConstantIntensity(1), comments: [] },
|
||||||
{ type: "Rest", duration: new Duration(60), intensity: new Intensity(0.5), comments: [] },
|
{ type: "Rest", duration: new Duration(60), intensity: new ConstantIntensity(0.5), comments: [] },
|
||||||
{ type: "Interval", duration: new Duration(60), intensity: new Intensity(1), comments: [] },
|
{ type: "Interval", duration: new Duration(60), intensity: new ConstantIntensity(1), comments: [] },
|
||||||
{ type: "Rest", duration: new Duration(60), intensity: new Intensity(0.5), comments: [] },
|
{ type: "Rest", duration: new Duration(60), intensity: new ConstantIntensity(0.5), comments: [] },
|
||||||
{ type: "Interval", duration: new Duration(60), intensity: new Intensity(1), comments: [] },
|
{ type: "Interval", duration: new Duration(60), intensity: new ConstantIntensity(1), comments: [] },
|
||||||
{ type: "Rest", duration: new Duration(60), intensity: new Intensity(0.5), comments: [] },
|
{ type: "Rest", duration: new Duration(60), intensity: new ConstantIntensity(0.5), comments: [] },
|
||||||
{ type: "Interval", duration: new Duration(60), intensity: new Intensity(1), comments: [] },
|
{ type: "Interval", duration: new Duration(60), intensity: new ConstantIntensity(1), comments: [] },
|
||||||
{ type: "Rest", duration: new Duration(60), intensity: new Intensity(0.5), comments: [] },
|
{ type: "Rest", duration: new Duration(60), intensity: new ConstantIntensity(0.5), comments: [] },
|
||||||
{ type: "Rest", duration: new Duration(120), intensity: new Intensity(0.2), comments: [] },
|
{ type: "Rest", duration: new Duration(120), intensity: new ConstantIntensity(0.2), comments: [] },
|
||||||
{ type: "Cooldown", duration: new Duration(60), intensity: new IntensityRange(1, 0.5), comments: [] },
|
{ type: "Cooldown", duration: new Duration(60), intensity: new RangeIntensity(1, 0.5), comments: [] },
|
||||||
];
|
];
|
||||||
expect(detectRepeats(intervals)).toEqual([
|
expect(detectRepeats(intervals)).toEqual([
|
||||||
{ type: "Warmup", duration: new Duration(60), intensity: new IntensityRange(0.5, 1), comments: [] },
|
{ type: "Warmup", duration: new Duration(60), intensity: new RangeIntensity(0.5, 1), comments: [] },
|
||||||
{ type: "Rest", duration: new Duration(120), intensity: new Intensity(0.2), comments: [] },
|
{ type: "Rest", duration: new Duration(120), intensity: new ConstantIntensity(0.2), comments: [] },
|
||||||
{
|
{
|
||||||
type: "repeat",
|
type: "repeat",
|
||||||
times: 4,
|
times: 4,
|
||||||
intervals: [
|
intervals: [
|
||||||
{ type: "Interval", duration: new Duration(60), intensity: new Intensity(1), comments: [] },
|
{ type: "Interval", duration: new Duration(60), intensity: new ConstantIntensity(1), comments: [] },
|
||||||
{ type: "Rest", duration: new Duration(60), intensity: new Intensity(0.5), comments: [] },
|
{ type: "Rest", duration: new Duration(60), intensity: new ConstantIntensity(0.5), comments: [] },
|
||||||
],
|
],
|
||||||
comments: [],
|
comments: [],
|
||||||
},
|
},
|
||||||
{ type: "Rest", duration: new Duration(120), intensity: new Intensity(0.2), comments: [] },
|
{ type: "Rest", duration: new Duration(120), intensity: new ConstantIntensity(0.2), comments: [] },
|
||||||
{ type: "Cooldown", duration: new Duration(60), intensity: new IntensityRange(1, 0.5), comments: [] },
|
{ type: "Cooldown", duration: new Duration(60), intensity: new RangeIntensity(1, 0.5), comments: [] },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("detects multiple repetitions", () => {
|
it("detects multiple repetitions", () => {
|
||||||
const intervals: Interval[] = [
|
const intervals: Interval[] = [
|
||||||
{ type: "Interval", duration: new Duration(60), intensity: new Intensity(1), comments: [] },
|
{ type: "Interval", duration: new Duration(60), intensity: new ConstantIntensity(1), comments: [] },
|
||||||
{ type: "Rest", duration: new Duration(60), intensity: new Intensity(0.5), comments: [] },
|
{ type: "Rest", duration: new Duration(60), intensity: new ConstantIntensity(0.5), comments: [] },
|
||||||
{ type: "Interval", duration: new Duration(60), intensity: new Intensity(1), comments: [] },
|
{ type: "Interval", duration: new Duration(60), intensity: new ConstantIntensity(1), comments: [] },
|
||||||
{ type: "Rest", duration: new Duration(60), intensity: new Intensity(0.5), comments: [] },
|
{ type: "Rest", duration: new Duration(60), intensity: new ConstantIntensity(0.5), comments: [] },
|
||||||
{ type: "Interval", duration: new Duration(100), intensity: new Intensity(1), comments: [] },
|
{ type: "Interval", duration: new Duration(100), intensity: new ConstantIntensity(1), comments: [] },
|
||||||
{ type: "Rest", duration: new Duration(100), intensity: new Intensity(0.5), comments: [] },
|
{ type: "Rest", duration: new Duration(100), intensity: new ConstantIntensity(0.5), comments: [] },
|
||||||
{ type: "Interval", duration: new Duration(100), intensity: new Intensity(1), comments: [] },
|
{ type: "Interval", duration: new Duration(100), intensity: new ConstantIntensity(1), comments: [] },
|
||||||
{ type: "Rest", duration: new Duration(100), intensity: new Intensity(0.5), comments: [] },
|
{ type: "Rest", duration: new Duration(100), intensity: new ConstantIntensity(0.5), comments: [] },
|
||||||
];
|
];
|
||||||
expect(detectRepeats(intervals)).toEqual([
|
expect(detectRepeats(intervals)).toEqual([
|
||||||
{
|
{
|
||||||
type: "repeat",
|
type: "repeat",
|
||||||
times: 2,
|
times: 2,
|
||||||
intervals: [
|
intervals: [
|
||||||
{ type: "Interval", duration: new Duration(60), intensity: new Intensity(1), comments: [] },
|
{ type: "Interval", duration: new Duration(60), intensity: new ConstantIntensity(1), comments: [] },
|
||||||
{ type: "Rest", duration: new Duration(60), intensity: new Intensity(0.5), comments: [] },
|
{ type: "Rest", duration: new Duration(60), intensity: new ConstantIntensity(0.5), comments: [] },
|
||||||
],
|
],
|
||||||
comments: [],
|
comments: [],
|
||||||
},
|
},
|
||||||
|
|
@ -99,8 +99,8 @@ describe("detectRepeats()", () => {
|
||||||
type: "repeat",
|
type: "repeat",
|
||||||
times: 2,
|
times: 2,
|
||||||
intervals: [
|
intervals: [
|
||||||
{ type: "Interval", duration: new Duration(100), intensity: new Intensity(1), comments: [] },
|
{ type: "Interval", duration: new Duration(100), intensity: new ConstantIntensity(1), comments: [] },
|
||||||
{ type: "Rest", duration: new Duration(100), intensity: new Intensity(0.5), comments: [] },
|
{ type: "Rest", duration: new Duration(100), intensity: new ConstantIntensity(0.5), comments: [] },
|
||||||
],
|
],
|
||||||
comments: [],
|
comments: [],
|
||||||
},
|
},
|
||||||
|
|
@ -109,22 +109,46 @@ describe("detectRepeats()", () => {
|
||||||
|
|
||||||
it("takes cadence differences into account", () => {
|
it("takes cadence differences into account", () => {
|
||||||
const intervals: Interval[] = [
|
const intervals: Interval[] = [
|
||||||
{ type: "Interval", duration: new Duration(120), intensity: new Intensity(1), comments: [] },
|
{ type: "Interval", duration: new Duration(120), intensity: new ConstantIntensity(1), comments: [] },
|
||||||
{ type: "Rest", duration: new Duration(60), intensity: new Intensity(0.5), comments: [] },
|
{ type: "Rest", duration: new Duration(60), intensity: new ConstantIntensity(0.5), comments: [] },
|
||||||
{ type: "Interval", duration: new Duration(120), intensity: new Intensity(1), cadence: 100, comments: [] },
|
{
|
||||||
{ type: "Rest", duration: new Duration(60), intensity: new Intensity(0.5), cadence: 80, comments: [] },
|
type: "Interval",
|
||||||
{ type: "Interval", duration: new Duration(120), intensity: new Intensity(1), cadence: 100, comments: [] },
|
duration: new Duration(120),
|
||||||
{ type: "Rest", duration: new Duration(60), intensity: new Intensity(0.5), cadence: 80, comments: [] },
|
intensity: new ConstantIntensity(1),
|
||||||
|
cadence: 100,
|
||||||
|
comments: [],
|
||||||
|
},
|
||||||
|
{ type: "Rest", duration: new Duration(60), intensity: new ConstantIntensity(0.5), cadence: 80, comments: [] },
|
||||||
|
{
|
||||||
|
type: "Interval",
|
||||||
|
duration: new Duration(120),
|
||||||
|
intensity: new ConstantIntensity(1),
|
||||||
|
cadence: 100,
|
||||||
|
comments: [],
|
||||||
|
},
|
||||||
|
{ type: "Rest", duration: new Duration(60), intensity: new ConstantIntensity(0.5), cadence: 80, comments: [] },
|
||||||
];
|
];
|
||||||
expect(detectRepeats(intervals)).toEqual([
|
expect(detectRepeats(intervals)).toEqual([
|
||||||
{ type: "Interval", duration: new Duration(120), intensity: new Intensity(1), comments: [] },
|
{ type: "Interval", duration: new Duration(120), intensity: new ConstantIntensity(1), comments: [] },
|
||||||
{ type: "Rest", duration: new Duration(60), intensity: new Intensity(0.5), comments: [] },
|
{ type: "Rest", duration: new Duration(60), intensity: new ConstantIntensity(0.5), comments: [] },
|
||||||
{
|
{
|
||||||
type: "repeat",
|
type: "repeat",
|
||||||
times: 2,
|
times: 2,
|
||||||
intervals: [
|
intervals: [
|
||||||
{ type: "Interval", duration: new Duration(120), intensity: new Intensity(1), cadence: 100, comments: [] },
|
{
|
||||||
{ type: "Rest", duration: new Duration(60), intensity: new Intensity(0.5), cadence: 80, comments: [] },
|
type: "Interval",
|
||||||
|
duration: new Duration(120),
|
||||||
|
intensity: new ConstantIntensity(1),
|
||||||
|
cadence: 100,
|
||||||
|
comments: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "Rest",
|
||||||
|
duration: new Duration(60),
|
||||||
|
intensity: new ConstantIntensity(0.5),
|
||||||
|
cadence: 80,
|
||||||
|
comments: [],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
comments: [],
|
comments: [],
|
||||||
},
|
},
|
||||||
|
|
@ -133,14 +157,14 @@ describe("detectRepeats()", () => {
|
||||||
|
|
||||||
it("does not consider warmup/cooldown-range intervals to be repeatable", () => {
|
it("does not consider warmup/cooldown-range intervals to be repeatable", () => {
|
||||||
const intervals: Interval[] = [
|
const intervals: Interval[] = [
|
||||||
{ type: "Warmup", duration: new Duration(60), intensity: new IntensityRange(0.1, 1), comments: [] },
|
{ type: "Warmup", duration: new Duration(60), intensity: new RangeIntensity(0.1, 1), comments: [] },
|
||||||
{ type: "Cooldown", duration: new Duration(120), intensity: new IntensityRange(1, 0.5), comments: [] },
|
{ type: "Cooldown", duration: new Duration(120), intensity: new RangeIntensity(1, 0.5), comments: [] },
|
||||||
{ type: "Warmup", duration: new Duration(60), intensity: new IntensityRange(0.1, 1), comments: [] },
|
{ type: "Warmup", duration: new Duration(60), intensity: new RangeIntensity(0.1, 1), comments: [] },
|
||||||
{ type: "Cooldown", duration: new Duration(120), intensity: new IntensityRange(1, 0.5), comments: [] },
|
{ type: "Cooldown", duration: new Duration(120), intensity: new RangeIntensity(1, 0.5), comments: [] },
|
||||||
{ type: "Warmup", duration: new Duration(60), intensity: new IntensityRange(0.1, 1), comments: [] },
|
{ type: "Warmup", duration: new Duration(60), intensity: new RangeIntensity(0.1, 1), comments: [] },
|
||||||
{ type: "Cooldown", duration: new Duration(120), intensity: new IntensityRange(1, 0.5), comments: [] },
|
{ type: "Cooldown", duration: new Duration(120), intensity: new RangeIntensity(1, 0.5), comments: [] },
|
||||||
{ type: "Warmup", duration: new Duration(60), intensity: new IntensityRange(0.1, 1), comments: [] },
|
{ type: "Warmup", duration: new Duration(60), intensity: new RangeIntensity(0.1, 1), comments: [] },
|
||||||
{ type: "Cooldown", duration: new Duration(120), intensity: new IntensityRange(1, 0.5), comments: [] },
|
{ type: "Cooldown", duration: new Duration(120), intensity: new RangeIntensity(1, 0.5), comments: [] },
|
||||||
];
|
];
|
||||||
expect(detectRepeats(intervals)).toEqual(intervals);
|
expect(detectRepeats(intervals)).toEqual(intervals);
|
||||||
});
|
});
|
||||||
|
|
@ -150,7 +174,7 @@ describe("detectRepeats()", () => {
|
||||||
{
|
{
|
||||||
type: "Interval",
|
type: "Interval",
|
||||||
duration: new Duration(100),
|
duration: new Duration(100),
|
||||||
intensity: new Intensity(1),
|
intensity: new ConstantIntensity(1),
|
||||||
comments: [
|
comments: [
|
||||||
{ offset: new Duration(0), text: "Let's start" },
|
{ offset: new Duration(0), text: "Let's start" },
|
||||||
{ offset: new Duration(20), text: "Stay strong!" },
|
{ offset: new Duration(20), text: "Stay strong!" },
|
||||||
|
|
@ -160,7 +184,7 @@ describe("detectRepeats()", () => {
|
||||||
{
|
{
|
||||||
type: "Rest",
|
type: "Rest",
|
||||||
duration: new Duration(100),
|
duration: new Duration(100),
|
||||||
intensity: new Intensity(0.5),
|
intensity: new ConstantIntensity(0.5),
|
||||||
comments: [
|
comments: [
|
||||||
{ offset: new Duration(0), text: "Huh... have a rest" },
|
{ offset: new Duration(0), text: "Huh... have a rest" },
|
||||||
{ offset: new Duration(80), text: "Ready for next?" },
|
{ offset: new Duration(80), text: "Ready for next?" },
|
||||||
|
|
@ -169,7 +193,7 @@ describe("detectRepeats()", () => {
|
||||||
{
|
{
|
||||||
type: "Interval",
|
type: "Interval",
|
||||||
duration: new Duration(100),
|
duration: new Duration(100),
|
||||||
intensity: new Intensity(1),
|
intensity: new ConstantIntensity(1),
|
||||||
comments: [
|
comments: [
|
||||||
{ offset: new Duration(0), text: "Bring it on again!" },
|
{ offset: new Duration(0), text: "Bring it on again!" },
|
||||||
{ offset: new Duration(50), text: "Half way" },
|
{ offset: new Duration(50), text: "Half way" },
|
||||||
|
|
@ -179,7 +203,7 @@ describe("detectRepeats()", () => {
|
||||||
{
|
{
|
||||||
type: "Rest",
|
type: "Rest",
|
||||||
duration: new Duration(100),
|
duration: new Duration(100),
|
||||||
intensity: new Intensity(0.5),
|
intensity: new ConstantIntensity(0.5),
|
||||||
comments: [
|
comments: [
|
||||||
{ offset: new Duration(30), text: "Wow... you did it!" },
|
{ offset: new Duration(30), text: "Wow... you did it!" },
|
||||||
{ offset: new Duration(40), text: "Nice job." },
|
{ offset: new Duration(40), text: "Nice job." },
|
||||||
|
|
@ -192,8 +216,8 @@ describe("detectRepeats()", () => {
|
||||||
type: "repeat",
|
type: "repeat",
|
||||||
times: 2,
|
times: 2,
|
||||||
intervals: [
|
intervals: [
|
||||||
{ type: "Interval", duration: new Duration(100), intensity: new Intensity(1), comments: [] },
|
{ type: "Interval", duration: new Duration(100), intensity: new ConstantIntensity(1), comments: [] },
|
||||||
{ type: "Rest", duration: new Duration(100), intensity: new Intensity(0.5), comments: [] },
|
{ type: "Rest", duration: new Duration(100), intensity: new ConstantIntensity(0.5), comments: [] },
|
||||||
],
|
],
|
||||||
comments: [
|
comments: [
|
||||||
{ offset: new Duration(0), text: "Let's start" },
|
{ offset: new Duration(0), text: "Let's start" },
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { eqProps, flatten, zip } from "ramda";
|
import { eqProps, flatten, zip } from "ramda";
|
||||||
import { Interval, Comment } from "./ast";
|
import { Interval, Comment } from "./ast";
|
||||||
import { Duration } from "./Duration";
|
import { Duration } from "./Duration";
|
||||||
import { IntensityRange } from "./Intensity";
|
import { RangeIntensity } from "./Intensity";
|
||||||
|
|
||||||
export type RepeatedInterval = {
|
export type RepeatedInterval = {
|
||||||
type: "repeat";
|
type: "repeat";
|
||||||
|
|
@ -70,7 +70,7 @@ const extractRepeatedInterval = (intervals: Interval[], i: number): RepeatedInte
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const isRangeInterval = (interval: Interval): boolean => interval.intensity instanceof IntensityRange;
|
const isRangeInterval = (interval: Interval): boolean => interval.intensity instanceof RangeIntensity;
|
||||||
|
|
||||||
export const detectRepeats = (intervals: Interval[]): (Interval | RepeatedInterval)[] => {
|
export const detectRepeats = (intervals: Interval[]): (Interval | RepeatedInterval)[] => {
|
||||||
if (intervals.length < windowSize) {
|
if (intervals.length < windowSize) {
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ export { parseCliOptions } from "./parseCliOptions";
|
||||||
// types
|
// types
|
||||||
export { Workout, Interval, Comment } from "./ast";
|
export { Workout, Interval, Comment } from "./ast";
|
||||||
export { Duration } from "./Duration";
|
export { Duration } from "./Duration";
|
||||||
export { Intensity, IntensityRange, FreeIntensity } from "./Intensity";
|
export { Intensity, ConstantIntensity, RangeIntensity, FreeIntensity } from "./Intensity";
|
||||||
|
|
||||||
// stats utils
|
// stats utils
|
||||||
export { totalDuration } from "./stats/totalDuration";
|
export { totalDuration } from "./stats/totalDuration";
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ Rest: 5:00 45%
|
||||||
"duration": Duration {
|
"duration": Duration {
|
||||||
"seconds": 300,
|
"seconds": 300,
|
||||||
},
|
},
|
||||||
"intensity": Intensity {
|
"intensity": ConstantIntensity {
|
||||||
"_value": 0.5,
|
"_value": 0.5,
|
||||||
},
|
},
|
||||||
"type": "Rest",
|
"type": "Rest",
|
||||||
|
|
@ -85,7 +85,7 @@ Rest: 5:00 45%
|
||||||
"duration": Duration {
|
"duration": Duration {
|
||||||
"seconds": 600,
|
"seconds": 600,
|
||||||
},
|
},
|
||||||
"intensity": Intensity {
|
"intensity": ConstantIntensity {
|
||||||
"_value": 0.8,
|
"_value": 0.8,
|
||||||
},
|
},
|
||||||
"type": "Interval",
|
"type": "Interval",
|
||||||
|
|
@ -96,7 +96,7 @@ Rest: 5:00 45%
|
||||||
"duration": Duration {
|
"duration": Duration {
|
||||||
"seconds": 300,
|
"seconds": 300,
|
||||||
},
|
},
|
||||||
"intensity": Intensity {
|
"intensity": ConstantIntensity {
|
||||||
"_value": 0.45,
|
"_value": 0.45,
|
||||||
},
|
},
|
||||||
"type": "Rest",
|
"type": "Rest",
|
||||||
|
|
@ -136,7 +136,7 @@ Interval: 5:00 50%
|
||||||
"duration": Duration {
|
"duration": Duration {
|
||||||
"seconds": 300,
|
"seconds": 300,
|
||||||
},
|
},
|
||||||
"intensity": Intensity {
|
"intensity": ConstantIntensity {
|
||||||
"_value": 0.5,
|
"_value": 0.5,
|
||||||
},
|
},
|
||||||
"type": "Interval",
|
"type": "Interval",
|
||||||
|
|
@ -147,7 +147,7 @@ Interval: 5:00 50%
|
||||||
"duration": Duration {
|
"duration": Duration {
|
||||||
"seconds": 600,
|
"seconds": 600,
|
||||||
},
|
},
|
||||||
"intensity": Intensity {
|
"intensity": ConstantIntensity {
|
||||||
"_value": 1,
|
"_value": 1,
|
||||||
},
|
},
|
||||||
"type": "Interval",
|
"type": "Interval",
|
||||||
|
|
@ -158,7 +158,7 @@ Interval: 5:00 50%
|
||||||
"duration": Duration {
|
"duration": Duration {
|
||||||
"seconds": 300,
|
"seconds": 300,
|
||||||
},
|
},
|
||||||
"intensity": Intensity {
|
"intensity": ConstantIntensity {
|
||||||
"_value": 0.5,
|
"_value": 0.5,
|
||||||
},
|
},
|
||||||
"type": "Interval",
|
"type": "Interval",
|
||||||
|
|
@ -185,7 +185,7 @@ Cooldown: 5:30 70%..45%
|
||||||
"duration": Duration {
|
"duration": Duration {
|
||||||
"seconds": 330,
|
"seconds": 330,
|
||||||
},
|
},
|
||||||
"intensity": IntensityRange {
|
"intensity": RangeIntensity {
|
||||||
"_end": 0.8,
|
"_end": 0.8,
|
||||||
"_start": 0.5,
|
"_start": 0.5,
|
||||||
},
|
},
|
||||||
|
|
@ -197,7 +197,7 @@ Cooldown: 5:30 70%..45%
|
||||||
"duration": Duration {
|
"duration": Duration {
|
||||||
"seconds": 330,
|
"seconds": 330,
|
||||||
},
|
},
|
||||||
"intensity": IntensityRange {
|
"intensity": RangeIntensity {
|
||||||
"_end": 0.45,
|
"_end": 0.45,
|
||||||
"_start": 0.7,
|
"_start": 0.7,
|
||||||
},
|
},
|
||||||
|
|
@ -251,7 +251,7 @@ FreeRide: 5:00
|
||||||
"duration": Duration {
|
"duration": Duration {
|
||||||
"seconds": 10,
|
"seconds": 10,
|
||||||
},
|
},
|
||||||
"intensity": Intensity {
|
"intensity": ConstantIntensity {
|
||||||
"_value": 0.5,
|
"_value": 0.5,
|
||||||
},
|
},
|
||||||
"type": "Interval",
|
"type": "Interval",
|
||||||
|
|
@ -264,7 +264,7 @@ FreeRide: 5:00
|
||||||
"duration": Duration {
|
"duration": Duration {
|
||||||
"seconds": 10,
|
"seconds": 10,
|
||||||
},
|
},
|
||||||
"intensity": Intensity {
|
"intensity": ConstantIntensity {
|
||||||
"_value": 0.5,
|
"_value": 0.5,
|
||||||
},
|
},
|
||||||
"type": "Interval",
|
"type": "Interval",
|
||||||
|
|
@ -277,7 +277,7 @@ FreeRide: 5:00
|
||||||
"duration": Duration {
|
"duration": Duration {
|
||||||
"seconds": 10,
|
"seconds": 10,
|
||||||
},
|
},
|
||||||
"intensity": Intensity {
|
"intensity": ConstantIntensity {
|
||||||
"_value": 0.5,
|
"_value": 0.5,
|
||||||
},
|
},
|
||||||
"type": "Interval",
|
"type": "Interval",
|
||||||
|
|
@ -293,7 +293,7 @@ FreeRide: 5:00
|
||||||
"duration": Duration {
|
"duration": Duration {
|
||||||
"seconds": 10,
|
"seconds": 10,
|
||||||
},
|
},
|
||||||
"intensity": Intensity {
|
"intensity": ConstantIntensity {
|
||||||
"_value": 0.5,
|
"_value": 0.5,
|
||||||
},
|
},
|
||||||
"type": "Interval",
|
"type": "Interval",
|
||||||
|
|
@ -306,7 +306,7 @@ FreeRide: 5:00
|
||||||
"duration": Duration {
|
"duration": Duration {
|
||||||
"seconds": 10,
|
"seconds": 10,
|
||||||
},
|
},
|
||||||
"intensity": Intensity {
|
"intensity": ConstantIntensity {
|
||||||
"_value": 0.5,
|
"_value": 0.5,
|
||||||
},
|
},
|
||||||
"type": "Interval",
|
"type": "Interval",
|
||||||
|
|
@ -417,7 +417,7 @@ Rest: 5:00 50%
|
||||||
"duration": Duration {
|
"duration": Duration {
|
||||||
"seconds": 600,
|
"seconds": 600,
|
||||||
},
|
},
|
||||||
"intensity": Intensity {
|
"intensity": ConstantIntensity {
|
||||||
"_value": 0.9,
|
"_value": 0.9,
|
||||||
},
|
},
|
||||||
"type": "Interval",
|
"type": "Interval",
|
||||||
|
|
@ -441,7 +441,7 @@ Rest: 5:00 50%
|
||||||
"duration": Duration {
|
"duration": Duration {
|
||||||
"seconds": 300,
|
"seconds": 300,
|
||||||
},
|
},
|
||||||
"intensity": Intensity {
|
"intensity": ConstantIntensity {
|
||||||
"_value": 0.5,
|
"_value": 0.5,
|
||||||
},
|
},
|
||||||
"type": "Rest",
|
"type": "Rest",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { Interval, Workout, Comment } from "../ast";
|
import { Interval, Workout, Comment } from "../ast";
|
||||||
import { Duration } from "../Duration";
|
import { Duration } from "../Duration";
|
||||||
import { FreeIntensity, Intensity, IntensityRange } from "../Intensity";
|
import { ConstantIntensity, FreeIntensity, RangeIntensity } from "../Intensity";
|
||||||
import { ParseError } from "./ParseError";
|
import { ParseError } from "./ParseError";
|
||||||
import { IntervalType, SourceLocation, Token } from "./tokenizer";
|
import { IntervalType, SourceLocation, Token } from "./tokenizer";
|
||||||
|
|
||||||
|
|
@ -92,10 +92,10 @@ const parseIntervalParams = (type: IntervalType, tokens: Token[], loc: SourceLoc
|
||||||
cadence = token.value;
|
cadence = token.value;
|
||||||
tokens.shift();
|
tokens.shift();
|
||||||
} else if (token.type === "intensity") {
|
} else if (token.type === "intensity") {
|
||||||
intensity = new Intensity(token.value);
|
intensity = new ConstantIntensity(token.value);
|
||||||
tokens.shift();
|
tokens.shift();
|
||||||
} else if (token.type === "intensity-range") {
|
} else if (token.type === "intensity-range") {
|
||||||
intensity = new IntensityRange(token.value[0], token.value[1]);
|
intensity = new RangeIntensity(token.value[0], token.value[1]);
|
||||||
tokens.shift();
|
tokens.shift();
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ export type NumberToken = {
|
||||||
value: number;
|
value: number;
|
||||||
loc: SourceLocation;
|
loc: SourceLocation;
|
||||||
};
|
};
|
||||||
export type IntensityRangeToken = {
|
export type RangeIntensityToken = {
|
||||||
type: "intensity-range";
|
type: "intensity-range";
|
||||||
value: [number, number];
|
value: [number, number];
|
||||||
loc: SourceLocation;
|
loc: SourceLocation;
|
||||||
|
|
@ -46,7 +46,7 @@ export type CommentStartToken = {
|
||||||
value?: undefined;
|
value?: undefined;
|
||||||
loc: SourceLocation;
|
loc: SourceLocation;
|
||||||
};
|
};
|
||||||
export type Token = HeaderToken | IntervalToken | TextToken | NumberToken | IntensityRangeToken | CommentStartToken;
|
export type Token = HeaderToken | IntervalToken | TextToken | NumberToken | RangeIntensityToken | CommentStartToken;
|
||||||
|
|
||||||
const toInteger = (str: string): number => {
|
const toInteger = (str: string): number => {
|
||||||
return parseInt(str.replace(/[^0-9]/, ""), 10);
|
return parseInt(str.replace(/[^0-9]/, ""), 10);
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import { pipe } from "ramda";
|
import { pipe } from "ramda";
|
||||||
import { Interval } from "../ast";
|
import { Interval } from "../ast";
|
||||||
import { Intensity } from "../Intensity";
|
import { ConstantIntensity } from "../Intensity";
|
||||||
import { average } from "./average";
|
import { average } from "./average";
|
||||||
import { intervalsToIntensityNumbers } from "./intervalsToIntensityNumbers";
|
import { intervalsToIntensityNumbers } from "./intervalsToIntensityNumbers";
|
||||||
|
|
||||||
export const averageIntensity = (intervals: Interval[]): Intensity => {
|
export const averageIntensity = (intervals: Interval[]): ConstantIntensity => {
|
||||||
return new Intensity(pipe(intervalsToIntensityNumbers, average)(intervals));
|
return new ConstantIntensity(pipe(intervalsToIntensityNumbers, average)(intervals));
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { pipe, sum } from "ramda";
|
import { pipe, sum } from "ramda";
|
||||||
import { Interval } from "../ast";
|
import { Interval } from "../ast";
|
||||||
import { Intensity } from "../Intensity";
|
import { ConstantIntensity } from "../Intensity";
|
||||||
import { average } from "./average";
|
import { average } from "./average";
|
||||||
import { intervalsToIntensityNumbers } from "./intervalsToIntensityNumbers";
|
import { intervalsToIntensityNumbers } from "./intervalsToIntensityNumbers";
|
||||||
|
|
||||||
|
|
@ -25,8 +25,8 @@ const fourthPower = (x: number) => Math.pow(x, 4);
|
||||||
|
|
||||||
const fourthRoot = (x: number) => Math.pow(x, 1 / 4);
|
const fourthRoot = (x: number) => Math.pow(x, 1 / 4);
|
||||||
|
|
||||||
export const normalizedIntensity = (intervals: Interval[]): Intensity => {
|
export const normalizedIntensity = (intervals: Interval[]): ConstantIntensity => {
|
||||||
return new Intensity(
|
return new ConstantIntensity(
|
||||||
pipe(
|
pipe(
|
||||||
intervalsToIntensityNumbers,
|
intervalsToIntensityNumbers,
|
||||||
rollingAverages,
|
rollingAverages,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue