//accurate when called from a mod's ToString(), but repeating lots of live translations is slow
        public static string TranslateModCraft(ModCraft mod, int modquality)
        {
            IList <ModRoll> statscopy = new List <ModRoll>(mod.Stats);
            IList <string>  lines     = new List <string>();

            while (statscopy.Count > 0)
            {
                string id = statscopy[0].ID;
                if (!Data.ContainsKey(id))
                {
                    Debug.WriteLine("skipping stat translation for " + id);
                    statscopy.RemoveAt(0);
                    continue;
                }
                StatLocalization chunk = Data[id];
                IList <int>      rolls = new List <int>();
                for (int i = 0; i < chunk.ids.Count; i++)       //copy out roll and remove handled stats from statcopy
                {
                    int found = -1;
                    for (int j = 0; j < statscopy.Count; j++)
                    {
                        if (statscopy[j].ID == chunk.ids[i])
                        {
                            found = j;
                            rolls.Add(statscopy[j].Roll * (100 + modquality) / 100);
                            break;
                        }
                    }
                    if (found < 0)
                    {
                        rolls.Add(0);
                    }
                    else
                    {
                        statscopy.RemoveAt(found);
                    }
                }

                if (chunk.hidden)
                {
                    continue;
                }
                LocalizationDefinition def = null;
                foreach (LocalizationDefinition d in chunk.definitions)     //find matching definition
                {
                    if (MeetsCondition(rolls, d.condition))
                    {
                        def = d;
                        break;
                    }
                }
                string linetext = BuildText(def.text, rolls, def.format, def.index_handlers);
                lines.Add(linetext);
            }
            return(string.Join("\n", lines));
        }
        //made private for new implementation - this is only called once on load
        //accurate when called from a mod's ToString(), but repeating lots of live translations is slow
        private static string TranslateModData(PoEModData mod)
        {
            IList <PoEModStat> statscopy = new List <PoEModStat>(mod.stats);
            IList <string>     lines     = new List <string>();

            while (statscopy.Count > 0)
            {
                string id = statscopy[0].id;
                if (!Data.ContainsKey(id))
                {
                    //Debug.WriteLine("skipping stat translation for " + id);
                    statscopy.RemoveAt(0);
                    continue;
                }
                StatLocalization chunk = Data[id];
                IList <int>      min   = new List <int>();
                IList <int>      max   = new List <int>();
                for (int i = 0; i < chunk.ids.Count; i++)       //copy out minmax and remove handled stats from statcopy
                {
                    int found = -1;
                    for (int j = 0; j < statscopy.Count; j++)
                    {
                        if (statscopy[j].id == chunk.ids[i])
                        {
                            found = j;
                            min.Add(statscopy[j].min);
                            max.Add(statscopy[j].max);
                            break;
                        }
                    }
                    if (found < 0)
                    {
                        min.Add(0);
                        max.Add(0);
                    }
                    else
                    {
                        statscopy.RemoveAt(found);
                    }
                }

                if (chunk.hidden)
                {
                    continue;
                }
                LocalizationDefinition def = null;
                foreach (LocalizationDefinition d in chunk.definitions)     //find matching definition
                {
                    if (MeetsCondition(max, d.condition))
                    {
                        def = d;
                        break;
                    }
                }
                if (def == null)
                {
                    continue;
                }
                string linetext = BuildText(def.text, min, max, def.format, def.index_handlers);
                lines.Add(linetext);
            }
            return(string.Join("\n", lines));
        }