running-tools

A collection of tools for runners and their coaches
git clone https://git.ashermorgan.net/running-tools/
Log | Files | Refs | README

targets.ts (9105B)


      1 /*
      2  * Contains types and helper functions for calculator target sets
      3  */
      4 
      5 import { DistanceUnits, convertDistance, formatDistance, formatDuration } from '@/core/units';
      6 import type { Distance } from '@/core/units';
      7 
      8 /*
      9  * The two basic types of targets: those defined by distance and those defined by time
     10  */
     11 export enum TargetTypes {
     12   Distance = 'distance',
     13   Time = 'time',
     14 };
     15 
     16 /*
     17  * The types for basic standard targets and target sets used by the pace and race calculators
     18  */
     19 interface DistanceTarget {
     20   type: TargetTypes.Distance,
     21   distanceValue: number,
     22   distanceUnit: DistanceUnits,
     23 };
     24 interface TimeTarget {
     25   type: TargetTypes.Time,
     26   time: number,
     27 };
     28 export type StandardTarget = DistanceTarget | TimeTarget;
     29 export interface StandardTargetSet {
     30   name: string,
     31   targets: Array<StandardTarget>,
     32 };
     33 export interface StandardTargetSets {
     34   [key: string]: StandardTargetSet,
     35 };
     36 
     37 /*
     38  * The types for split calculator targets and target sets
     39  */
     40 export type SplitTarget = DistanceTarget & {
     41   splitTime?: number
     42 };
     43 export interface SplitTargetSet {
     44   name: string,
     45   targets: Array<SplitTarget>,
     46 };
     47 export interface SplitTargetSets {
     48   [key: string]: SplitTargetSet,
     49 };
     50 
     51 /*
     52  * The types for workout calculator targets and target sets
     53  */
     54 export type WorkoutTarget = StandardTarget & {
     55   splitValue: number,
     56   splitUnit: DistanceUnits,
     57   customName?: string,
     58 };
     59 export interface WorkoutTargetSet {
     60   name: string,
     61   targets: Array<WorkoutTarget>,
     62 };
     63 export interface WorkoutTargetSets {
     64   [key: string]: WorkoutTargetSet,
     65 };
     66 
     67 /*
     68  * The types for generic targets and target sets
     69  */
     70 export type Target = StandardTarget | SplitTarget | WorkoutTarget;
     71 export type TargetSet = StandardTargetSet | SplitTargetSet | WorkoutTargetSet;
     72 export type TargetSets = StandardTargetSets | SplitTargetSets | WorkoutTargetSets;
     73 
     74 /**
     75  * Sort an array of targets
     76  * @param {Array<Target>} targets The array of targets
     77  * @returns {Array<Target>} The sorted targets
     78  */
     79 export function sort(targets: Array<Target>): Array<Target> {
     80   return [
     81     ...targets.filter((item) => item.type === TargetTypes.Distance)
     82       .sort((a, b) => convertDistance(a.distanceValue, a.distanceUnit, DistanceUnits.Meters)
     83         - convertDistance(b.distanceValue, b.distanceUnit, DistanceUnits.Meters)),
     84 
     85     ...targets.filter((item) => item.type === TargetTypes.Time)
     86       .sort((a, b) => a.time - b.time),
     87   ];
     88 }
     89 
     90 /**
     91  * Generate a string description of a workout target
     92  * @param {WorkoutTarget} target The workout target
     93  * @return {string} The string description
     94  */
     95 export function workoutTargetToString(target: WorkoutTarget): string {
     96   let result = formatDistance({ distanceValue: target.splitValue, distanceUnit: target.splitUnit },
     97                               false);
     98 
     99   if (target.type === TargetTypes.Time) {
    100     result += ' @ ' + formatDuration(target.time, 3, 2, false);
    101   } else if (target.distanceValue != target.splitValue || target.distanceUnit != target.splitUnit) {
    102     result += ' @ ' + formatDistance(target as Distance, false);
    103   }
    104   return result;
    105 }
    106 
    107 /*
    108  * The default target sets for each calculator
    109  */
    110 export const defaultTargetSets: { [key: string]: TargetSet } = {
    111   '_pace_targets': {
    112     name: 'Common Pace Targets',
    113     targets: sort([
    114       { type: TargetTypes.Distance, distanceValue: 100, distanceUnit: DistanceUnits.Meters },
    115       { type: TargetTypes.Distance, distanceValue: 200, distanceUnit: DistanceUnits.Meters },
    116       { type: TargetTypes.Distance, distanceValue: 300, distanceUnit: DistanceUnits.Meters },
    117       { type: TargetTypes.Distance, distanceValue: 400, distanceUnit: DistanceUnits.Meters },
    118       { type: TargetTypes.Distance, distanceValue: 600, distanceUnit: DistanceUnits.Meters },
    119       { type: TargetTypes.Distance, distanceValue: 800, distanceUnit: DistanceUnits.Meters },
    120       { type: TargetTypes.Distance, distanceValue: 1000, distanceUnit: DistanceUnits.Meters },
    121       { type: TargetTypes.Distance, distanceValue: 1200, distanceUnit: DistanceUnits.Meters },
    122       { type: TargetTypes.Distance, distanceValue: 1500, distanceUnit: DistanceUnits.Meters },
    123       { type: TargetTypes.Distance, distanceValue: 1600, distanceUnit: DistanceUnits.Meters },
    124       { type: TargetTypes.Distance, distanceValue: 3200, distanceUnit: DistanceUnits.Meters },
    125 
    126       { type: TargetTypes.Distance, distanceValue: 2, distanceUnit: DistanceUnits.Kilometers },
    127       { type: TargetTypes.Distance, distanceValue: 3, distanceUnit: DistanceUnits.Kilometers },
    128       { type: TargetTypes.Distance, distanceValue: 4, distanceUnit: DistanceUnits.Kilometers },
    129       { type: TargetTypes.Distance, distanceValue: 5, distanceUnit: DistanceUnits.Kilometers },
    130       { type: TargetTypes.Distance, distanceValue: 6, distanceUnit: DistanceUnits.Kilometers },
    131       { type: TargetTypes.Distance, distanceValue: 8, distanceUnit: DistanceUnits.Kilometers },
    132       { type: TargetTypes.Distance, distanceValue: 10, distanceUnit: DistanceUnits.Kilometers },
    133 
    134       { type: TargetTypes.Distance, distanceValue: 1, distanceUnit: DistanceUnits.Miles },
    135       { type: TargetTypes.Distance, distanceValue: 2, distanceUnit: DistanceUnits.Miles },
    136       { type: TargetTypes.Distance, distanceValue: 3, distanceUnit: DistanceUnits.Miles },
    137       { type: TargetTypes.Distance, distanceValue: 5, distanceUnit: DistanceUnits.Miles },
    138       { type: TargetTypes.Distance, distanceValue: 6, distanceUnit: DistanceUnits.Miles },
    139       { type: TargetTypes.Distance, distanceValue: 8, distanceUnit: DistanceUnits.Miles },
    140       { type: TargetTypes.Distance, distanceValue: 10, distanceUnit: DistanceUnits.Miles },
    141 
    142       { type: TargetTypes.Distance, distanceValue: 0.5, distanceUnit: DistanceUnits.Marathons },
    143       { type: TargetTypes.Distance, distanceValue: 1, distanceUnit: DistanceUnits.Marathons },
    144 
    145       { type: TargetTypes.Time, time: 600 },
    146       { type: TargetTypes.Time, time: 1800 },
    147       { type: TargetTypes.Time, time: 3600 },
    148     ]),
    149   }, '_race_targets': {
    150     name: 'Common Race Targets',
    151     targets: sort([
    152       { type: TargetTypes.Distance, distanceValue: 400, distanceUnit: DistanceUnits.Meters },
    153       { type: TargetTypes.Distance, distanceValue: 800, distanceUnit: DistanceUnits.Meters },
    154       { type: TargetTypes.Distance, distanceValue: 1500, distanceUnit: DistanceUnits.Meters },
    155       { type: TargetTypes.Distance, distanceValue: 1600, distanceUnit: DistanceUnits.Meters },
    156       { type: TargetTypes.Distance, distanceValue: 1, distanceUnit: DistanceUnits.Miles },
    157       { type: TargetTypes.Distance, distanceValue: 3000, distanceUnit: DistanceUnits.Meters },
    158       { type: TargetTypes.Distance, distanceValue: 3200, distanceUnit: DistanceUnits.Meters },
    159       { type: TargetTypes.Distance, distanceValue: 2, distanceUnit: DistanceUnits.Miles },
    160 
    161       { type: TargetTypes.Distance, distanceValue: 3, distanceUnit: DistanceUnits.Miles },
    162       { type: TargetTypes.Distance, distanceValue: 5, distanceUnit: DistanceUnits.Kilometers },
    163       { type: TargetTypes.Distance, distanceValue: 6, distanceUnit: DistanceUnits.Kilometers },
    164       { type: TargetTypes.Distance, distanceValue: 8, distanceUnit: DistanceUnits.Kilometers },
    165       { type: TargetTypes.Distance, distanceValue: 10, distanceUnit: DistanceUnits.Kilometers },
    166       { type: TargetTypes.Distance, distanceValue: 15, distanceUnit: DistanceUnits.Kilometers },
    167 
    168       { type: TargetTypes.Distance, distanceValue: 0.5, distanceUnit: DistanceUnits.Marathons },
    169       { type: TargetTypes.Distance, distanceValue: 1, distanceUnit: DistanceUnits.Marathons },
    170     ]),
    171   }, '_split_targets': {
    172     name: '5K Mile Splits',
    173     targets: [
    174       { type: TargetTypes.Distance, distanceValue: 1, distanceUnit: DistanceUnits.Miles },
    175       { type: TargetTypes.Distance, distanceValue: 2, distanceUnit: DistanceUnits.Miles },
    176       { type: TargetTypes.Distance, distanceValue: 5, distanceUnit: DistanceUnits.Kilometers },
    177     ],
    178   }, '_workout_targets': {
    179     name: 'Common Workout Targets',
    180     targets: [
    181       {
    182         splitValue: 400, splitUnit: DistanceUnits.Meters,
    183         type: TargetTypes.Distance, distanceValue: 1, distanceUnit: DistanceUnits.Miles,
    184       },
    185       {
    186         splitValue: 800, splitUnit: DistanceUnits.Meters,
    187         type: TargetTypes.Distance, distanceValue: 5, distanceUnit: DistanceUnits.Kilometers,
    188       },
    189       {
    190         splitValue: 1600, splitUnit: DistanceUnits.Meters,
    191         type: TargetTypes.Time, time: 3600,
    192       },
    193       {
    194         splitValue: 1, splitUnit: DistanceUnits.Miles,
    195         type: TargetTypes.Distance, distanceValue: 1, distanceUnit: DistanceUnits.Marathons,
    196       },
    197     ],
    198   },
    199 };
    200 export const defaultPaceTargetSets: StandardTargetSets = {
    201   '_pace_targets': defaultTargetSets._pace_targets,
    202 };
    203 export const defaultRaceTargetSets: StandardTargetSets = {
    204   '_race_targets': defaultTargetSets._race_targets,
    205 };
    206 export const defaultSplitTargetSets: SplitTargetSets = {
    207   '_split_targets': defaultTargetSets._split_targets as SplitTargetSet,
    208 };
    209 export const defaultWorkoutTargetSets: WorkoutTargetSets = {
    210   '_workout_targets': defaultTargetSets._workout_targets as WorkoutTargetSet,
    211 };