#include "MoABoneNameMappings.h"

FString FMoABoneNameMappings::NormalizeBoneName(const FString& BoneName)
{
    FString Normalized = BoneName.ToLower();

    Normalized.RemoveFromStart(TEXT("mixamorig:"));
    Normalized.RemoveFromStart(TEXT("mixamorig_"));
    Normalized.RemoveFromStart(TEXT("mixamorig"));
    Normalized.RemoveFromStart(TEXT("bip001_"));
    Normalized.RemoveFromStart(TEXT("bip01_"));
    Normalized.RemoveFromStart(TEXT("bip_"));
    Normalized.RemoveFromStart(TEXT("valvebiped_"));
    Normalized.RemoveFromStart(TEXT("valvebiped."));
    Normalized.RemoveFromStart(TEXT("def_"));
    Normalized.RemoveFromStart(TEXT("deform_"));
    Normalized.RemoveFromStart(TEXT("jnt_"));
    Normalized.RemoveFromStart(TEXT("joint_"));
    Normalized.RemoveFromStart(TEXT("bone_"));
    Normalized.RemoveFromStart(TEXT("rig_"));
    Normalized.RemoveFromStart(TEXT("root_"));
    Normalized.RemoveFromStart(TEXT("character_"));
    Normalized.RemoveFromStart(TEXT("char_"));

    Normalized.RemoveFromEnd(TEXT("_jnt"));
    Normalized.RemoveFromEnd(TEXT("_bone"));
    Normalized.RemoveFromEnd(TEXT("_joint"));
    Normalized.RemoveFromEnd(TEXT("_bind"));

    Normalized.ReplaceInline(TEXT("_l"), TEXT("l"));
    Normalized.ReplaceInline(TEXT("_r"), TEXT("r"));
    Normalized.ReplaceInline(TEXT("l_"), TEXT("l"));
    Normalized.ReplaceInline(TEXT("r_"), TEXT("r"));
    Normalized.ReplaceInline(TEXT(".l"), TEXT("l"));
    Normalized.ReplaceInline(TEXT(".r"), TEXT("r"));
    Normalized.ReplaceInline(TEXT("l."), TEXT("l"));
    Normalized.ReplaceInline(TEXT("r."), TEXT("r"));
    Normalized.ReplaceInline(TEXT("-l"), TEXT("l"));
    Normalized.ReplaceInline(TEXT("-r"), TEXT("r"));
    Normalized.ReplaceInline(TEXT("l-"), TEXT("l"));
    Normalized.ReplaceInline(TEXT("r-"), TEXT("r"));
    Normalized.ReplaceInline(TEXT(" l"), TEXT("l"));
    Normalized.ReplaceInline(TEXT(" r"), TEXT("r"));
    Normalized.ReplaceInline(TEXT("l "), TEXT("l"));
    Normalized.ReplaceInline(TEXT("r "), TEXT("r"));
    Normalized.ReplaceInline(TEXT("left"), TEXT("l"));
    Normalized.ReplaceInline(TEXT("right"), TEXT("r"));

    Normalized.ReplaceInline(TEXT("_"), TEXT(""));
    Normalized.ReplaceInline(TEXT("-"), TEXT(""));
    Normalized.ReplaceInline(TEXT("."), TEXT(""));
    Normalized.ReplaceInline(TEXT(" "), TEXT(""));
    Normalized.ReplaceInline(TEXT(":"), TEXT(""));
    Normalized.ReplaceInline(TEXT("|"), TEXT(""));

    return Normalized;
}

const TMap<FString, TArray<FString>>& FMoABoneNameMappings::GetCommonMappings()
{

    static
    TMap<FString, TArray<FString>> CommonMappings = {
        {TEXT("hips"), {TEXT("pelvis"), TEXT("root"), TEXT("hip"), TEXT("basin"), TEXT("spine0"), TEXT("spine_0")}},
        {TEXT("pelvis"), {TEXT("hips"), TEXT("root"), TEXT("hip"), TEXT("basin")}},
        {TEXT("root"), {TEXT("hips"), TEXT("pelvis"), TEXT("hip")}},

        {TEXT("lefthip"), {TEXT("thigh"), TEXT("thigl"), TEXT("thigh_l"), TEXT("upleg"), TEXT("upperleg"), TEXT("leftupleg"), TEXT("l_thigh"), TEXT("left_thigh"), TEXT("l_upleg"), TEXT("upperlegl"), TEXT("leftupperleg")}},
        {TEXT("righthip"), {TEXT("thigh"), TEXT("thighr"), TEXT("thigh_r"), TEXT("upleg"), TEXT("upperleg"), TEXT("rightupleg"), TEXT("r_thigh"), TEXT("right_thigh"), TEXT("r_upleg"), TEXT("upperlegr"), TEXT("rightupperleg")}},
        {TEXT("thigh"), {TEXT("hip"), TEXT("upleg"), TEXT("upperleg"), TEXT("leg")}},
        {TEXT("thigl"), {TEXT("lefthip"), TEXT("thigh_l"), TEXT("leftupleg"), TEXT("l_thigh"), TEXT("left_thigh"), TEXT("upperlegl")}},
        {TEXT("thighr"), {TEXT("righthip"), TEXT("thigh_r"), TEXT("rightupleg"), TEXT("r_thigh"), TEXT("right_thigh"), TEXT("upperlegr")}},
        {TEXT("thigh_l"), {TEXT("lefthip"), TEXT("thigl"), TEXT("leftupleg"), TEXT("l_thigh"), TEXT("left_thigh"), TEXT("upperlegl")}},
        {TEXT("thigh_r"), {TEXT("righthip"), TEXT("thighr"), TEXT("rightupleg"), TEXT("r_thigh"), TEXT("right_thigh"), TEXT("upperlegr")}},
        {TEXT("leftupleg"), {TEXT("lefthip"), TEXT("thigl"), TEXT("thigh_l"), TEXT("l_thigh"), TEXT("left_thigh"), TEXT("l_upleg"), TEXT("upperlegl")}},
        {TEXT("rightupleg"), {TEXT("righthip"), TEXT("thighr"), TEXT("thigh_r"), TEXT("r_thigh"), TEXT("right_thigh"), TEXT("r_upleg"), TEXT("upperlegr")}},
        {TEXT("upleg"), {TEXT("hip"), TEXT("thigh"), TEXT("upperleg"), TEXT("leg")}},
        {TEXT("upperleg"), {TEXT("hip"), TEXT("thigh"), TEXT("upleg"), TEXT("leg")}},
        {TEXT("upperlegl"), {TEXT("lefthip"), TEXT("thigl"), TEXT("thigh_l"), TEXT("leftupleg"), TEXT("l_thigh"), TEXT("left_thigh"), TEXT("leftupperleg")}},
        {TEXT("upperlegr"), {TEXT("righthip"), TEXT("thighr"), TEXT("thigh_r"), TEXT("rightupleg"), TEXT("r_thigh"), TEXT("right_thigh"), TEXT("rightupperleg")}},
        {TEXT("leftupperleg"), {TEXT("lefthip"), TEXT("thigl"), TEXT("thigh_l"), TEXT("leftupleg"), TEXT("upperlegl")}},
        {TEXT("rightupperleg"), {TEXT("righthip"), TEXT("thighr"), TEXT("thigh_r"), TEXT("rightupleg"), TEXT("upperlegr")}},
        
        {TEXT("leftknee"), {TEXT("calf"), TEXT("calfl"), TEXT("calf_l"), TEXT("shin"), TEXT("lowleg"), TEXT("lowerleg"), TEXT("leftleg"), TEXT("l_calf"), TEXT("left_calf"), TEXT("l_leg"), TEXT("lowerlegl"), TEXT("leftlowerleg")}},
        {TEXT("rightknee"), {TEXT("calf"), TEXT("calfr"), TEXT("calf_r"), TEXT("shin"), TEXT("lowleg"), TEXT("lowerleg"), TEXT("rightleg"), TEXT("r_calf"), TEXT("right_calf"), TEXT("r_leg"), TEXT("lowerlegr"), TEXT("rightlowerleg")}},
        {TEXT("knee"), {TEXT("calf"), TEXT("shin"), TEXT("lowleg"), TEXT("lowerleg"), TEXT("leg"), TEXT("leg1")}},
        {TEXT("calf"), {TEXT("knee"), TEXT("shin"), TEXT("lowleg"), TEXT("lowerleg"), TEXT("leg")}},
        {TEXT("calfl"), {TEXT("leftknee"), TEXT("calf_l"), TEXT("leftleg"), TEXT("l_calf"), TEXT("left_calf"), TEXT("lowerlegl")}},
        {TEXT("calfr"), {TEXT("rightknee"), TEXT("calf_r"), TEXT("rightleg"), TEXT("r_calf"), TEXT("right_calf"), TEXT("lowerlegr")}},
        {TEXT("calf_l"), {TEXT("leftknee"), TEXT("calfl"), TEXT("leftleg"), TEXT("l_calf"), TEXT("left_calf"), TEXT("lowerlegl")}},
        {TEXT("calf_r"), {TEXT("rightknee"), TEXT("calfr"), TEXT("rightleg"), TEXT("r_calf"), TEXT("right_calf"), TEXT("lowerlegr")}},
        {TEXT("leftleg"), {TEXT("leftknee"), TEXT("calfl"), TEXT("calf_l"), TEXT("l_calf"), TEXT("left_calf"), TEXT("l_leg"), TEXT("lowerlegl")}},
        {TEXT("rightleg"), {TEXT("rightknee"), TEXT("calfr"), TEXT("calf_r"), TEXT("r_calf"), TEXT("right_calf"), TEXT("r_leg"), TEXT("lowerlegr")}},
        {TEXT("lowleg"), {TEXT("knee"), TEXT("calf"), TEXT("shin"), TEXT("lowerleg"), TEXT("leg")}},
        {TEXT("lowerleg"), {TEXT("knee"), TEXT("calf"), TEXT("shin"), TEXT("lowleg"), TEXT("leg")}},
        {TEXT("lowerlegl"), {TEXT("leftknee"), TEXT("calfl"), TEXT("calf_l"), TEXT("leftleg"), TEXT("l_calf"), TEXT("left_calf"), TEXT("leftlowerleg")}},
        {TEXT("lowerlegr"), {TEXT("rightknee"), TEXT("calfr"), TEXT("calf_r"), TEXT("rightleg"), TEXT("r_calf"), TEXT("right_calf"), TEXT("rightlowerleg")}},
        {TEXT("leftlowerleg"), {TEXT("leftknee"), TEXT("calfl"), TEXT("calf_l"), TEXT("leftleg"), TEXT("lowerlegl")}},
        {TEXT("rightlowerleg"), {TEXT("rightknee"), TEXT("calfr"), TEXT("calf_r"), TEXT("rightleg"), TEXT("lowerlegr")}},
        
        {TEXT("leftankle"), {TEXT("foot"), TEXT("footl"), TEXT("foot_l"), TEXT("ankle"), TEXT("l_foot"), TEXT("left_foot")}},
        {TEXT("rightankle"), {TEXT("foot"), TEXT("footr"), TEXT("foot_r"), TEXT("ankle"), TEXT("r_foot"), TEXT("right_foot")}},
        {TEXT("ankle"), {TEXT("foot"), TEXT("feet"), TEXT("toes")}},
        {TEXT("foot"), {TEXT("ankle"), TEXT("feet")}},
        {TEXT("footl"), {TEXT("leftankle"), TEXT("foot_l"), TEXT("l_foot"), TEXT("left_foot")}},
        {TEXT("footr"), {TEXT("rightankle"), TEXT("foot_r"), TEXT("r_foot"), TEXT("right_foot")}},
        {TEXT("foot_l"), {TEXT("leftankle"), TEXT("footl"), TEXT("l_foot"), TEXT("left_foot")}},
        {TEXT("foot_r"), {TEXT("rightankle"), TEXT("footr"), TEXT("r_foot"), TEXT("right_foot")}},

        {TEXT("lefttoe"), {TEXT("lefttoes"), TEXT("ball"), TEXT("balll"), TEXT("ball_l"), TEXT("ball01l"), TEXT("ball_01_l"), TEXT("toes"), TEXT("toesl"), TEXT("toes_l"), TEXT("toe"), TEXT("toel"), TEXT("toe_l"), TEXT("toebase"), TEXT("toebasel"), TEXT("toebase_l"), TEXT("l_ball"), TEXT("left_ball"), TEXT("l_toes"), TEXT("left_toes"), TEXT("l_toebase"), TEXT("left_toebase"), TEXT("lefttoebase")}},
        {TEXT("lefttoes"), {TEXT("lefttoe"), TEXT("ball"), TEXT("balll"), TEXT("ball_l"), TEXT("ball01l"), TEXT("ball_01_l"), TEXT("toes"), TEXT("toesl"), TEXT("toes_l"), TEXT("toe"), TEXT("toel"), TEXT("toe_l"), TEXT("toebase"), TEXT("toebasel"), TEXT("toebase_l"), TEXT("l_ball"), TEXT("left_ball"), TEXT("l_toes"), TEXT("left_toes"), TEXT("l_toebase"), TEXT("left_toebase"), TEXT("lefttoebase")}},
        {TEXT("righttoe"), {TEXT("righttoes"), TEXT("ball"), TEXT("ballr"), TEXT("ball_r"), TEXT("ball01r"), TEXT("ball_01_r"), TEXT("toes"), TEXT("toesr"), TEXT("toes_r"), TEXT("toe"), TEXT("toer"), TEXT("toe_r"), TEXT("toebase"), TEXT("toebaser"), TEXT("toebase_r"), TEXT("r_ball"), TEXT("right_ball"), TEXT("r_toes"), TEXT("right_toes"), TEXT("r_toebase"), TEXT("right_toebase"), TEXT("righttoebase")}},
        {TEXT("righttoes"), {TEXT("righttoe"), TEXT("ball"), TEXT("ballr"), TEXT("ball_r"), TEXT("ball01r"), TEXT("ball_01_r"), TEXT("toes"), TEXT("toesr"), TEXT("toes_r"), TEXT("toe"), TEXT("toer"), TEXT("toe_r"), TEXT("toebase"), TEXT("toebaser"), TEXT("toebase_r"), TEXT("r_ball"), TEXT("right_ball"), TEXT("r_toes"), TEXT("right_toes"), TEXT("r_toebase"), TEXT("right_toebase"), TEXT("righttoebase")}},
        {TEXT("ball01l"), {TEXT("lefttoe"), TEXT("lefttoes"), TEXT("ball_l"), TEXT("balll"), TEXT("ball_01_l")}},
        {TEXT("ball01r"), {TEXT("righttoe"), TEXT("righttoes"), TEXT("ball_r"), TEXT("ballr"), TEXT("ball_01_r")}},
        {TEXT("toes"), {TEXT("ball"), TEXT("toe"), TEXT("toebase"), TEXT("toetip"), TEXT("footend")}},
                {TEXT("toesl"), {TEXT("lefttoe"), TEXT("lefttoes"), TEXT("ball_l"), TEXT("toes_l"), TEXT("toebase_l"), TEXT("l_ball"), TEXT("left_ball"), TEXT("l_toes"), TEXT("left_toes"), TEXT("l_toebase"), TEXT("left_toebase")}},
        {TEXT("toesr"), {TEXT("righttoe"), TEXT("righttoes"), TEXT("ball_r"), TEXT("toes_r"), TEXT("toebase_r"), TEXT("r_ball"), TEXT("right_ball"), TEXT("r_toes"), TEXT("right_toes"), TEXT("r_toebase"), TEXT("right_toebase")}},
        {TEXT("ball"), {TEXT("toes"), TEXT("toe"), TEXT("toebase"), TEXT("toetip")}},        {TEXT("balll"), {TEXT("lefttoe"), TEXT("lefttoes"), TEXT("ball_l"), TEXT("toes_l"), TEXT("toebase_l"), TEXT("l_ball"), TEXT("left_ball"), TEXT("lefttoebase")}},
        {TEXT("ballr"), {TEXT("righttoe"), TEXT("righttoes"), TEXT("ball_r"), TEXT("toes_r"), TEXT("toebase_r"), TEXT("r_ball"), TEXT("right_ball"), TEXT("righttoebase")}},
        {TEXT("ball_l"), {TEXT("lefttoe"), TEXT("lefttoes"), TEXT("balll"), TEXT("toesl"), TEXT("toes_l"), TEXT("toebase_l"), TEXT("l_ball"), TEXT("left_ball"), TEXT("l_toes"), TEXT("left_toes"), TEXT("l_toebase"), TEXT("left_toebase"), TEXT("lefttoebase")}},
        {TEXT("ball_r"), {TEXT("righttoe"), TEXT("righttoes"), TEXT("ballr"), TEXT("toesr"), TEXT("toes_r"), TEXT("toebase_r"), TEXT("r_ball"), TEXT("right_ball"), TEXT("r_toes"), TEXT("right_toes"), TEXT("r_toebase"), TEXT("right_toebase"), TEXT("righttoebase")}},
        {TEXT("toes_l"), {TEXT("lefttoe"), TEXT("lefttoes"), TEXT("ball_l"), TEXT("toesl"), TEXT("toebase_l"), TEXT("l_ball"), TEXT("left_ball"), TEXT("l_toes"), TEXT("left_toes"), TEXT("l_toebase"), TEXT("left_toebase")}},
        {TEXT("toes_r"), {TEXT("righttoe"), TEXT("righttoes"), TEXT("ball_r"), TEXT("toesr"), TEXT("toebase_r"), TEXT("r_ball"), TEXT("right_ball"), TEXT("r_toes"), TEXT("right_toes"), TEXT("r_toebase"), TEXT("right_toebase")}},
        {TEXT("toe"), {TEXT("toes"), TEXT("ball"), TEXT("toebase"), TEXT("toetip")}},
                {TEXT("toel"), {TEXT("lefttoe"), TEXT("lefttoes"), TEXT("ball_l"), TEXT("toes_l"), TEXT("toebase_l"), TEXT("l_toes"), TEXT("left_toes"), TEXT("l_toebase"), TEXT("left_toebase")}},
        {TEXT("toer"), {TEXT("righttoe"), TEXT("righttoes"), TEXT("ball_r"), TEXT("toes_r"), TEXT("toebase_r"), TEXT("r_toes"), TEXT("right_toes"), TEXT("r_toebase"), TEXT("right_toebase")}},
        {TEXT("toe_l"), {TEXT("lefttoe"), TEXT("lefttoes"), TEXT("ball_l"), TEXT("toes_l"), TEXT("toebase_l"), TEXT("l_toes"), TEXT("left_toes"), TEXT("l_toebase"), TEXT("left_toebase")}},
        {TEXT("toe_r"), {TEXT("righttoe"), TEXT("righttoes"), TEXT("ball_r"), TEXT("toes_r"), TEXT("toebase_r"), TEXT("r_toes"), TEXT("right_toes"), TEXT("r_toebase"), TEXT("right_toebase")}},
        {TEXT("toebase"), {TEXT("toes"), TEXT("ball"), TEXT("toe"), TEXT("toetip")}},
                {TEXT("toebasel"), {TEXT("lefttoe"), TEXT("lefttoes"), TEXT("ball_l"), TEXT("toes_l"), TEXT("toebase_l"), TEXT("l_toebase"), TEXT("left_toebase"), TEXT("lefttoebase")}},
        {TEXT("toebaser"), {TEXT("righttoe"), TEXT("righttoes"), TEXT("ball_r"), TEXT("toes_r"), TEXT("toebase_r"), TEXT("r_toebase"), TEXT("right_toebase"), TEXT("righttoebase")}},
        {TEXT("toebase_l"), {TEXT("lefttoe"), TEXT("lefttoes"), TEXT("ball_l"), TEXT("toes_l"), TEXT("toebasel"), TEXT("l_toebase"), TEXT("left_toebase"), TEXT("lefttoebase")}},
        {TEXT("toebase_r"), {TEXT("righttoe"), TEXT("righttoes"), TEXT("ball_r"), TEXT("toes_r"), TEXT("toebaser"), TEXT("r_toebase"), TEXT("right_toebase"), TEXT("righttoebase")}},
        {TEXT("lefttoebase"), {TEXT("lefttoe"), TEXT("lefttoes"), TEXT("ball_l"), TEXT("toes_l"), TEXT("toebase_l"), TEXT("toebasel"), TEXT("l_toebase"), TEXT("left_toebase")}},
        {TEXT("righttoebase"), {TEXT("righttoe"), TEXT("righttoes"), TEXT("ball_r"), TEXT("toes_r"), TEXT("toebase_r"), TEXT("toebaser"), TEXT("r_toebase"), TEXT("right_toebase")}},
        {TEXT("l_toebase"), {TEXT("lefttoe"), TEXT("lefttoes"), TEXT("ball_l"), TEXT("toes_l"), TEXT("toebase_l"), TEXT("left_toebase"), TEXT("lefttoebase")}},
        {TEXT("r_toebase"), {TEXT("righttoe"), TEXT("righttoes"), TEXT("ball_r"), TEXT("toes_r"), TEXT("toebase_r"), TEXT("right_toebase"), TEXT("righttoebase")}},
        {TEXT("left_toebase"), {TEXT("lefttoe"), TEXT("lefttoes"), TEXT("ball_l"), TEXT("toes_l"), TEXT("toebase_l"), TEXT("l_toebase"), TEXT("lefttoebase")}},
        {TEXT("right_toebase"), {TEXT("righttoe"), TEXT("righttoes"), TEXT("ball_r"), TEXT("toes_r"), TEXT("toebase_r"), TEXT("r_toebase"), TEXT("righttoebase")}},
        
        // Spine - bidirectional
        {TEXT("chest"), {TEXT("spine"), TEXT("spine1"), TEXT("spine01"), TEXT("spine_01"), TEXT("spine_1"), TEXT("torso"), TEXT("upperbody")}},
        {TEXT("spine"), {TEXT("chest"), TEXT("spine1"), TEXT("spine01"), TEXT("spine_01"), TEXT("torso"), TEXT("body")}},
        {TEXT("spine1"), {TEXT("chest"), TEXT("spine"), TEXT("spine01"), TEXT("spine_01")}},
        {TEXT("spine01"), {TEXT("chest"), TEXT("spine"), TEXT("spine1"), TEXT("spine_01")}},
        {TEXT("spine_01"), {TEXT("chest"), TEXT("spine"), TEXT("spine1"), TEXT("spine01")}},

        {TEXT("chest1"), {TEXT("chest"), TEXT("spine2"), TEXT("spine02"), TEXT("spine_02"), TEXT("spine_2"), TEXT("chest2"), TEXT("upperchest")}},
        {TEXT("spine2"), {TEXT("chest1"), TEXT("chest"), TEXT("spine02"), TEXT("spine_02"), TEXT("chest2")}},
        {TEXT("spine02"), {TEXT("chest1"), TEXT("chest"), TEXT("spine2"), TEXT("spine_02")}},
        {TEXT("spine_02"), {TEXT("chest1"), TEXT("chest"), TEXT("spine2"), TEXT("spine02")}},

        {TEXT("chest2"), {TEXT("upperchest"), TEXT("spine3"), TEXT("spine03"), TEXT("spine_03"), TEXT("spine_3"), TEXT("chest3")}},
        {TEXT("spine3"), {TEXT("chest2"), TEXT("upperchest"), TEXT("spine03"), TEXT("spine_03")}},
        {TEXT("spine03"), {TEXT("chest2"), TEXT("upperchest"), TEXT("spine3"), TEXT("spine_03")}},
        {TEXT("spine_03"), {TEXT("chest2"), TEXT("upperchest"), TEXT("spine3"), TEXT("spine03")}},

        {TEXT("neck"), {TEXT("neck1"), TEXT("neck01"), TEXT("neck_01"), TEXT("neck_1"), TEXT("neckbase")}},
        {TEXT("neck1"), {TEXT("head"), TEXT("neck"), TEXT("head1"), TEXT("neck02"), TEXT("neck_02")}},
        {TEXT("neck01"), {TEXT("neck"), TEXT("neck1"), TEXT("neck_01")}},
        {TEXT("neck_01"), {TEXT("neck"), TEXT("neck1"), TEXT("neck01")}},
        {TEXT("head"), {TEXT("neck1"), TEXT("skull"), TEXT("head1")}},

        {TEXT("leftcollar"), {TEXT("clavicle"), TEXT("claviclel"), TEXT("clavicle_l"), TEXT("shoulder"), TEXT("shoulderl"), TEXT("l_clavicle"), TEXT("left_clavicle"), TEXT("leftshoulder")}},
        {TEXT("rightcollar"), {TEXT("clavicle"), TEXT("clavicler"), TEXT("clavicle_r"), TEXT("shoulder"), TEXT("shoulderr"), TEXT("r_clavicle"), TEXT("right_clavicle"), TEXT("rightshoulder")}},
        {TEXT("collar"), {TEXT("clavicle"), TEXT("shoulder"), TEXT("scapula"), TEXT("shoulderblade")}},
        {TEXT("clavicle"), {TEXT("collar"), TEXT("shoulder"), TEXT("scapula")}},
        {TEXT("claviclel"), {TEXT("leftcollar"), TEXT("clavicle_l"), TEXT("shoulderl"), TEXT("l_clavicle"), TEXT("left_clavicle")}},
        {TEXT("clavicler"), {TEXT("rightcollar"), TEXT("clavicle_r"), TEXT("shoulderr"), TEXT("r_clavicle"), TEXT("right_clavicle")}},
        {TEXT("clavicle_l"), {TEXT("leftcollar"), TEXT("claviclel"), TEXT("shoulderl"), TEXT("l_clavicle"), TEXT("left_clavicle")}},
        {TEXT("clavicle_r"), {TEXT("rightcollar"), TEXT("clavicler"), TEXT("shoulderr"), TEXT("r_clavicle"), TEXT("right_clavicle")}},
        {TEXT("shoulderl"), {TEXT("leftcollar"), TEXT("claviclel"), TEXT("clavicle_l"), TEXT("l_clavicle"), TEXT("left_clavicle")}},
        {TEXT("shoulderr"), {TEXT("rightcollar"), TEXT("clavicler"), TEXT("clavicle_r"), TEXT("r_clavicle"), TEXT("right_clavicle")}},
        
        {TEXT("leftshoulder"), {TEXT("upperarm"), TEXT("upperarml"), TEXT("upperarm_l"), TEXT("arm"), TEXT("leftarm"), TEXT("l_upperarm"), TEXT("left_upperarm")}},
        {TEXT("rightshoulder"), {TEXT("upperarm"), TEXT("upperarmr"), TEXT("upperarm_r"), TEXT("arm"), TEXT("rightarm"), TEXT("r_upperarm"), TEXT("right_upperarm")}},
        {TEXT("shoulder"), {TEXT("upperarm"), TEXT("arm"), TEXT("uparm"), TEXT("bicep"), TEXT("humerus")}},
        {TEXT("upperarm"), {TEXT("shoulder"), TEXT("arm"), TEXT("uparm"), TEXT("bicep")}},
        {TEXT("upperarml"), {TEXT("leftshoulder"), TEXT("upperarm_l"), TEXT("leftarm"), TEXT("l_upperarm"), TEXT("left_upperarm")}},
        {TEXT("upperarmr"), {TEXT("rightshoulder"), TEXT("upperarm_r"), TEXT("rightarm"), TEXT("r_upperarm"), TEXT("right_upperarm")}},
        {TEXT("upperarm_l"), {TEXT("leftshoulder"), TEXT("upperarml"), TEXT("leftarm"), TEXT("l_upperarm"), TEXT("left_upperarm")}},
        {TEXT("upperarm_r"), {TEXT("rightshoulder"), TEXT("upperarmr"), TEXT("rightarm"), TEXT("r_upperarm"), TEXT("right_upperarm")}},
        {TEXT("leftarm"), {TEXT("leftshoulder"), TEXT("upperarml"), TEXT("upperarm_l"), TEXT("l_upperarm"), TEXT("left_upperarm")}},
        {TEXT("rightarm"), {TEXT("rightshoulder"), TEXT("upperarmr"), TEXT("upperarm_r"), TEXT("r_upperarm"), TEXT("right_upperarm")}},
        
        {TEXT("leftelbow"), {TEXT("lowerarm"), TEXT("lowerarml"), TEXT("lowerarm_l"), TEXT("forearm"), TEXT("leftforearm"), TEXT("l_lowerarm"), TEXT("left_lowerarm")}},
        {TEXT("rightelbow"), {TEXT("lowerarm"), TEXT("lowerarmr"), TEXT("lowerarm_r"), TEXT("forearm"), TEXT("rightforearm"), TEXT("r_lowerarm"), TEXT("right_lowerarm")}},
        {TEXT("elbow"), {TEXT("lowerarm"), TEXT("forearm"), TEXT("lowarm"), TEXT("arm1"), TEXT("ulna")}},
        {TEXT("lowerarm"), {TEXT("elbow"), TEXT("forearm"), TEXT("lowarm")}},
        {TEXT("lowerarml"), {TEXT("leftelbow"), TEXT("lowerarm_l"), TEXT("leftforearm"), TEXT("l_lowerarm"), TEXT("left_lowerarm")}},
        {TEXT("lowerarmr"), {TEXT("rightelbow"), TEXT("lowerarm_r"), TEXT("rightforearm"), TEXT("r_lowerarm"), TEXT("right_lowerarm")}},
        {TEXT("lowerarm_l"), {TEXT("leftelbow"), TEXT("lowerarml"), TEXT("leftforearm"), TEXT("l_lowerarm"), TEXT("left_lowerarm")}},
        {TEXT("lowerarm_r"), {TEXT("rightelbow"), TEXT("lowerarmr"), TEXT("rightforearm"), TEXT("r_lowerarm"), TEXT("right_lowerarm")}},
        {TEXT("leftforearm"), {TEXT("leftelbow"), TEXT("lowerarml"), TEXT("lowerarm_l"), TEXT("l_lowerarm"), TEXT("left_lowerarm")}},
        {TEXT("rightforearm"), {TEXT("rightelbow"), TEXT("lowerarmr"), TEXT("lowerarm_r"), TEXT("r_lowerarm"), TEXT("right_lowerarm")}},
        
        {TEXT("leftwrist"), {TEXT("hand"), TEXT("handl"), TEXT("hand_l"), TEXT("palm"), TEXT("lefthand"), TEXT("l_hand"), TEXT("left_hand")}},
        {TEXT("rightwrist"), {TEXT("hand"), TEXT("handr"), TEXT("hand_r"), TEXT("palm"), TEXT("righthand"), TEXT("r_hand"), TEXT("right_hand")}},
        {TEXT("wrist"), {TEXT("hand"), TEXT("palm"), TEXT("metacarpal")}},
        {TEXT("hand"), {TEXT("wrist"), TEXT("palm")}},
        {TEXT("handl"), {TEXT("leftwrist"), TEXT("hand_l"), TEXT("lefthand"), TEXT("l_hand"), TEXT("left_hand")}},
        {TEXT("handr"), {TEXT("rightwrist"), TEXT("hand_r"), TEXT("righthand"), TEXT("r_hand"), TEXT("right_hand")}},
        {TEXT("hand_l"), {TEXT("leftwrist"), TEXT("handl"), TEXT("lefthand"), TEXT("l_hand"), TEXT("left_hand")}},
        {TEXT("hand_r"), {TEXT("rightwrist"), TEXT("handr"), TEXT("righthand"), TEXT("r_hand"), TEXT("right_hand")}},
        {TEXT("lefthand"), {TEXT("leftwrist"), TEXT("handl"), TEXT("hand_l"), TEXT("l_hand"), TEXT("left_hand")}},
        {TEXT("righthand"), {TEXT("rightwrist"), TEXT("handr"), TEXT("hand_r"), TEXT("r_hand"), TEXT("right_hand")}},

        {TEXT("leftfinger0"), {TEXT("thumb"), TEXT("thumb1"), TEXT("thumb01"), TEXT("thumb_01"), TEXT("thumbl"), TEXT("thumb_01_l"), TEXT("l_thumb_01"), TEXT("lefthandthumb1"), TEXT("lefthandthumb01"), TEXT("thumbproximall"), TEXT("thumbproximal_l")}},
        {TEXT("rightfinger0"), {TEXT("thumb"), TEXT("thumb1"), TEXT("thumb01"), TEXT("thumb_01"), TEXT("thumbr"), TEXT("thumb_01_r"), TEXT("r_thumb_01"), TEXT("righthandthumb1"), TEXT("righthandthumb01"), TEXT("thumbproximalr"), TEXT("thumbproximal_r")}},
        {TEXT("finger0"), {TEXT("thumb"), TEXT("thumb1"), TEXT("thumb01"), TEXT("thumb_01"), TEXT("thumbproximal"), TEXT("handthumb1")}},
        {TEXT("thumb"), {TEXT("finger0"), TEXT("thumb1"), TEXT("thumb01"), TEXT("thumb_01")}},
        {TEXT("thumb1"), {TEXT("finger0"), TEXT("leftfinger0"), TEXT("rightfinger0"), TEXT("thumb01"), TEXT("thumb_01")}},
        {TEXT("thumb01"), {TEXT("finger0"), TEXT("thumb"), TEXT("thumb1"), TEXT("thumb_01")}},
        {TEXT("thumb_01"), {TEXT("finger0"), TEXT("thumb"), TEXT("thumb1"), TEXT("thumb01")}},
        {TEXT("thumb_01_l"), {TEXT("leftfinger0"), TEXT("thumbl"), TEXT("l_thumb_01"), TEXT("left_thumb_01"), TEXT("lefthandthumb1"), TEXT("thumbproximall")}},
        {TEXT("thumb_01_r"), {TEXT("rightfinger0"), TEXT("thumbr"), TEXT("r_thumb_01"), TEXT("right_thumb_01"), TEXT("righthandthumb1"), TEXT("thumbproximalr")}},
        {TEXT("lefthandthumb1"), {TEXT("leftfinger0"), TEXT("thumbl"), TEXT("thumb_01_l"), TEXT("l_thumb_01"), TEXT("thumbproximall")}},
        {TEXT("righthandthumb1"), {TEXT("rightfinger0"), TEXT("thumbr"), TEXT("thumb_01_r"), TEXT("r_thumb_01"), TEXT("thumbproximalr")}},
        {TEXT("handthumb1"), {TEXT("finger0"), TEXT("thumb1"), TEXT("thumb01"), TEXT("thumb_01")}},
        {TEXT("thumbproximal"), {TEXT("finger0"), TEXT("thumb1"), TEXT("thumb01"), TEXT("thumb_01")}},
        {TEXT("thumbproximall"), {TEXT("leftfinger0"), TEXT("thumb_01_l"), TEXT("l_thumb_01"), TEXT("lefthandthumb1")}},
        {TEXT("thumbproximalr"), {TEXT("rightfinger0"), TEXT("thumb_01_r"), TEXT("r_thumb_01"), TEXT("righthandthumb1")}},
        
        {TEXT("leftfinger01"), {TEXT("thumb2"), TEXT("thumb02"), TEXT("thumb_02"), TEXT("thumb_02_l"), TEXT("l_thumb_02"), TEXT("lefthandthumb2"), TEXT("lefthandthumb02"), TEXT("thumbintermediatel"), TEXT("thumbintermediate_l")}},
        {TEXT("rightfinger01"), {TEXT("thumb2"), TEXT("thumb02"), TEXT("thumb_02"), TEXT("thumb_02_r"), TEXT("r_thumb_02"), TEXT("righthandthumb2"), TEXT("righthandthumb02"), TEXT("thumbintermediater"), TEXT("thumbintermediate_r")}},
        {TEXT("finger01"), {TEXT("thumb2"), TEXT("thumb02"), TEXT("thumb_02"), TEXT("thumbmedial"), TEXT("thumbintermediate"), TEXT("handthumb2")}},
        {TEXT("thumb2"), {TEXT("finger01"), TEXT("leftfinger01"), TEXT("rightfinger01"), TEXT("thumb02"), TEXT("thumb_02")}},
        {TEXT("thumb02"), {TEXT("finger01"), TEXT("thumb2"), TEXT("thumb_02")}},
        {TEXT("thumb_02"), {TEXT("finger01"), TEXT("thumb2"), TEXT("thumb02")}},
        {TEXT("thumb_02_l"), {TEXT("leftfinger01"), TEXT("l_thumb_02"), TEXT("left_thumb_02"), TEXT("lefthandthumb2"), TEXT("thumbintermediatel")}},
        {TEXT("thumb_02_r"), {TEXT("rightfinger01"), TEXT("r_thumb_02"), TEXT("right_thumb_02"), TEXT("righthandthumb2"), TEXT("thumbintermediater")}},
        {TEXT("lefthandthumb2"), {TEXT("leftfinger01"), TEXT("thumb_02_l"), TEXT("l_thumb_02"), TEXT("thumbintermediatel")}},
        {TEXT("righthandthumb2"), {TEXT("rightfinger01"), TEXT("thumb_02_r"), TEXT("r_thumb_02"), TEXT("thumbintermediater")}},
        {TEXT("handthumb2"), {TEXT("finger01"), TEXT("thumb2"), TEXT("thumb02"), TEXT("thumb_02")}},
        {TEXT("thumbintermediate"), {TEXT("finger01"), TEXT("thumb2"), TEXT("thumb02"), TEXT("thumb_02")}},
        {TEXT("thumbintermediatel"), {TEXT("leftfinger01"), TEXT("thumb_02_l"), TEXT("l_thumb_02"), TEXT("lefthandthumb2")}},
        {TEXT("thumbintermediater"), {TEXT("rightfinger01"), TEXT("thumb_02_r"), TEXT("r_thumb_02"), TEXT("righthandthumb2")}},
        
        {TEXT("leftfinger02"), {TEXT("thumb3"), TEXT("thumb03"), TEXT("thumb_03"), TEXT("thumb_03_l"), TEXT("l_thumb_03"), TEXT("lefthandthumb3"), TEXT("lefthandthumb03"), TEXT("thumbdistall"), TEXT("thumbdistal_l")}},
        {TEXT("rightfinger02"), {TEXT("thumb3"), TEXT("thumb03"), TEXT("thumb_03"), TEXT("thumb_03_r"), TEXT("r_thumb_03"), TEXT("righthandthumb3"), TEXT("righthandthumb03"), TEXT("thumbdistalr"), TEXT("thumbdistal_r")}},
        {TEXT("finger02"), {TEXT("thumb3"), TEXT("thumb03"), TEXT("thumb_03"), TEXT("thumbdistal"), TEXT("handthumb3")}},
        {TEXT("thumb3"), {TEXT("finger02"), TEXT("leftfinger02"), TEXT("rightfinger02"), TEXT("thumb03"), TEXT("thumb_03")}},
        {TEXT("thumb03"), {TEXT("finger02"), TEXT("thumb3"), TEXT("thumb_03")}},
        {TEXT("thumb_03"), {TEXT("finger02"), TEXT("thumb3"), TEXT("thumb03")}},
        {TEXT("thumb_03_l"), {TEXT("leftfinger02"), TEXT("l_thumb_03"), TEXT("left_thumb_03"), TEXT("lefthandthumb3"), TEXT("thumbdistall")}},
        {TEXT("thumb_03_r"), {TEXT("rightfinger02"), TEXT("r_thumb_03"), TEXT("right_thumb_03"), TEXT("righthandthumb3"), TEXT("thumbdistalr")}},
        {TEXT("lefthandthumb3"), {TEXT("leftfinger02"), TEXT("thumb_03_l"), TEXT("l_thumb_03"), TEXT("thumbdistall")}},
        {TEXT("righthandthumb3"), {TEXT("rightfinger02"), TEXT("thumb_03_r"), TEXT("r_thumb_03"), TEXT("thumbdistalr")}},
        {TEXT("handthumb3"), {TEXT("finger02"), TEXT("thumb3"), TEXT("thumb03"), TEXT("thumb_03")}},
        {TEXT("thumbdistal"), {TEXT("finger02"), TEXT("thumb3"), TEXT("thumb03"), TEXT("thumb_03")}},
        {TEXT("thumbdistall"), {TEXT("leftfinger02"), TEXT("thumb_03_l"), TEXT("l_thumb_03"), TEXT("lefthandthumb3")}},
        {TEXT("thumbdistalr"), {TEXT("rightfinger02"), TEXT("thumb_03_r"), TEXT("r_thumb_03"), TEXT("righthandthumb3")}},

        {TEXT("leftfinger1"), {TEXT("index"), TEXT("index1"), TEXT("index01"), TEXT("index_01"), TEXT("indexl"), TEXT("index_01_l"), TEXT("l_index_01"), TEXT("lefthandindex1"), TEXT("lefthandindex01"), TEXT("indexproximall"), TEXT("indexproximal_l")}},
        {TEXT("rightfinger1"), {TEXT("index"), TEXT("index1"), TEXT("index01"), TEXT("index_01"), TEXT("indexr"), TEXT("index_01_r"), TEXT("r_index_01"), TEXT("righthandindex1"), TEXT("righthandindex01"), TEXT("indexproximalr"), TEXT("indexproximal_r")}},
        {TEXT("finger1"), {TEXT("index"), TEXT("index1"), TEXT("index01"), TEXT("index_01"), TEXT("indexproximal"), TEXT("pointer"), TEXT("handindex1")}},
        {TEXT("index"), {TEXT("finger1"), TEXT("index1"), TEXT("index01"), TEXT("index_01")}},
        {TEXT("index1"), {TEXT("finger1"), TEXT("leftfinger1"), TEXT("rightfinger1"), TEXT("index01"), TEXT("index_01")}},
        {TEXT("index01"), {TEXT("finger1"), TEXT("index"), TEXT("index1"), TEXT("index_01")}},
        {TEXT("index_01"), {TEXT("finger1"), TEXT("index"), TEXT("index1"), TEXT("index01")}},
        {TEXT("index_01_l"), {TEXT("leftfinger1"), TEXT("indexl"), TEXT("l_index_01"), TEXT("left_index_01"), TEXT("lefthandindex1"), TEXT("indexproximall")}},
        {TEXT("index_01_r"), {TEXT("rightfinger1"), TEXT("indexr"), TEXT("r_index_01"), TEXT("right_index_01"), TEXT("righthandindex1"), TEXT("indexproximalr")}},
        {TEXT("lefthandindex1"), {TEXT("leftfinger1"), TEXT("indexl"), TEXT("index_01_l"), TEXT("l_index_01"), TEXT("indexproximall")}},
        {TEXT("righthandindex1"), {TEXT("rightfinger1"), TEXT("indexr"), TEXT("index_01_r"), TEXT("r_index_01"), TEXT("indexproximalr")}},
        {TEXT("handindex1"), {TEXT("finger1"), TEXT("index1"), TEXT("index01"), TEXT("index_01")}},
        {TEXT("indexproximal"), {TEXT("finger1"), TEXT("index1"), TEXT("index01"), TEXT("index_01")}},
        {TEXT("indexproximall"), {TEXT("leftfinger1"), TEXT("index_01_l"), TEXT("l_index_01"), TEXT("lefthandindex1")}},
        {TEXT("indexproximalr"), {TEXT("rightfinger1"), TEXT("index_01_r"), TEXT("r_index_01"), TEXT("righthandindex1")}},
        
        {TEXT("leftfinger11"), {TEXT("index2"), TEXT("index02"), TEXT("index_02"), TEXT("index_02_l"), TEXT("l_index_02"), TEXT("lefthandindex2"), TEXT("lefthandindex02"), TEXT("indexintermediatel"), TEXT("indexintermediate_l")}},
        {TEXT("rightfinger11"), {TEXT("index2"), TEXT("index02"), TEXT("index_02"), TEXT("index_02_r"), TEXT("r_index_02"), TEXT("righthandindex2"), TEXT("righthandindex02"), TEXT("indexintermediater"), TEXT("indexintermediate_r")}},
        {TEXT("finger11"), {TEXT("index2"), TEXT("index02"), TEXT("index_02"), TEXT("indexmedial"), TEXT("indexintermediate"), TEXT("handindex2")}},
        {TEXT("index2"), {TEXT("finger11"), TEXT("leftfinger11"), TEXT("rightfinger11"), TEXT("index02"), TEXT("index_02")}},
        {TEXT("index02"), {TEXT("finger11"), TEXT("index2"), TEXT("index_02")}},
        {TEXT("index_02"), {TEXT("finger11"), TEXT("index2"), TEXT("index02")}},
        {TEXT("index_02_l"), {TEXT("leftfinger11"), TEXT("l_index_02"), TEXT("left_index_02"), TEXT("lefthandindex2"), TEXT("indexintermediatel")}},
        {TEXT("index_02_r"), {TEXT("rightfinger11"), TEXT("r_index_02"), TEXT("right_index_02"), TEXT("righthandindex2"), TEXT("indexintermediater")}},
        {TEXT("lefthandindex2"), {TEXT("leftfinger11"), TEXT("index_02_l"), TEXT("l_index_02"), TEXT("indexintermediatel")}},
        {TEXT("righthandindex2"), {TEXT("rightfinger11"), TEXT("index_02_r"), TEXT("r_index_02"), TEXT("indexintermediater")}},
        {TEXT("handindex2"), {TEXT("finger11"), TEXT("index2"), TEXT("index02"), TEXT("index_02")}},
        {TEXT("indexintermediate"), {TEXT("finger11"), TEXT("index2"), TEXT("index02"), TEXT("index_02")}},
        {TEXT("indexintermediatel"), {TEXT("leftfinger11"), TEXT("index_02_l"), TEXT("l_index_02"), TEXT("lefthandindex2")}},
        {TEXT("indexintermediater"), {TEXT("rightfinger11"), TEXT("index_02_r"), TEXT("r_index_02"), TEXT("righthandindex2")}},
        
        {TEXT("leftfinger12"), {TEXT("index3"), TEXT("index03"), TEXT("index_03"), TEXT("index_03_l"), TEXT("l_index_03"), TEXT("lefthandindex3"), TEXT("lefthandindex03"), TEXT("indexdistall"), TEXT("indexdistal_l")}},
        {TEXT("rightfinger12"), {TEXT("index3"), TEXT("index03"), TEXT("index_03"), TEXT("index_03_r"), TEXT("r_index_03"), TEXT("righthandindex3"), TEXT("righthandindex03"), TEXT("indexdistalr"), TEXT("indexdistal_r")}},
        {TEXT("finger12"), {TEXT("index3"), TEXT("index03"), TEXT("index_03"), TEXT("indexdistal"), TEXT("handindex3")}},
        {TEXT("index3"), {TEXT("finger12"), TEXT("leftfinger12"), TEXT("rightfinger12"), TEXT("index03"), TEXT("index_03")}},
        {TEXT("index03"), {TEXT("finger12"), TEXT("index3"), TEXT("index_03")}},
        {TEXT("index_03"), {TEXT("finger12"), TEXT("index3"), TEXT("index03")}},
        {TEXT("index_03_l"), {TEXT("leftfinger12"), TEXT("l_index_03"), TEXT("left_index_03"), TEXT("lefthandindex3"), TEXT("indexdistall")}},
        {TEXT("index_03_r"), {TEXT("rightfinger12"), TEXT("r_index_03"), TEXT("right_index_03"), TEXT("righthandindex3"), TEXT("indexdistalr")}},
        {TEXT("lefthandindex3"), {TEXT("leftfinger12"), TEXT("index_03_l"), TEXT("l_index_03"), TEXT("indexdistall")}},
        {TEXT("righthandindex3"), {TEXT("rightfinger12"), TEXT("index_03_r"), TEXT("r_index_03"), TEXT("indexdistalr")}},
        {TEXT("handindex3"), {TEXT("finger12"), TEXT("index3"), TEXT("index03"), TEXT("index_03")}},
        {TEXT("indexdistal"), {TEXT("finger12"), TEXT("index3"), TEXT("index03"), TEXT("index_03")}},
        {TEXT("indexdistall"), {TEXT("leftfinger12"), TEXT("index_03_l"), TEXT("l_index_03"), TEXT("lefthandindex3")}},
        {TEXT("indexdistalr"), {TEXT("rightfinger12"), TEXT("index_03_r"), TEXT("r_index_03"), TEXT("righthandindex3")}},

        {TEXT("leftfinger2"), {TEXT("middle"), TEXT("middle1"), TEXT("middle01"), TEXT("middle_01"), TEXT("middlel"), TEXT("middle_01_l"), TEXT("l_middle_01"), TEXT("lefthandmiddle1"), TEXT("lefthandmiddle01"), TEXT("mid1"), TEXT("midl"), TEXT("mid_l"), TEXT("l_mid1"), TEXT("lmid1"), TEXT("mid_01_l")}},
        {TEXT("rightfinger2"), {TEXT("middle"), TEXT("middle1"), TEXT("middle01"), TEXT("middle_01"), TEXT("middler"), TEXT("middle_01_r"), TEXT("r_middle_01"), TEXT("righthandmiddle1"), TEXT("righthandmiddle01"), TEXT("mid1"), TEXT("midr"), TEXT("mid_r"), TEXT("r_mid1"), TEXT("rmid1"), TEXT("mid_01_r")}},
        {TEXT("finger2"), {TEXT("middle"), TEXT("middle1"), TEXT("middle01"), TEXT("middle_01"), TEXT("middleproximal"), TEXT("mid"), TEXT("mid1"), TEXT("handmiddle1")}},
        {TEXT("middle"), {TEXT("finger2"), TEXT("middle1"), TEXT("middle01"), TEXT("middle_01"), TEXT("mid")}},
        {TEXT("middle1"), {TEXT("finger2"), TEXT("leftfinger2"), TEXT("rightfinger2"), TEXT("middle01"), TEXT("middle_01"), TEXT("mid1")}},
        {TEXT("middle01"), {TEXT("finger2"), TEXT("middle"), TEXT("middle1"), TEXT("middle_01"), TEXT("mid1")}},
        {TEXT("middle_01"), {TEXT("finger2"), TEXT("middle"), TEXT("middle1"), TEXT("middle01"), TEXT("mid1")}},
        {TEXT("middle_01_l"), {TEXT("leftfinger2"), TEXT("middlel"), TEXT("l_middle_01"), TEXT("left_middle_01"), TEXT("lefthandmiddle1"), TEXT("l_mid1"), TEXT("lmid1")}},
        {TEXT("middle_01_r"), {TEXT("rightfinger2"), TEXT("middler"), TEXT("r_middle_01"), TEXT("right_middle_01"), TEXT("righthandmiddle1"), TEXT("r_mid1"), TEXT("rmid1")}},
        {TEXT("lefthandmiddle1"), {TEXT("leftfinger2"), TEXT("middlel"), TEXT("middle_01_l"), TEXT("l_middle_01"), TEXT("l_mid1")}},
        {TEXT("righthandmiddle1"), {TEXT("rightfinger2"), TEXT("middler"), TEXT("middle_01_r"), TEXT("r_middle_01"), TEXT("r_mid1")}},
        {TEXT("handmiddle1"), {TEXT("finger2"), TEXT("middle1"), TEXT("middle01"), TEXT("middle_01"), TEXT("mid1")}},
        {TEXT("mid"), {TEXT("middle"), TEXT("finger2")}},
        {TEXT("mid1"), {TEXT("middle1"), TEXT("leftfinger2"), TEXT("rightfinger2")}},
        {TEXT("lmid1"), {TEXT("leftfinger2"), TEXT("l_mid1"), TEXT("middle_01_l")}},
        {TEXT("rmid1"), {TEXT("rightfinger2"), TEXT("r_mid1"), TEXT("middle_01_r")}},
        {TEXT("l_mid1"), {TEXT("leftfinger2"), TEXT("lmid1"), TEXT("middle_01_l")}},
        {TEXT("r_mid1"), {TEXT("rightfinger2"), TEXT("rmid1"), TEXT("middle_01_r")}},
        
        {TEXT("leftfinger21"), {TEXT("middle2"), TEXT("middle02"), TEXT("middle_02"), TEXT("middle_02_l"), TEXT("l_middle_02"), TEXT("lefthandmiddle2"), TEXT("lefthandmiddle02"), TEXT("mid2"), TEXT("l_mid2"), TEXT("lmid2")}},
        {TEXT("rightfinger21"), {TEXT("middle2"), TEXT("middle02"), TEXT("middle_02"), TEXT("middle_02_r"), TEXT("r_middle_02"), TEXT("righthandmiddle2"), TEXT("righthandmiddle02"), TEXT("mid2"), TEXT("r_mid2"), TEXT("rmid2")}},
        {TEXT("finger21"), {TEXT("middle2"), TEXT("middle02"), TEXT("middle_02"), TEXT("middlemedial"), TEXT("handmiddle2"), TEXT("mid2")}},
        {TEXT("middle2"), {TEXT("finger21"), TEXT("leftfinger21"), TEXT("rightfinger21"), TEXT("middle02"), TEXT("middle_02"), TEXT("mid2")}},
        {TEXT("middle02"), {TEXT("finger21"), TEXT("middle2"), TEXT("middle_02"), TEXT("mid2")}},
        {TEXT("middle_02"), {TEXT("finger21"), TEXT("middle2"), TEXT("middle02"), TEXT("mid2")}},
        {TEXT("middle_02_l"), {TEXT("leftfinger21"), TEXT("l_middle_02"), TEXT("left_middle_02"), TEXT("lefthandmiddle2"), TEXT("l_mid2")}},
        {TEXT("middle_02_r"), {TEXT("rightfinger21"), TEXT("r_middle_02"), TEXT("right_middle_02"), TEXT("righthandmiddle2"), TEXT("r_mid2")}},
        {TEXT("lefthandmiddle2"), {TEXT("leftfinger21"), TEXT("middle_02_l"), TEXT("l_middle_02"), TEXT("l_mid2")}},
        {TEXT("righthandmiddle2"), {TEXT("rightfinger21"), TEXT("middle_02_r"), TEXT("r_middle_02"), TEXT("r_mid2")}},
        {TEXT("handmiddle2"), {TEXT("finger21"), TEXT("middle2"), TEXT("middle02"), TEXT("middle_02"), TEXT("mid2")}},
        {TEXT("mid2"), {TEXT("middle2"), TEXT("leftfinger21"), TEXT("rightfinger21")}},
        {TEXT("lmid2"), {TEXT("leftfinger21"), TEXT("l_mid2"), TEXT("middle_02_l")}},
        {TEXT("rmid2"), {TEXT("rightfinger21"), TEXT("r_mid2"), TEXT("middle_02_r")}},
        {TEXT("l_mid2"), {TEXT("leftfinger21"), TEXT("lmid2"), TEXT("middle_02_l")}},
        {TEXT("r_mid2"), {TEXT("rightfinger21"), TEXT("rmid2"), TEXT("middle_02_r")}},
        
        {TEXT("leftfinger22"), {TEXT("middle3"), TEXT("middle03"), TEXT("middle_03"), TEXT("middle_03_l"), TEXT("l_middle_03"), TEXT("lefthandmiddle3"), TEXT("lefthandmiddle03"), TEXT("mid3"), TEXT("l_mid3"), TEXT("lmid3")}},
        {TEXT("rightfinger22"), {TEXT("middle3"), TEXT("middle03"), TEXT("middle_03"), TEXT("middle_03_r"), TEXT("r_middle_03"), TEXT("righthandmiddle3"), TEXT("righthandmiddle03"), TEXT("mid3"), TEXT("r_mid3"), TEXT("rmid3")}},
        {TEXT("finger22"), {TEXT("middle3"), TEXT("middle03"), TEXT("middle_03"), TEXT("middledistal"), TEXT("handmiddle3"), TEXT("mid3")}},
        {TEXT("middle3"), {TEXT("finger22"), TEXT("leftfinger22"), TEXT("rightfinger22"), TEXT("middle03"), TEXT("middle_03"), TEXT("mid3")}},
        {TEXT("middle03"), {TEXT("finger22"), TEXT("middle3"), TEXT("middle_03"), TEXT("mid3")}},
        {TEXT("middle_03"), {TEXT("finger22"), TEXT("middle3"), TEXT("middle03"), TEXT("mid3")}},
        {TEXT("middle_03_l"), {TEXT("leftfinger22"), TEXT("l_middle_03"), TEXT("left_middle_03"), TEXT("lefthandmiddle3"), TEXT("l_mid3")}},
        {TEXT("middle_03_r"), {TEXT("rightfinger22"), TEXT("r_middle_03"), TEXT("right_middle_03"), TEXT("righthandmiddle3"), TEXT("r_mid3")}},
        {TEXT("lefthandmiddle3"), {TEXT("leftfinger22"), TEXT("middle_03_l"), TEXT("l_middle_03"), TEXT("l_mid3")}},
        {TEXT("righthandmiddle3"), {TEXT("rightfinger22"), TEXT("middle_03_r"), TEXT("r_middle_03"), TEXT("r_mid3")}},
        {TEXT("handmiddle3"), {TEXT("finger22"), TEXT("middle3"), TEXT("middle03"), TEXT("middle_03"), TEXT("mid3")}},
        {TEXT("mid3"), {TEXT("middle3"), TEXT("leftfinger22"), TEXT("rightfinger22")}},
        {TEXT("lmid3"), {TEXT("leftfinger22"), TEXT("l_mid3"), TEXT("middle_03_l")}},
        {TEXT("rmid3"), {TEXT("rightfinger22"), TEXT("r_mid3"), TEXT("middle_03_r")}},
        {TEXT("l_mid3"), {TEXT("leftfinger22"), TEXT("lmid3"), TEXT("middle_03_l")}},
        {TEXT("r_mid3"), {TEXT("rightfinger22"), TEXT("rmid3"), TEXT("middle_03_r")}},

        {TEXT("leftfinger3"), {TEXT("ring"), TEXT("ring1"), TEXT("ring01"), TEXT("ring_01"), TEXT("ringl"), TEXT("ring_01_l"), TEXT("l_ring_01"), TEXT("lefthandring1"), TEXT("lefthandring01"), TEXT("l_ring1"), TEXT("lring1")}},
        {TEXT("rightfinger3"), {TEXT("ring"), TEXT("ring1"), TEXT("ring01"), TEXT("ring_01"), TEXT("ringr"), TEXT("ring_01_r"), TEXT("r_ring_01"), TEXT("righthandring1"), TEXT("righthandring01"), TEXT("r_ring1"), TEXT("rring1")}},
        {TEXT("finger3"), {TEXT("ring"), TEXT("ring1"), TEXT("ring01"), TEXT("ring_01"), TEXT("ringproximal"), TEXT("handring1")}},
        {TEXT("ring"), {TEXT("finger3"), TEXT("ring1"), TEXT("ring01"), TEXT("ring_01")}},
        {TEXT("ring1"), {TEXT("finger3"), TEXT("leftfinger3"), TEXT("rightfinger3"), TEXT("ring01"), TEXT("ring_01")}},
        {TEXT("ring01"), {TEXT("finger3"), TEXT("ring"), TEXT("ring1"), TEXT("ring_01")}},
        {TEXT("ring_01"), {TEXT("finger3"), TEXT("ring"), TEXT("ring1"), TEXT("ring01")}},
        {TEXT("ring_01_l"), {TEXT("leftfinger3"), TEXT("ringl"), TEXT("l_ring_01"), TEXT("left_ring_01"), TEXT("lefthandring1"), TEXT("l_ring1")}},
        {TEXT("ring_01_r"), {TEXT("rightfinger3"), TEXT("ringr"), TEXT("r_ring_01"), TEXT("right_ring_01"), TEXT("righthandring1"), TEXT("r_ring1")}},
        {TEXT("lefthandring1"), {TEXT("leftfinger3"), TEXT("ringl"), TEXT("ring_01_l"), TEXT("l_ring_01"), TEXT("l_ring1")}},
        {TEXT("righthandring1"), {TEXT("rightfinger3"), TEXT("ringr"), TEXT("ring_01_r"), TEXT("r_ring_01"), TEXT("r_ring1")}},
        {TEXT("handring1"), {TEXT("finger3"), TEXT("ring1"), TEXT("ring01"), TEXT("ring_01")}},
        {TEXT("l_ring1"), {TEXT("leftfinger3"), TEXT("lring1"), TEXT("ring_01_l")}},
        {TEXT("r_ring1"), {TEXT("rightfinger3"), TEXT("rring1"), TEXT("ring_01_r")}},
        {TEXT("lring1"), {TEXT("leftfinger3"), TEXT("l_ring1"), TEXT("ring_01_l")}},
        {TEXT("rring1"), {TEXT("rightfinger3"), TEXT("r_ring1"), TEXT("ring_01_r")}},
        
        {TEXT("leftfinger31"), {TEXT("ring2"), TEXT("ring02"), TEXT("ring_02"), TEXT("ring_02_l"), TEXT("l_ring_02"), TEXT("lefthandring2"), TEXT("lefthandring02"), TEXT("l_ring2"), TEXT("lring2")}},
        {TEXT("rightfinger31"), {TEXT("ring2"), TEXT("ring02"), TEXT("ring_02"), TEXT("ring_02_r"), TEXT("r_ring_02"), TEXT("righthandring2"), TEXT("righthandring02"), TEXT("r_ring2"), TEXT("rring2")}},
        {TEXT("finger31"), {TEXT("ring2"), TEXT("ring02"), TEXT("ring_02"), TEXT("ringmedial"), TEXT("handring2")}},
        {TEXT("ring2"), {TEXT("finger31"), TEXT("leftfinger31"), TEXT("rightfinger31"), TEXT("ring02"), TEXT("ring_02")}},
        {TEXT("ring02"), {TEXT("finger31"), TEXT("ring2"), TEXT("ring_02")}},
        {TEXT("ring_02"), {TEXT("finger31"), TEXT("ring2"), TEXT("ring02")}},
        {TEXT("ring_02_l"), {TEXT("leftfinger31"), TEXT("l_ring_02"), TEXT("left_ring_02"), TEXT("lefthandring2"), TEXT("l_ring2")}},
        {TEXT("ring_02_r"), {TEXT("rightfinger31"), TEXT("r_ring_02"), TEXT("right_ring_02"), TEXT("righthandring2"), TEXT("r_ring2")}},
        {TEXT("lefthandring2"), {TEXT("leftfinger31"), TEXT("ring_02_l"), TEXT("l_ring_02"), TEXT("l_ring2")}},
        {TEXT("righthandring2"), {TEXT("rightfinger31"), TEXT("ring_02_r"), TEXT("r_ring_02"), TEXT("r_ring2")}},
        {TEXT("handring2"), {TEXT("finger31"), TEXT("ring2"), TEXT("ring02"), TEXT("ring_02")}},
        {TEXT("l_ring2"), {TEXT("leftfinger31"), TEXT("lring2"), TEXT("ring_02_l")}},
        {TEXT("r_ring2"), {TEXT("rightfinger31"), TEXT("rring2"), TEXT("ring_02_r")}},
        {TEXT("lring2"), {TEXT("leftfinger31"), TEXT("l_ring2"), TEXT("ring_02_l")}},
        {TEXT("rring2"), {TEXT("rightfinger31"), TEXT("r_ring2"), TEXT("ring_02_r")}},
        
        {TEXT("leftfinger32"), {TEXT("ring3"), TEXT("ring03"), TEXT("ring_03"), TEXT("ring_03_l"), TEXT("l_ring_03"), TEXT("lefthandring3"), TEXT("lefthandring03"), TEXT("l_ring3"), TEXT("lring3")}},
        {TEXT("rightfinger32"), {TEXT("ring3"), TEXT("ring03"), TEXT("ring_03"), TEXT("ring_03_r"), TEXT("r_ring_03"), TEXT("righthandring3"), TEXT("righthandring03"), TEXT("r_ring3"), TEXT("rring3")}},
        {TEXT("finger32"), {TEXT("ring3"), TEXT("ring03"), TEXT("ring_03"), TEXT("ringdistal"), TEXT("handring3")}},
        {TEXT("ring3"), {TEXT("finger32"), TEXT("leftfinger32"), TEXT("rightfinger32"), TEXT("ring03"), TEXT("ring_03")}},
        {TEXT("ring03"), {TEXT("finger32"), TEXT("ring3"), TEXT("ring_03")}},
        {TEXT("ring_03"), {TEXT("finger32"), TEXT("ring3"), TEXT("ring03")}},
        {TEXT("ring_03_l"), {TEXT("leftfinger32"), TEXT("l_ring_03"), TEXT("left_ring_03"), TEXT("lefthandring3"), TEXT("l_ring3")}},
        {TEXT("ring_03_r"), {TEXT("rightfinger32"), TEXT("r_ring_03"), TEXT("right_ring_03"), TEXT("righthandring3"), TEXT("r_ring3")}},
        {TEXT("lefthandring3"), {TEXT("leftfinger32"), TEXT("ring_03_l"), TEXT("l_ring_03"), TEXT("l_ring3")}},
        {TEXT("righthandring3"), {TEXT("rightfinger32"), TEXT("ring_03_r"), TEXT("r_ring_03"), TEXT("r_ring3")}},
        {TEXT("l_ring3"), {TEXT("leftfinger32"), TEXT("lring3"), TEXT("ring_03_l")}},
        {TEXT("r_ring3"), {TEXT("rightfinger32"), TEXT("rring3"), TEXT("ring_03_r")}},
        {TEXT("lring3"), {TEXT("leftfinger32"), TEXT("l_ring3"), TEXT("ring_03_l")}},
        {TEXT("rring3"), {TEXT("rightfinger32"), TEXT("r_ring3"), TEXT("ring_03_r")}},
        {TEXT("handring3"), {TEXT("finger32"), TEXT("ring3"), TEXT("ring03"), TEXT("ring_03")}},

        {TEXT("leftfinger4"), {TEXT("pinky"), TEXT("pinky1"), TEXT("pinky01"), TEXT("pinky_01"), TEXT("pinkyl"), TEXT("pinky_01_l"), TEXT("l_pinky_01"), TEXT("little"), TEXT("lefthandpinky1"), TEXT("lefthandpinky01"), TEXT("littleproximall"), TEXT("littleproximal_l"), TEXT("pinkyproximall")}},
        {TEXT("rightfinger4"), {TEXT("pinky"), TEXT("pinky1"), TEXT("pinky01"), TEXT("pinky_01"), TEXT("pinkyr"), TEXT("pinky_01_r"), TEXT("r_pinky_01"), TEXT("little"), TEXT("righthandpinky1"), TEXT("righthandpinky01"), TEXT("littleproximalr"), TEXT("littleproximal_r"), TEXT("pinkyproximalr")}},
        {TEXT("finger4"), {TEXT("pinky"), TEXT("pinky1"), TEXT("pinky01"), TEXT("pinky_01"), TEXT("pinkyproximal"), TEXT("little"), TEXT("littleproximal"), TEXT("handpinky1")}},
        {TEXT("pinky"), {TEXT("finger4"), TEXT("pinky1"), TEXT("pinky01"), TEXT("pinky_01"), TEXT("little")}},
        {TEXT("little"), {TEXT("pinky"), TEXT("finger4"), TEXT("pinky1"), TEXT("pinky01"), TEXT("pinky_01")}},
        {TEXT("pinky1"), {TEXT("finger4"), TEXT("leftfinger4"), TEXT("rightfinger4"), TEXT("pinky01"), TEXT("pinky_01")}},
        {TEXT("pinky01"), {TEXT("finger4"), TEXT("pinky"), TEXT("pinky1"), TEXT("pinky_01")}},
        {TEXT("pinky_01"), {TEXT("finger4"), TEXT("pinky"), TEXT("pinky1"), TEXT("pinky01")}},
        {TEXT("pinky_01_l"), {TEXT("leftfinger4"), TEXT("pinkyl"), TEXT("l_pinky_01"), TEXT("left_pinky_01"), TEXT("lefthandpinky1"), TEXT("littleproximall")}},
        {TEXT("pinky_01_r"), {TEXT("rightfinger4"), TEXT("pinkyr"), TEXT("r_pinky_01"), TEXT("right_pinky_01"), TEXT("righthandpinky1"), TEXT("littleproximalr")}},
        {TEXT("lefthandpinky1"), {TEXT("leftfinger4"), TEXT("pinkyl"), TEXT("pinky_01_l"), TEXT("l_pinky_01"), TEXT("littleproximall")}},
        {TEXT("righthandpinky1"), {TEXT("rightfinger4"), TEXT("pinkyr"), TEXT("pinky_01_r"), TEXT("r_pinky_01"), TEXT("littleproximalr")}},
        {TEXT("handpinky1"), {TEXT("finger4"), TEXT("pinky1"), TEXT("pinky01"), TEXT("pinky_01")}},
        {TEXT("littleproximal"), {TEXT("finger4"), TEXT("pinky1"), TEXT("pinky01"), TEXT("pinky_01"), TEXT("pinkyproximal")}},
        {TEXT("littleproximall"), {TEXT("leftfinger4"), TEXT("pinky_01_l"), TEXT("l_pinky_01"), TEXT("lefthandpinky1"), TEXT("pinkyproximall")}},
        {TEXT("littleproximalr"), {TEXT("rightfinger4"), TEXT("pinky_01_r"), TEXT("r_pinky_01"), TEXT("righthandpinky1"), TEXT("pinkyproximalr")}},
        {TEXT("pinkyproximal"), {TEXT("finger4"), TEXT("pinky1"), TEXT("pinky01"), TEXT("pinky_01"), TEXT("littleproximal")}},
        {TEXT("pinkyproximall"), {TEXT("leftfinger4"), TEXT("pinky_01_l"), TEXT("l_pinky_01"), TEXT("lefthandpinky1"), TEXT("littleproximall")}},
        {TEXT("pinkyproximalr"), {TEXT("rightfinger4"), TEXT("pinky_01_r"), TEXT("r_pinky_01"), TEXT("righthandpinky1"), TEXT("littleproximalr")}},
        
        {TEXT("leftfinger41"), {TEXT("pinky2"), TEXT("pinky02"), TEXT("pinky_02"), TEXT("pinky_02_l"), TEXT("l_pinky_02"), TEXT("lefthandpinky2"), TEXT("lefthandpinky02"), TEXT("littleintermediatel"), TEXT("littleintermediate_l"), TEXT("pinkyintermediatel")}},
        {TEXT("rightfinger41"), {TEXT("pinky2"), TEXT("pinky02"), TEXT("pinky_02"), TEXT("pinky_02_r"), TEXT("r_pinky_02"), TEXT("righthandpinky2"), TEXT("righthandpinky02"), TEXT("littleintermediater"), TEXT("littleintermediate_r"), TEXT("pinkyintermediater")}},
        {TEXT("finger41"), {TEXT("pinky2"), TEXT("pinky02"), TEXT("pinky_02"), TEXT("pinkymedial"), TEXT("pinkyintermediate"), TEXT("littleintermediate"), TEXT("handpinky2")}},
        {TEXT("pinky2"), {TEXT("finger41"), TEXT("leftfinger41"), TEXT("rightfinger41"), TEXT("pinky02"), TEXT("pinky_02")}},
        {TEXT("pinky02"), {TEXT("finger41"), TEXT("pinky2"), TEXT("pinky_02")}},
        {TEXT("pinky_02"), {TEXT("finger41"), TEXT("pinky2"), TEXT("pinky02")}},
        {TEXT("pinky_02_l"), {TEXT("leftfinger41"), TEXT("l_pinky_02"), TEXT("left_pinky_02"), TEXT("lefthandpinky2"), TEXT("littleintermediatel")}},
        {TEXT("pinky_02_r"), {TEXT("rightfinger41"), TEXT("r_pinky_02"), TEXT("right_pinky_02"), TEXT("righthandpinky2"), TEXT("littleintermediater")}},
        {TEXT("lefthandpinky2"), {TEXT("leftfinger41"), TEXT("pinky_02_l"), TEXT("l_pinky_02"), TEXT("littleintermediatel")}},
        {TEXT("righthandpinky2"), {TEXT("rightfinger41"), TEXT("pinky_02_r"), TEXT("r_pinky_02"), TEXT("littleintermediater")}},
        {TEXT("handpinky2"), {TEXT("finger41"), TEXT("pinky2"), TEXT("pinky02"), TEXT("pinky_02")}},
        {TEXT("littleintermediate"), {TEXT("finger41"), TEXT("pinky2"), TEXT("pinky02"), TEXT("pinky_02"), TEXT("pinkyintermediate")}},
        {TEXT("littleintermediatel"), {TEXT("leftfinger41"), TEXT("pinky_02_l"), TEXT("l_pinky_02"), TEXT("lefthandpinky2"), TEXT("pinkyintermediatel")}},
        {TEXT("littleintermediater"), {TEXT("rightfinger41"), TEXT("pinky_02_r"), TEXT("r_pinky_02"), TEXT("righthandpinky2"), TEXT("pinkyintermediater")}},
        {TEXT("pinkyintermediate"), {TEXT("finger41"), TEXT("pinky2"), TEXT("pinky02"), TEXT("pinky_02"), TEXT("littleintermediate")}},
        {TEXT("pinkyintermediatel"), {TEXT("leftfinger41"), TEXT("pinky_02_l"), TEXT("l_pinky_02"), TEXT("lefthandpinky2"), TEXT("littleintermediatel")}},
        {TEXT("pinkyintermediater"), {TEXT("rightfinger41"), TEXT("pinky_02_r"), TEXT("r_pinky_02"), TEXT("righthandpinky2"), TEXT("littleintermediater")}},
        
        {TEXT("leftfinger42"), {TEXT("pinky3"), TEXT("pinky03"), TEXT("pinky_03"), TEXT("pinky_03_l"), TEXT("l_pinky_03"), TEXT("lefthandpinky3"), TEXT("lefthandpinky03"), TEXT("littledistall"), TEXT("littledistal_l"), TEXT("pinkydistall")}},
        {TEXT("rightfinger42"), {TEXT("pinky3"), TEXT("pinky03"), TEXT("pinky_03"), TEXT("pinky_03_r"), TEXT("r_pinky_03"), TEXT("righthandpinky3"), TEXT("righthandpinky03"), TEXT("littledistalr"), TEXT("littledistal_r"), TEXT("pinkydistalr")}},
        {TEXT("finger42"), {TEXT("pinky3"), TEXT("pinky03"), TEXT("pinky_03"), TEXT("pinkydistal"), TEXT("littledistal"), TEXT("handpinky3")}},
        {TEXT("pinky3"), {TEXT("finger42"), TEXT("leftfinger42"), TEXT("rightfinger42"), TEXT("pinky03"), TEXT("pinky_03")}},
        {TEXT("pinky03"), {TEXT("finger42"), TEXT("pinky3"), TEXT("pinky_03")}},
        {TEXT("pinky_03"), {TEXT("finger42"), TEXT("pinky3"), TEXT("pinky03")}},
        {TEXT("pinky_03_l"), {TEXT("leftfinger42"), TEXT("l_pinky_03"), TEXT("left_pinky_03"), TEXT("lefthandpinky3"), TEXT("littledistall")}},
        {TEXT("pinky_03_r"), {TEXT("rightfinger42"), TEXT("r_pinky_03"), TEXT("right_pinky_03"), TEXT("righthandpinky3"), TEXT("littledistalr")}},
        {TEXT("lefthandpinky3"), {TEXT("leftfinger42"), TEXT("pinky_03_l"), TEXT("l_pinky_03"), TEXT("littledistall")}},
        {TEXT("righthandpinky3"), {TEXT("rightfinger42"), TEXT("pinky_03_r"), TEXT("r_pinky_03"), TEXT("littledistalr")}},
        {TEXT("handpinky3"), {TEXT("finger42"), TEXT("pinky3"), TEXT("pinky03"), TEXT("pinky_03")}},
        {TEXT("littledistal"), {TEXT("finger42"), TEXT("pinky3"), TEXT("pinky03"), TEXT("pinky_03"), TEXT("pinkydistal")}},
        {TEXT("littledistall"), {TEXT("leftfinger42"), TEXT("pinky_03_l"), TEXT("l_pinky_03"), TEXT("lefthandpinky3"), TEXT("pinkydistall")}},
        {TEXT("littledistalr"), {TEXT("rightfinger42"), TEXT("pinky_03_r"), TEXT("r_pinky_03"), TEXT("righthandpinky3"), TEXT("pinkydistalr")}},
        {TEXT("pinkydistal"), {TEXT("finger42"), TEXT("pinky3"), TEXT("pinky03"), TEXT("pinky_03"), TEXT("littledistal")}},
        {TEXT("pinkydistall"), {TEXT("leftfinger42"), TEXT("pinky_03_l"), TEXT("l_pinky_03"), TEXT("lefthandpinky3"), TEXT("littledistall")}},
        {TEXT("pinkydistalr"), {TEXT("rightfinger42"), TEXT("pinky_03_r"), TEXT("r_pinky_03"), TEXT("righthandpinky3"), TEXT("littledistalr")}}
    };
    
    return CommonMappings;
}

TArray<FString> FMoABoneNameMappings::GenerateVariations(const FString& BoneName)
{
    TArray<FString> Variations;
    Variations.Reserve(50);
    
    // Original name
    Variations.Add(BoneName);
    
    FString LowerName = BoneName.ToLower();
    
    TArray<TPair<FString, FString>> LeftRightPatterns = {
        {TEXT("left"), TEXT("l")},
        {TEXT("left"), TEXT("_l")},
        {TEXT("left"), TEXT(".l")},
        {TEXT("left"), TEXT("_left")},
        {TEXT("left"), TEXT("-l")},
        {TEXT("left"), TEXT(" l")},
        {TEXT("l_"), TEXT("left_")},
        {TEXT("l."), TEXT("left.")},
        {TEXT("_l"), TEXT("_left")},
        {TEXT(".l"), TEXT(".left")},
        {TEXT("right"), TEXT("r")},
        {TEXT("right"), TEXT("_r")},
        {TEXT("right"), TEXT(".r")},
        {TEXT("right"), TEXT("_right")},
        {TEXT("right"), TEXT("-r")},
        {TEXT("right"), TEXT(" r")},
        {TEXT("r_"), TEXT("right_")},
        {TEXT("r."), TEXT("right.")},
        {TEXT("_r"), TEXT("_right")},
        {TEXT(".r"), TEXT(".right")}
    };
    
    for (const auto& Pattern : LeftRightPatterns)
    {
        if (LowerName.Contains(Pattern.Key))
        {
            Variations.Add(BoneName.Replace(*Pattern.Key, *Pattern.Value, ESearchCase::IgnoreCase));
        }
    }
    
    TArray<TPair<FString, FString>> NumberPatterns = {
        {TEXT("0"), TEXT("00")}, {TEXT("1"), TEXT("01")}, {TEXT("2"), TEXT("02")}, {TEXT("3"), TEXT("03")},
        {TEXT("_0"), TEXT("_00")}, {TEXT("_1"), TEXT("_01")}, {TEXT("_2"), TEXT("_02")}, {TEXT("_3"), TEXT("_03")},
        {TEXT("0"), TEXT("_0")}, {TEXT("1"), TEXT("_1")}, {TEXT("2"), TEXT("_2")}, {TEXT("3"), TEXT("_3")},
        {TEXT("01"), TEXT("1")}, {TEXT("02"), TEXT("2")}, {TEXT("03"), TEXT("3")}, {TEXT("04"), TEXT("4")},
        {TEXT("_01"), TEXT("_1")}, {TEXT("_02"), TEXT("_2")}, {TEXT("_03"), TEXT("_3")}
    };
    
    TArray<FString> TempVariations = Variations;
    for (const FString& Var : TempVariations)
    {
        for (const auto& NumPattern : NumberPatterns)
        {
            if (Var.Contains(NumPattern.Key))
            {
                Variations.Add(Var.Replace(*NumPattern.Key, *NumPattern.Value));
            }
        }
    }
    
    TMap<FString, TArray<FString>> CommonMappings = GetCommonMappings();
    
    TempVariations = Variations;
    for (const FString& Var : TempVariations)
    {
        FString VarLower = Var.ToLower();
        for (const auto& Mapping : CommonMappings)
        {
            if (VarLower.Contains(Mapping.Key))
            {
                for (const FString& Alternative : Mapping.Value)
                {
                    // Replace the synonym while keeping case and side markers
                    FString NewName = Var.Replace(*Mapping.Key, *Alternative, ESearchCase::IgnoreCase);
                    Variations.AddUnique(NewName);
                    
                    // Also try with different separators
                    Variations.AddUnique(NewName.Replace(TEXT("_"), TEXT("")));
                    Variations.AddUnique(NewName.Replace(TEXT(""), TEXT("_")));
                    Variations.AddUnique(NewName.Replace(TEXT(" "), TEXT("_")));
                    Variations.AddUnique(NewName.Replace(TEXT("-"), TEXT("_")));
                }
            }
        }
    }
    
    TempVariations = Variations;
    for (const FString& Var : TempVariations)
    {
        FString VarLower = Var.ToLower();

        TArray<TPair<FString, FString>> LegArmPatterns = {
            // Thigh/Hip -> UpperLeg
            {TEXT("lefthip"), TEXT("upperlegl")},
            {TEXT("lefthip"), TEXT("leftupperleg")},
            {TEXT("lefthip"), TEXT("upleg_l")},
            {TEXT("righthip"), TEXT("upperlegr")},
            {TEXT("righthip"), TEXT("rightupperleg")},
            {TEXT("righthip"), TEXT("upleg_r")},
            // Knee/Calf -> LowerLeg
            {TEXT("leftknee"), TEXT("lowerlegl")},
            {TEXT("leftknee"), TEXT("leftlowerleg")},
            {TEXT("leftknee"), TEXT("lowleg_l")},
            {TEXT("rightknee"), TEXT("lowerlegr")},
            {TEXT("rightknee"), TEXT("rightlowerleg")},
            {TEXT("rightknee"), TEXT("lowleg_r")},
            // Collar/Clavicle -> Shoulder
            {TEXT("leftcollar"), TEXT("shoulderl")},
            {TEXT("leftcollar"), TEXT("leftshoulder")},
            {TEXT("rightcollar"), TEXT("shoulderr")},
            {TEXT("rightcollar"), TEXT("rightshoulder")},
            // Toe -> Ball
            {TEXT("lefttoe"), TEXT("ball01l")},
            {TEXT("lefttoe"), TEXT("balll")},
            {TEXT("righttoe"), TEXT("ball01r")},
            {TEXT("righttoe"), TEXT("ballr")},
            // Chest1/Chest2 -> Chest/UpperChest (MoA Spine 02/03 -> target Chest)
            {TEXT("chest1"), TEXT("chest")},
            {TEXT("chest1"), TEXT("upperchest")},
            {TEXT("chest2"), TEXT("upperchest")},
            {TEXT("chest2"), TEXT("chest")},
        };
        
        for (const auto& Pattern : LegArmPatterns)
        {
            if (VarLower == Pattern.Key)
            {
                Variations.AddUnique(Pattern.Value);
            }
            if (VarLower == Pattern.Value)
            {
                Variations.AddUnique(Pattern.Key);
            }
        }
    }
    
    TempVariations = Variations;
    for (const FString& Var : TempVariations)
    {
        FString VarLower = Var.ToLower();

        TArray<TPair<FString, FString>> FingerPatterns = {
            // Thumb
            {TEXT("thumbproximal"), TEXT("thumb01")},
            {TEXT("thumbintermediate"), TEXT("thumb02")},
            {TEXT("thumbdistal"), TEXT("thumb03")},
            // Index
            {TEXT("indexproximal"), TEXT("index01")},
            {TEXT("indexintermediate"), TEXT("index02")},
            {TEXT("indexdistal"), TEXT("index03")},
            // Middle
            {TEXT("middleproximal"), TEXT("middle01")},
            {TEXT("middleintermediate"), TEXT("middle02")},
            {TEXT("middledistal"), TEXT("middle03")},
            // Ring
            {TEXT("ringproximal"), TEXT("ring01")},
            {TEXT("ringintermediate"), TEXT("ring02")},
            {TEXT("ringdistal"), TEXT("ring03")},
            // Pinky/Little
            {TEXT("pinkyproximal"), TEXT("pinky01")},
            {TEXT("pinkyintermediate"), TEXT("pinky02")},
            {TEXT("pinkydistal"), TEXT("pinky03")},
            {TEXT("littleproximal"), TEXT("pinky01")},
            {TEXT("littleintermediate"), TEXT("pinky02")},
            {TEXT("littledistal"), TEXT("pinky03")},
        };
        
        for (const auto& Pattern : FingerPatterns)
        {
            if (VarLower.Contains(Pattern.Key))
            {
                Variations.AddUnique(Var.Replace(*Pattern.Key, *Pattern.Value, ESearchCase::IgnoreCase));
            }
            if (VarLower.Contains(Pattern.Value))
            {
                Variations.AddUnique(Var.Replace(*Pattern.Value, *Pattern.Key, ESearchCase::IgnoreCase));
            }
        }
        
        // Little <-> Pinky conversion
        if (VarLower.Contains(TEXT("little")))
        {
            Variations.AddUnique(Var.Replace(TEXT("little"), TEXT("pinky"), ESearchCase::IgnoreCase));
        }
        if (VarLower.Contains(TEXT("pinky")))
        {
            Variations.AddUnique(Var.Replace(TEXT("pinky"), TEXT("little"), ESearchCase::IgnoreCase));
        }
    }
    
    TempVariations = Variations;
    for (const FString& Var : TempVariations)
    {
        FString NoSep = Var;
        NoSep.ReplaceInline(TEXT("_"), TEXT(""));
        NoSep.ReplaceInline(TEXT("-"), TEXT(""));
        NoSep.ReplaceInline(TEXT("."), TEXT(""));
        NoSep.ReplaceInline(TEXT(" "), TEXT(""));
        Variations.AddUnique(NoSep);

        FString Underscore = Var;
        Underscore.ReplaceInline(TEXT("-"), TEXT("_"));
        Underscore.ReplaceInline(TEXT("."), TEXT("_"));
        Underscore.ReplaceInline(TEXT(" "), TEXT("_"));
        Variations.AddUnique(Underscore);

        FString Dot = Var;
        Dot.ReplaceInline(TEXT("_"), TEXT("."));
        Dot.ReplaceInline(TEXT("-"), TEXT("."));
        Dot.ReplaceInline(TEXT(" "), TEXT("."));
        Variations.AddUnique(Dot);
    }
    
    return Variations;
}

const TMap<FString, FMoABoneHierarchyInfo>& FMoABoneNameMappings::GetExpectedBoneHierarchy()
{
    static TMap<FString, FMoABoneHierarchyInfo> BoneHierarchy = {
        // Root/Body
        {TEXT("hips"), FMoABoneHierarchyInfo(TEXT("hips"), TEXT(""), {TEXT("chest"), TEXT("lefthip"), TEXT("righthip")})},
        
        {TEXT("chest"), FMoABoneHierarchyInfo(TEXT("chest"), TEXT("hips"), {TEXT("chest1")})},
        {TEXT("chest1"), FMoABoneHierarchyInfo(TEXT("chest1"), TEXT("chest"), {TEXT("chest2")})},
        {TEXT("chest2"), FMoABoneHierarchyInfo(TEXT("chest2"), TEXT("chest1"), {TEXT("neck"), TEXT("leftcollar"), TEXT("rightcollar")})},
        
        // Neck/Head chain
        {TEXT("neck"), FMoABoneHierarchyInfo(TEXT("neck"), TEXT("chest2"), {TEXT("neck1")})},
        {TEXT("neck1"), FMoABoneHierarchyInfo(TEXT("neck1"), TEXT("neck"), {})},
        
        // Left Leg chain
        {TEXT("lefthip"), FMoABoneHierarchyInfo(TEXT("lefthip"), TEXT("hips"), {TEXT("leftknee")})},
        {TEXT("leftknee"), FMoABoneHierarchyInfo(TEXT("leftknee"), TEXT("lefthip"), {TEXT("leftankle")})},
        {TEXT("leftankle"), FMoABoneHierarchyInfo(TEXT("leftankle"), TEXT("leftknee"), {TEXT("lefttoe")})},
        {TEXT("lefttoe"), FMoABoneHierarchyInfo(TEXT("lefttoe"), TEXT("leftankle"), {})},
        
        // Right Leg chain
        {TEXT("righthip"), FMoABoneHierarchyInfo(TEXT("righthip"), TEXT("hips"), {TEXT("rightknee")})},
        {TEXT("rightknee"), FMoABoneHierarchyInfo(TEXT("rightknee"), TEXT("righthip"), {TEXT("rightankle")})},
        {TEXT("rightankle"), FMoABoneHierarchyInfo(TEXT("rightankle"), TEXT("rightknee"), {TEXT("righttoe")})},
        {TEXT("righttoe"), FMoABoneHierarchyInfo(TEXT("righttoe"), TEXT("rightankle"), {})},
        
        {TEXT("leftcollar"), FMoABoneHierarchyInfo(TEXT("leftcollar"), TEXT("chest2"), {TEXT("leftshoulder")})},
        {TEXT("leftshoulder"), FMoABoneHierarchyInfo(TEXT("leftshoulder"), TEXT("leftcollar"), {TEXT("leftelbow")})},
        {TEXT("leftelbow"), FMoABoneHierarchyInfo(TEXT("leftelbow"), TEXT("leftshoulder"), {TEXT("leftwrist")})},
        {TEXT("leftwrist"), FMoABoneHierarchyInfo(TEXT("leftwrist"), TEXT("leftelbow"), {TEXT("leftfinger0"), TEXT("leftfinger1"), TEXT("leftfinger2"), TEXT("leftfinger3"), TEXT("leftfinger4")})},

        {TEXT("rightcollar"), FMoABoneHierarchyInfo(TEXT("rightcollar"), TEXT("chest2"), {TEXT("rightshoulder")})},
        {TEXT("rightshoulder"), FMoABoneHierarchyInfo(TEXT("rightshoulder"), TEXT("rightcollar"), {TEXT("rightelbow")})},
        {TEXT("rightelbow"), FMoABoneHierarchyInfo(TEXT("rightelbow"), TEXT("rightshoulder"), {TEXT("rightwrist")})},
        {TEXT("rightwrist"), FMoABoneHierarchyInfo(TEXT("rightwrist"), TEXT("rightelbow"), {TEXT("rightfinger0"), TEXT("rightfinger1"), TEXT("rightfinger2"), TEXT("rightfinger3"), TEXT("rightfinger4")})},
        
        // Left Fingers - Thumb chain
        {TEXT("leftfinger0"), FMoABoneHierarchyInfo(TEXT("leftfinger0"), TEXT("leftwrist"), {TEXT("leftfinger01")})},
        {TEXT("leftfinger01"), FMoABoneHierarchyInfo(TEXT("leftfinger01"), TEXT("leftfinger0"), {TEXT("leftfinger02")})},
        {TEXT("leftfinger02"), FMoABoneHierarchyInfo(TEXT("leftfinger02"), TEXT("leftfinger01"), {})},
        
        // Left Fingers - Index chain
        {TEXT("leftfinger1"), FMoABoneHierarchyInfo(TEXT("leftfinger1"), TEXT("leftwrist"), {TEXT("leftfinger11")})},
        {TEXT("leftfinger11"), FMoABoneHierarchyInfo(TEXT("leftfinger11"), TEXT("leftfinger1"), {TEXT("leftfinger12")})},
        {TEXT("leftfinger12"), FMoABoneHierarchyInfo(TEXT("leftfinger12"), TEXT("leftfinger11"), {})},
        
        // Left Fingers - Middle chain
        {TEXT("leftfinger2"), FMoABoneHierarchyInfo(TEXT("leftfinger2"), TEXT("leftwrist"), {TEXT("leftfinger21")})},
        {TEXT("leftfinger21"), FMoABoneHierarchyInfo(TEXT("leftfinger21"), TEXT("leftfinger2"), {TEXT("leftfinger22")})},
        {TEXT("leftfinger22"), FMoABoneHierarchyInfo(TEXT("leftfinger22"), TEXT("leftfinger21"), {})},
        
        // Left Fingers - Ring chain
        {TEXT("leftfinger3"), FMoABoneHierarchyInfo(TEXT("leftfinger3"), TEXT("leftwrist"), {TEXT("leftfinger31")})},
        {TEXT("leftfinger31"), FMoABoneHierarchyInfo(TEXT("leftfinger31"), TEXT("leftfinger3"), {TEXT("leftfinger32")})},
        {TEXT("leftfinger32"), FMoABoneHierarchyInfo(TEXT("leftfinger32"), TEXT("leftfinger31"), {})},
        
        // Left Fingers - Pinky chain
        {TEXT("leftfinger4"), FMoABoneHierarchyInfo(TEXT("leftfinger4"), TEXT("leftwrist"), {TEXT("leftfinger41")})},
        {TEXT("leftfinger41"), FMoABoneHierarchyInfo(TEXT("leftfinger41"), TEXT("leftfinger4"), {TEXT("leftfinger42")})},
        {TEXT("leftfinger42"), FMoABoneHierarchyInfo(TEXT("leftfinger42"), TEXT("leftfinger41"), {})},
        
        // Right Fingers - Thumb chain
        {TEXT("rightfinger0"), FMoABoneHierarchyInfo(TEXT("rightfinger0"), TEXT("rightwrist"), {TEXT("rightfinger01")})},
        {TEXT("rightfinger01"), FMoABoneHierarchyInfo(TEXT("rightfinger01"), TEXT("rightfinger0"), {TEXT("rightfinger02")})},
        {TEXT("rightfinger02"), FMoABoneHierarchyInfo(TEXT("rightfinger02"), TEXT("rightfinger01"), {})},
        
        // Right Fingers - Index chain
        {TEXT("rightfinger1"), FMoABoneHierarchyInfo(TEXT("rightfinger1"), TEXT("rightwrist"), {TEXT("rightfinger11")})},
        {TEXT("rightfinger11"), FMoABoneHierarchyInfo(TEXT("rightfinger11"), TEXT("rightfinger1"), {TEXT("rightfinger12")})},
        {TEXT("rightfinger12"), FMoABoneHierarchyInfo(TEXT("rightfinger12"), TEXT("rightfinger11"), {})},
        
        // Right Fingers - Middle chain
        {TEXT("rightfinger2"), FMoABoneHierarchyInfo(TEXT("rightfinger2"), TEXT("rightwrist"), {TEXT("rightfinger21")})},
        {TEXT("rightfinger21"), FMoABoneHierarchyInfo(TEXT("rightfinger21"), TEXT("rightfinger2"), {TEXT("rightfinger22")})},
        {TEXT("rightfinger22"), FMoABoneHierarchyInfo(TEXT("rightfinger22"), TEXT("rightfinger21"), {})},
        
        // Right Fingers - Ring chain
        {TEXT("rightfinger3"), FMoABoneHierarchyInfo(TEXT("rightfinger3"), TEXT("rightwrist"), {TEXT("rightfinger31")})},
        {TEXT("rightfinger31"), FMoABoneHierarchyInfo(TEXT("rightfinger31"), TEXT("rightfinger3"), {TEXT("rightfinger32")})},
        {TEXT("rightfinger32"), FMoABoneHierarchyInfo(TEXT("rightfinger32"), TEXT("rightfinger31"), {})},
        
        // Right Fingers - Pinky chain
        {TEXT("rightfinger4"), FMoABoneHierarchyInfo(TEXT("rightfinger4"), TEXT("rightwrist"), {TEXT("rightfinger41")})},
        {TEXT("rightfinger41"), FMoABoneHierarchyInfo(TEXT("rightfinger41"), TEXT("rightfinger4"), {TEXT("rightfinger42")})},
        {TEXT("rightfinger42"), FMoABoneHierarchyInfo(TEXT("rightfinger42"), TEXT("rightfinger41"), {})}
    };
    
    return BoneHierarchy;
}

FMoAHierarchyValidationResult FMoABoneNameMappings::ValidateBoneHierarchy(
    const FString& SourceBoneName,
    const FString& CandidateTargetBone,
    const TMap<FName, FName>& TargetBoneParentMap,
    const TMap<FString, FString>& CurrentMappings)
{
    FString NormalizedSource = NormalizeBoneName(SourceBoneName);
    FString NormalizedCandidate = NormalizeBoneName(CandidateTargetBone);

    const TMap<FString, FMoABoneHierarchyInfo>& Hierarchy = GetExpectedBoneHierarchy();

    const FMoABoneHierarchyInfo* SourceInfo = Hierarchy.Find(NormalizedSource);
    if (!SourceInfo)
    {
        return FMoAHierarchyValidationResult(true, 0.5f, TEXT("Unknown source bone, hierarchy not validated"));
    }
    
    float ConfidenceScore = 1.0f;

    if (!SourceInfo->ExpectedParent.IsEmpty())
    {
        const FString* MappedParent = CurrentMappings.Find(SourceInfo->ExpectedParent);
        if (MappedParent && !MappedParent->IsEmpty())
        {
            const FName* CandidateParent = TargetBoneParentMap.Find(FName(*CandidateTargetBone));
            if (CandidateParent && *CandidateParent != NAME_None)
            {
                FString NormalizedCandidateParent = NormalizeBoneName(CandidateParent->ToString());
                FString NormalizedMappedParent = NormalizeBoneName(*MappedParent);

                if (NormalizedCandidateParent != NormalizedMappedParent)
                {
                    ConfidenceScore *= 0.7f;
                }
                else
                {
                    ConfidenceScore *= 1.2f;
                }
            }
        }
    }

    for (const auto& Mapping : CurrentMappings)
    {
        if (NormalizeBoneName(Mapping.Value) == NormalizedCandidate &&
            NormalizeBoneName(Mapping.Key) != NormalizedSource)
        {
            if (AreBonesMutuallyExclusive(Mapping.Key, SourceBoneName))
            {
                return FMoAHierarchyValidationResult(false, 0.0f,
                    FString::Printf(TEXT("Target '%s' already mapped to '%s'"), *CandidateTargetBone, *Mapping.Key));
            }
            else
            {
                ConfidenceScore *= 0.5f;
            }
        }
    }

    bool bSourceIsLeft = NormalizedSource.Contains(TEXT("left"));
    bool bSourceIsRight = NormalizedSource.Contains(TEXT("right"));
    bool bCandidateIsLeft = NormalizedCandidate.Contains(TEXT("left")) ||
                           NormalizedCandidate.Contains(TEXT("_l")) ||
                           NormalizedCandidate.EndsWith(TEXT("l"));
    bool bCandidateIsRight = NormalizedCandidate.Contains(TEXT("right")) ||
                            NormalizedCandidate.Contains(TEXT("_r")) ||
                            NormalizedCandidate.EndsWith(TEXT("r"));

    if ((bSourceIsLeft && bCandidateIsRight) || (bSourceIsRight && bCandidateIsLeft))
    {
        return FMoAHierarchyValidationResult(false, 0.0f, TEXT("Left/Right side mismatch"));
    }
    
    // Clamp confidence score
    ConfidenceScore = FMath::Clamp(ConfidenceScore, 0.0f, 1.5f);
    
    return FMoAHierarchyValidationResult(true, ConfidenceScore);
}

TArray<TPair<FString, float>> FMoABoneNameMappings::RankCandidatesByHierarchy(
    const FString& SourceBoneName,
    const TArray<FString>& CandidateTargetBones,
    const TMap<FName, FName>& TargetBoneParentMap,
    const TMap<FString, FString>& CurrentMappings)
{
    TArray<TPair<FString, float>> RankedCandidates;
    RankedCandidates.Reserve(CandidateTargetBones.Num());
    
    for (const FString& Candidate : CandidateTargetBones)
    {
        FMoAHierarchyValidationResult Result = ValidateBoneHierarchy(
            SourceBoneName, Candidate, TargetBoneParentMap, CurrentMappings);
        
        if (Result.bIsValid)
        {
            RankedCandidates.Add(TPair<FString, float>(Candidate, Result.ConfidenceScore));
        }
    }
    
    // Sort by confidence score (descending)
    RankedCandidates.Sort([](const TPair<FString, float>& A, const TPair<FString, float>& B)
    {
        return A.Value > B.Value;
    });
    
    return RankedCandidates;
}

bool FMoABoneNameMappings::AreBonesMutuallyExclusive(const FString& SourceBone1, const FString& SourceBone2)
{
    FString Normalized1 = NormalizeBoneName(SourceBone1);
    FString Normalized2 = NormalizeBoneName(SourceBone2);

    if (Normalized1 == Normalized2)
    {
        return false;
    }

    static TArray<TArray<FString>> EquivalentBoneGroups;
    static bool bGroupsInitialized = false;

    if (!bGroupsInitialized)
    {
        bGroupsInitialized = true;

        EquivalentBoneGroups.Add({TEXT("hips"), TEXT("pelvis")});
        EquivalentBoneGroups.Add({TEXT("chest"), TEXT("spine"), TEXT("spine1")});
        EquivalentBoneGroups.Add({TEXT("chest1"), TEXT("spine2")});
        EquivalentBoneGroups.Add({TEXT("chest2"), TEXT("spine3")});
        EquivalentBoneGroups.Add({TEXT("neck")});
        EquivalentBoneGroups.Add({TEXT("neck1"), TEXT("head")});
        
        // Left leg chain
        EquivalentBoneGroups.Add({TEXT("lefthip"), TEXT("leftupleg")});
        EquivalentBoneGroups.Add({TEXT("leftknee"), TEXT("leftleg")});
        EquivalentBoneGroups.Add({TEXT("leftankle"), TEXT("leftfoot")});
        EquivalentBoneGroups.Add({TEXT("lefttoe"), TEXT("lefttoes")});
        
        // Right leg chain
        EquivalentBoneGroups.Add({TEXT("righthip"), TEXT("rightupleg")});
        EquivalentBoneGroups.Add({TEXT("rightknee"), TEXT("rightleg")});
        EquivalentBoneGroups.Add({TEXT("rightankle"), TEXT("rightfoot")});
        EquivalentBoneGroups.Add({TEXT("righttoe"), TEXT("righttoes")});
        
        // Left arm chain
        EquivalentBoneGroups.Add({TEXT("leftcollar"), TEXT("leftclavicle")});
        EquivalentBoneGroups.Add({TEXT("leftshoulder"), TEXT("leftupperarm")});
        EquivalentBoneGroups.Add({TEXT("leftelbow"), TEXT("leftlowerarm"), TEXT("leftforearm")});
        EquivalentBoneGroups.Add({TEXT("leftwrist"), TEXT("lefthand")});
        
        // Right arm chain
        EquivalentBoneGroups.Add({TEXT("rightcollar"), TEXT("rightclavicle")});
        EquivalentBoneGroups.Add({TEXT("rightshoulder"), TEXT("rightupperarm")});
        EquivalentBoneGroups.Add({TEXT("rightelbow"), TEXT("rightlowerarm"), TEXT("rightforearm")});
        EquivalentBoneGroups.Add({TEXT("rightwrist"), TEXT("righthand")});
    }
    
    // Check if bones are in the same equivalent group
    for (const TArray<FString>& Group : EquivalentBoneGroups)
    {
        bool bBone1InGroup = Group.Contains(Normalized1);
        bool bBone2InGroup = Group.Contains(Normalized2);
        
        // If both in same group, they're equivalent (not mutually exclusive)
        if (bBone1InGroup && bBone2InGroup)
        {
            return false;
        }
    }
    
    const TMap<FString, FMoABoneHierarchyInfo>& Hierarchy = GetExpectedBoneHierarchy();

    const FMoABoneHierarchyInfo* Info1 = Hierarchy.Find(Normalized1);
    const FMoABoneHierarchyInfo* Info2 = Hierarchy.Find(Normalized2);

    if (Info1 && Info2)
    {
        const int32 MaxIterations = 20;

        FString CurrentParent = Info2->ExpectedParent;
        FString LastParent;
        int32 Iterations = 0;
        while (!CurrentParent.IsEmpty() && Iterations < MaxIterations)
        {
            if (CurrentParent == Normalized1)
            {
                return true;
            }
            if (CurrentParent == LastParent)
            {
                break;
            }
            const FMoABoneHierarchyInfo* ParentInfo = Hierarchy.Find(CurrentParent);
            LastParent = CurrentParent;
            CurrentParent = ParentInfo ? ParentInfo->ExpectedParent : TEXT("");
            Iterations++;
        }

        CurrentParent = Info1->ExpectedParent;
        LastParent = TEXT("");
        Iterations = 0;
        while (!CurrentParent.IsEmpty() && Iterations < MaxIterations)
        {
            if (CurrentParent == Normalized2)
            {
                return true;
            }
            if (CurrentParent == LastParent)
            {
                break;
            }
            const FMoABoneHierarchyInfo* ParentInfo = Hierarchy.Find(CurrentParent);
            LastParent = CurrentParent;
            CurrentParent = ParentInfo ? ParentInfo->ExpectedParent : TEXT("");
            Iterations++;
        }
    }
    
    bool bBone1Left = Normalized1.Contains(TEXT("left"));
    bool bBone1Right = Normalized1.Contains(TEXT("right"));
    bool bBone2Left = Normalized2.Contains(TEXT("left"));
    bool bBone2Right = Normalized2.Contains(TEXT("right"));

    if ((bBone1Left && bBone2Right) || (bBone1Right && bBone2Left))
    {
        return true;
    }

    return true;
}

