# Path: athlib/codes.py
# PAT_JUMPS = re.compile(_orjoin(PAT_VERTICAL_JUMPS,PAT_HORIZONTAL_JUMPS))
# 
# PAT_THROWS = re.compile(
#                         (
#                         r"^(?:"
#                         r"[sS]?[dD][tT](?P<dtnum>%s|)|"
#                         r"[sS]?[jJ][tT](?P<jtnum>[45678]00\s*g?|)|"
#                         r"[hH][tT](?P<htnum>%s|)|"
#                         r"[sS][pP](?P<spnum>%s|)|"
#                         r"[wW][tT](?P<wtnum>\d?%s|)|"
#                         r"[sS][sW][tT](?P<swtnum>%s|)|"
#                         r"[sS]?[bB][tT](?P<btnum>%s|)|"
#                         r"[sS][tT](?P<stnum>%s|)|"
#                         r"[gG][dD][tT](?P<gdtnum>%s|)|"
#                         r"[oO][tT](?P<otnum>\d+\s*g?|)|"
#                         r"[tT][aA][rR][tT]|"  # weight not relevant
#                         r"[cC][hH][tT]|"
#                         r"[oO][hH][tT]|"                         
#                         r"[Hh][1-9]|"
#                         r"[Ll][1-9]"
#                         ")$"
#                         ) % (_, _, _, _, _, _, _, _),
#                         )
# 
# Path: athlib/wma/agegrader.py
# class AthlonsAgeGrader(AgeGrader):
#     data_file_name = "wma-athlons-data.json"
#     text_columns = 0, 2
#     event_column = 2
# 
#     def calculate_factor(self, gender, age, event):
#         """Work out 'slowdown factor' for a geezer of this
#         age taking part in this event e.g.
# 
#         >>> from .agegrader import AthlonsAgeGrader
#         >>> ag=AthlonsAgeGrader()
#         >>> ag.calculate_factor('M',65,'100H')
#         0.8637
#         >>> ag.calculate_factor('M',69,'100H')
#         0.8637
#         >>> ag.calculate_factor('M',65,'10000')
#         0.7858
#         >>> ag.calculate_factor('M',69,'10000')
#         0.7858
#         >>> ag.calculate_factor('f',35,'100H')
#         0.9852
#         >>> ag.calculate_factor('F',39,'100H')
#         0.9852
#         >>> ag.calculate_factor('F',35,'1500')
#         0.9872
#         >>> ag.calculate_factor('f',39,'1500')
#         0.9872
#         """
#         event = event.upper()
#         gender = self.normalize_gender(gender)
# 
#         # Which table we're using
#         data = self.get_data()[self.data_year]
#         table = data[gender]
#         ages = data['ages']
# 
#         # We must match an event exactly
#         self.find_row_by_event(event,
#                                table,
#                                x=2,
#                                label='wma-athlons.%s.%s' % (self.data_year,
#                                                             gender))
#         self.find_age(int(age // 5) * 5, ages, interpolate=False)
#         fac = table[self._fx][3:][self._ax1]
#         return fac
# 
# Path: athlib/implements.py
# def get_specific_event_code(generic_event_code: str, gender: str, age_group: str) -> str:
#     "Given e.g. 'SP', return 'SP7.26K"
# 
#     if generic_event_code not in ["SP", "HT", "JT", "DT", "WT"]:
#         return generic_event_code
# 
#     txt_weight = get_implement_weight(generic_event_code, gender, age_group)
#     # print("    implement weight for %s %s %s as text is %s" % (generic_event_code, gender, age_group, txt_weight))
#     mass = float(txt_weight)
# 
#     if mass == int(mass):
#         mass = int(mass)  # 4.00 becomes integer 4
# 
#     formatted = "%s%s" % (generic_event_code, mass)
#     if mass < 99:  # kg
#         formatted += 'K'
#     return formatted


import math
from .codes import PAT_JUMPS, PAT_THROWS
from .wma.agegrader import AthlonsAgeGrader
from .implements import get_specific_event_code
from typing import Union, Optional
        if value > coeffs["Z"]:
            points = max(0, int(coeffs["A"] * ((value - coeffs["Z"]) **
                       coeffs["X"])))
        else:
            points =  0
    elif PAT_THROWS.match(event_code):
        value = 0.01 * (math.floor(100* value * age_factor))
        if value > coeffs["Z"]:
            points =  max(0, int(coeffs["A"] * ((value - coeffs["Z"]) **
                       coeffs["X"])))
        else:
            points = 0
    else:
        value = 0.01 * (math.ceil(100* value * age_factor))
        if coeffs["Z"] > value:
            points = max(0, int(coeffs["A"] * ((coeffs["Z"] - value) **
                       coeffs["X"])))
        else:
            points = 0

    
    return points



def unit_name(event_code: str) -> str:
    """Utility function to get the unit name based on event type."""
    if PAT_JUMPS.match(event_code):
        # Used to be cm, but we standardised
        return "metres"

# Path: athlib/codes.py
# PAT_JUMPS = re.compile(_orjoin(PAT_VERTICAL_JUMPS,PAT_HORIZONTAL_JUMPS))
# 
# PAT_THROWS = re.compile(
#                         (
#                         r"^(?:"
#                         r"[sS]?[dD][tT](?P<dtnum>%s|)|"
#                         r"[sS]?[jJ][tT](?P<jtnum>[45678]00\s*g?|)|"
#                         r"[hH][tT](?P<htnum>%s|)|"
#                         r"[sS][pP](?P<spnum>%s|)|"
#                         r"[wW][tT](?P<wtnum>\d?%s|)|"
#                         r"[sS][sW][tT](?P<swtnum>%s|)|"
#                         r"[sS]?[bB][tT](?P<btnum>%s|)|"
#                         r"[sS][tT](?P<stnum>%s|)|"
#                         r"[gG][dD][tT](?P<gdtnum>%s|)|"
#                         r"[oO][tT](?P<otnum>\d+\s*g?|)|"
#                         r"[tT][aA][rR][tT]|"  # weight not relevant
#                         r"[cC][hH][tT]|"
#                         r"[oO][hH][tT]|"                         
#                         r"[Hh][1-9]|"
#                         r"[Ll][1-9]"
#                         ")$"
#                         ) % (_, _, _, _, _, _, _, _),
#                         )
# 
# Path: athlib/wma/agegrader.py
# class AthlonsAgeGrader(AgeGrader):
#     data_file_name = "wma-athlons-data.json"
#     text_columns = 0, 2
#     event_column = 2
# 
#     def calculate_factor(self, gender, age, event):
#         """Work out 'slowdown factor' for a geezer of this
#         age taking part in this event e.g.
# 
#         >>> from .agegrader import AthlonsAgeGrader
#         >>> ag=AthlonsAgeGrader()
#         >>> ag.calculate_factor('M',65,'100H')
#         0.8637
#         >>> ag.calculate_factor('M',69,'100H')
#         0.8637
#         >>> ag.calculate_factor('M',65,'10000')
#         0.7858
#         >>> ag.calculate_factor('M',69,'10000')
#         0.7858
#         >>> ag.calculate_factor('f',35,'100H')
#         0.9852
#         >>> ag.calculate_factor('F',39,'100H')
#         0.9852
#         >>> ag.calculate_factor('F',35,'1500')
#         0.9872
#         >>> ag.calculate_factor('f',39,'1500')
#         0.9872
#         """
#         event = event.upper()
#         gender = self.normalize_gender(gender)
# 
#         # Which table we're using
#         data = self.get_data()[self.data_year]
#         table = data[gender]
#         ages = data['ages']
# 
#         # We must match an event exactly
#         self.find_row_by_event(event,
#                                table,
#                                x=2,
#                                label='wma-athlons.%s.%s' % (self.data_year,
#                                                             gender))
#         self.find_age(int(age // 5) * 5, ages, interpolate=False)
#         fac = table[self._fx][3:][self._ax1]
#         return fac
# 
# Path: athlib/implements.py
# def get_specific_event_code(generic_event_code: str, gender: str, age_group: str) -> str:
#     "Given e.g. 'SP', return 'SP7.26K"
# 
#     if generic_event_code not in ["SP", "HT", "JT", "DT", "WT"]:
#         return generic_event_code
# 
#     txt_weight = get_implement_weight(generic_event_code, gender, age_group)
#     # print("    implement weight for %s %s %s as text is %s" % (generic_event_code, gender, age_group, txt_weight))
#     mass = float(txt_weight)
# 
#     if mass == int(mass):
#         mass = int(mass)  # 4.00 becomes integer 4
# 
#     formatted = "%s%s" % (generic_event_code, mass)
#     if mass < 99:  # kg
#         formatted += 'K'
#     return formatted


# Path: athlib/athlon_score.py
import math
from .codes import PAT_JUMPS, PAT_THROWS
from .wma.agegrader import AthlonsAgeGrader
from .implements import get_specific_event_code
from typing import Union, Optional

        if value > coeffs["Z"]:
            points = max(0, int(coeffs["A"] * ((value - coeffs["Z"]) **
                       coeffs["X"])))
        else:
            points =  0
    elif PAT_THROWS.match(event_code):
        value = 0.01 * (math.floor(100* value * age_factor))
        if value > coeffs["Z"]:
            points =  max(0, int(coeffs["A"] * ((value - coeffs["Z"]) **
                       coeffs["X"])))
        else:
            points = 0
    else:
        value = 0.01 * (math.ceil(100* value * age_factor))
        if coeffs["Z"] > value:
            points = max(0, int(coeffs["A"] * ((coeffs["Z"] - value) **
                       coeffs["X"])))
        else:
            points = 0

    
    return points



def unit_name(event_code: str) -> str:
    """Utility function to get the unit name based on event type."""
    if PAT_JUMPS.match(event_code):
        # Used to be cm, but we standardised
        return "metres"

    elif PAT_THROWS.match(event_code):