ski-din-calculator
Version:
Calculate a skier's DIN binding release value based on height, weight, age, skill level, and boot sole length
162 lines (161 loc) • 5.82 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DinCalculator = void 0;
var SkierCode;
(function (SkierCode) {
SkierCode["A"] = "A";
SkierCode["B"] = "B";
SkierCode["C"] = "C";
SkierCode["D"] = "D";
SkierCode["E"] = "E";
SkierCode["F"] = "F";
SkierCode["G"] = "G";
SkierCode["H"] = "H";
SkierCode["I"] = "I";
SkierCode["J"] = "J";
SkierCode["K"] = "K";
SkierCode["L"] = "L";
SkierCode["M"] = "M";
SkierCode["N"] = "N";
SkierCode["O"] = "O";
})(SkierCode || (SkierCode = {}));
/**
* Class-based DIN calculator using traditional ISO 11088 standard.
*
* This calculator uses Imperial units (inches/pounds) and provides a different
* approach compared to the function-based calculator which uses metric units.
*
* @example
* ```typescript
* const calculator = new DinCalculator();
* const profile: SkierProfile = {
* height: 70, // inches
* weight: 160, // pounds
* age: 25,
* skill: 2, // moderate
* soleLength: 305 // mm
* };
* const dinValue = calculator.calculateDIN(profile);
* ```
*/
class DinCalculator {
constructor() {
this.skierCodes = [
SkierCode.A, SkierCode.B, SkierCode.C, SkierCode.D, SkierCode.E, SkierCode.F,
SkierCode.G, SkierCode.H, SkierCode.I, SkierCode.J, SkierCode.K, SkierCode.L,
SkierCode.M, SkierCode.N, SkierCode.O,
];
this.dins = [
[0.75, 0.75, 0.75, null, null, null, null, null], // A
[1, 0.75, 0.75, 0.75, null, null, null, null], // B
[1.5, 1.25, 1.25, 1, null, null, null, null], // C
[2, 1.75, 1.5, 1.5, 1.25, null, null, null], // D
[2.5, 2.25, 2, 1.75, 1.5, 1.25, null, null], // E
[3, 2.75, 2.5, 2.25, 2, 1.75, 1.75, null], // F
[null, 3.5, 3, 2.75, 2.5, 2.25, 2, null], // G
[null, null, 3.5, 3, 3, 2.75, 2.5, null], // H
[null, null, 4.5, 4, 3.5, 3.5, 3, null], // I
[null, null, 5.5, 5, 4.5, 4, 3.5, 3], // J
[null, null, 6.5, 6, 5.5, 5, 4.5, 4], // K
[null, null, 7.5, 7, 6.5, 6, 5.5, 5], // L
[null, null, null, 8.5, 8, 7, 6.5, 6], // M
[null, null, null, 10, 9.5, 8.5, 8, 7.5], // N
[null, null, null, 11.5, 11, 10, 9.5, 9], // O
];
}
/**
* Determines the index for height based on the skier's height in inches.
*/
getHeightIndex(height) {
if (height < 58)
return 0; // Under 4'10"
if (height >= 58 && height <= 62)
return 1; // 4'10" - 5'2"
if (height > 62 && height <= 66)
return 2; // 5'2" - 5'6"
if (height > 66 && height <= 70)
return 3; // 5'6" - 5'10"
if (height > 70 && height <= 74)
return 4; // 5'10" - 6'2"
if (height > 74 && height <= 78)
return 5; // 6'2" - 6'6"
return 6; // Over 6'6"
}
/**
* Determines the index for weight based on the skier's weight in pounds.
*/
getWeightIndex(weight) {
if (weight < 118)
return 0; // Under 118 lbs
if (weight >= 118 && weight <= 132)
return 1; // 118 - 132 lbs
if (weight > 132 && weight <= 148)
return 2; // 133 - 148 lbs
if (weight > 148 && weight <= 174)
return 3; // 149 - 174 lbs
if (weight > 174 && weight <= 200)
return 4; // 175 - 200 lbs
if (weight > 200 && weight <= 225)
return 5; // 201 - 225 lbs
return 6; // Over 225 lbs
}
/**
* Determines the skier code based on height and weight.
*/
getSkierCode(profile) {
const heightIndex = this.getHeightIndex(profile.height);
const weightIndex = this.getWeightIndex(profile.weight);
return this.skierCodes[Math.min(heightIndex, weightIndex)];
}
/**
* Adjusts the skier code based on the skier's age and skill level.
*/
adjustSkierCodeForAgeAndSkill(profile, skierCode) {
let skierCodeIndex = this.skierCodes.indexOf(skierCode);
// Adjust for skill level
if (profile.skill === 2) {
skierCodeIndex += 1; // Moderate
}
else if (profile.skill === 3) {
skierCodeIndex += 2; // Aggressive
}
// Adjust for age
if (profile.age > 50) {
skierCodeIndex -= 1;
}
skierCodeIndex = Math.max(0, skierCodeIndex); // Ensure index is within bounds
return this.skierCodes[skierCodeIndex];
}
/**
* Converts the sole length into an index for the DIN table.
*/
getSoleLengthIndex(soleLength) {
if (soleLength < 230)
return 0;
if (soleLength >= 230 && soleLength <= 250)
return 1;
if (soleLength > 250 && soleLength <= 270)
return 2;
if (soleLength > 270 && soleLength <= 290)
return 3;
if (soleLength > 290 && soleLength <= 310)
return 4;
if (soleLength > 310 && soleLength <= 330)
return 5;
return 6;
}
/**
* Calculates the DIN setting based on the skier's profile.
*
* @param profile - Skier profile with Imperial measurements
* @returns DIN value or null if no suitable setting found
*/
calculateDIN(profile) {
const initialSkierCode = this.getSkierCode(profile);
const adjustedSkierCode = this.adjustSkierCodeForAgeAndSkill(profile, initialSkierCode);
const skierCodeIndex = this.skierCodes.indexOf(adjustedSkierCode);
const soleLengthIndex = this.getSoleLengthIndex(profile.soleLength);
return this.dins[skierCodeIndex]?.[soleLengthIndex] ?? null;
}
}
exports.DinCalculator = DinCalculator;