Files
platform/calculator/util.ts
T

138 lines
4.3 KiB
TypeScript

// -------------------------------------------------------------------------------------------------
// Attributes
// -------------------------------------------------------------------------------------------------
export const attributes = Object.freeze({
STRENGTH: "Strength",
POWER: "Power",
ENDURANCE: "Endurance",
// SPEED: "Speed",
AGILITY: "Agility",
} as const);
export type Attribute = typeof attributes[keyof typeof attributes];
// -------------------------------------------------------------------------------------------------
// Enumerations & basic value objects
// -------------------------------------------------------------------------------------------------
export interface Player {
metrics: Metrics;
}
export const activities = Object.freeze({
BACK_SQUAT: "Back Squat",
DEADLIFT: "Deadlift",
BENCH_PRESS: "Bench Press",
RUN: "Run",
DASH: "Dash",
TREADMILL_DASH: "Treadmill Dash",
BROAD_JUMP: "Broad Jump",
CONE_DRILL: "Cone Drill",
} as const);
export type Activity = typeof activities[keyof typeof activities];
const activityAttrMap: Record<Activity, Attribute> = {
[activities.RUN]: attributes.ENDURANCE,
// [activities.TREADMILL_DASH]: attributes.SPEED,
// [activities.DASH]: attributes.SPEED,
[activities.DEADLIFT]: attributes.STRENGTH,
[activities.BACK_SQUAT]: attributes.STRENGTH,
[activities.BENCH_PRESS]: attributes.STRENGTH,
[activities.BROAD_JUMP]: attributes.POWER,
[activities.CONE_DRILL]: attributes.AGILITY,
} as const;
export const getActivityAttribute = (activity: Activity): Attribute => {
const attribute = activityAttrMap[activity];
if (!attribute) throw new Error(`${activity} does not have an associated attribute`);
return attribute;
};
export const getAttributeActivities = (attribute: Attribute): Activity[] => {
const activities: Activity[] = [];
for (const activity in activityAttrMap) {
if (activityAttrMap[activity] === attribute) {
activities.push(activity as Activity);
}
}
return activities;
}
export const genders = Object.freeze({
MALE: "male",
FEMALE: "female",
} as const);
export type Gender = typeof genders[keyof typeof genders];
// -------------------------------------------------------------------------------------------------
// Data model interfaces
// -------------------------------------------------------------------------------------------------
export interface ActivityPerformance {
activity: Activity;
performance: number;
}
export type Levels = Record<number, number>
export interface Metrics {
age: number;
weight: number;
gender: Gender;
};
export interface Standard {
metrics: Metrics;
levels: Levels;
}
export type StandardsMap = Record<
Activity,
Standard[]
>;
// -------------------------------------------------------------------------------------------------
// Conversion utilities
// -------------------------------------------------------------------------------------------------
export const lbToKg = (lb: number | string): number => +lb * 0.453592;
export const kgToLb = (kg: number | string): number => +kg * 2.20462;
export const minToMs = (min) => min * 60000;
export const secToMs = (sec) => sec * 1000;
export const feetToCm = (feet) => feet * 30.48;
export const inchesToCm = (inches) => inches * 2.54;
export const mphToMtrsPerMs = (mph: number): number => (mph * 0.44704) / 1000;
export const timeToMs = (time: string): number => {
const [main, decimal = "0"] = time.split(".");
const milliseconds = Number(decimal.padEnd(3, "0").slice(0, 3));
const parts = main.split(":").map(Number);
let minutes = 0,
seconds = 0;
if (parts.length === 1) {
seconds = parts[0];
} else if (parts.length === 2) {
[minutes, seconds] = parts as [number, number];
} else {
throw new Error("Invalid time format");
}
return (minutes * 60 + seconds) * 1000 + milliseconds;
};
export const msToTime = (ms: number, includeMs = false): string => {
const minutes = Math.floor(ms / 60000);
const seconds = Math.floor((ms % 60000) / 1000);
const milliseconds = Math.floor(ms % 1000);
let formattedTime = `${minutes}:${seconds.toString().padStart(2, "0")}`;
if (includeMs) {
formattedTime += `.${milliseconds.toString().padStart(3, "0")}`;
}
return formattedTime;
};