<commit_before>import Analyzer, { SELECTED_PLAYER } from 'parser/core/Analyzer';
import { Options } from 'parser/core/Module';
import { TALENTS_DRUID } from 'common/TALENTS';
import { REJUVENATION_BUFFS } from 'analysis/retail/druid/restoration/constants';
import SPELLS from 'common/SPELLS';
import Events, { HealEvent } from 'parser/core/Events';
import { calculateEffectiveHealing } from 'parser/core/EventCalculateLib';
import Statistic from 'parser/ui/Statistic';
import STATISTIC_ORDER from 'parser/ui/STATISTIC_ORDER';
import STATISTIC_CATEGORY from 'parser/ui/STATISTIC_CATEGORY';
import BoringSpellValueText from 'parser/ui/BoringSpellValueText';
import ItemPercentHealingDone from 'parser/ui/ItemPercentHealingDone';
import { SpellLink } from 'interface';

const REJUV_MAX_BOOST_PER_RANK = 0.1;
const TRANQ_MAX_BOOST_PER_RANK = 0.2;

/**
 * **Regenesis**
 * Spec Talent
 *
 * Rejuvenation healing is increased by up to (10 / 20)%, and Tranquility healing is increased by
 * up to (15 / 30)%, healing for more on low-health targets.
 */
class Regenesis extends Analyzer {
  ranks: number;
  rejuvBoostHealing: number = 0;
  tranqBoostHealing: number = 0;

  constructor(options: Options) {
    super(options);

    this.ranks = this.selectedCombatant.getTalentRank(TALENTS_DRUID.REGENESIS_TALENT);
    this.active = this.ranks > 0;

    this.addEventListener(
      Events.heal.by(SELECTED_PLAYER).spell(REJUVENATION_BUFFS),
      this.onRejuvHeal,
    );
    this.addEventListener(
      Events.heal.by(SELECTED_PLAYER).spell(SPELLS.TRANQUILITY_HEAL),
      this.onTranqHeal,
    );
  }

  onRejuvHeal(event: HealEvent) {
    this.rejuvBoostHealing += this._getBoostHealing(event, REJUV_MAX_BOOST_PER_RANK * this.ranks);
  }

  onTranqHeal(event: HealEvent) {
    this.tranqBoostHealing += this._getBoostHealing(event, TRANQ_MAX_BOOST_PER_RANK * this.ranks);
  }

  _getBoostHealing(event: HealEvent, boostAmount: number): number {
    // looks like the scaling on the boost is linear, with max boost when target is at 0% and no boost when target is full
    const healthPercentMissingBeforeHeal =
      1 - (event.hitPoints - event.amount) / event.maxHitPoints;
    return calculateEffectiveHealing(event, boostAmount * healthPercentMissingBeforeHeal);
  }

  get totalHealing() {
    return this.rejuvBoostHealing + this.tranqBoostHealing;
  }

  statistic() {
    return (
      <Statistic
        size="flexible"
        position={STATISTIC_ORDER.OPTIONAL(7)} // number based on talent row
        category={STATISTIC_CATEGORY.TALENTS}
        tooltip={
          <>
            Breakdown by boosted spell:
            <ul>
              <li>
                <SpellLink id={SPELLS.REJUVENATION.id} />:{' '}
                <strong>{this.owner.formatItemHealingDone(this.rejuvBoostHealing)}</strong>
              </li>
              <li>
                <SpellLink id={SPELLS.TRANQUILITY_HEAL.id} />:{' '}
                <strong>{this.owner.formatItemHealingDone(this.tranqBoostHealing)}</strong>
              </li>
            </ul>
          </>
        }
      >
        <BoringSpellValueText spellId={TALENTS_DRUID.REGENESIS_TALENT.id}>
          <ItemPercentHealingDone amount={this.totalHealing} />
          <br />
        </BoringSpellValueText>
      </Statistic>
    );
  }
}

export default Regenesis;
<commit_msg>Missed a spot<commit_after>import Analyzer, { SELECTED_PLAYER } from 'parser/core/Analyzer';
import { Options } from 'parser/core/Module';
import { TALENTS_DRUID } from 'common/TALENTS';
import { REJUVENATION_BUFFS } from 'analysis/retail/druid/restoration/constants';
import SPELLS from 'common/SPELLS';
import Events, { HealEvent } from 'parser/core/Events';
import { calculateEffectiveHealing } from 'parser/core/EventCalculateLib';
import Statistic from 'parser/ui/Statistic';
import STATISTIC_ORDER from 'parser/ui/STATISTIC_ORDER';
import STATISTIC_CATEGORY from 'parser/ui/STATISTIC_CATEGORY';
import BoringSpellValueText from 'parser/ui/BoringSpellValueText';
import ItemPercentHealingDone from 'parser/ui/ItemPercentHealingDone';
import { SpellLink } from 'interface';

const REJUV_MAX_BOOST_PER_RANK = 0.1;
const TRANQ_MAX_BOOST_PER_RANK = 0.15;

/**
 * **Regenesis**
 * Spec Talent
 *
 * Rejuvenation healing is increased by up to (10 / 20)%, and Tranquility healing is increased by
 * up to (15 / 30)%, healing for more on low-health targets.
 */
class Regenesis extends Analyzer {
  ranks: number;
  rejuvBoostHealing: number = 0;
  tranqBoostHealing: number = 0;

  constructor(options: Options) {
    super(options);

    this.ranks = this.selectedCombatant.getTalentRank(TALENTS_DRUID.REGENESIS_TALENT);
    this.active = this.ranks > 0;

    this.addEventListener(
      Events.heal.by(SELECTED_PLAYER).spell(REJUVENATION_BUFFS),
      this.onRejuvHeal,
    );
    this.addEventListener(
      Events.heal.by(SELECTED_PLAYER).spell(SPELLS.TRANQUILITY_HEAL),
      this.onTranqHeal,
    );
  }

  onRejuvHeal(event: HealEvent) {
    this.rejuvBoostHealing += this._getBoostHealing(event, REJUV_MAX_BOOST_PER_RANK * this.ranks);
  }

  onTranqHeal(event: HealEvent) {
    this.tranqBoostHealing += this._getBoostHealing(event, TRANQ_MAX_BOOST_PER_RANK * this.ranks);
  }

  _getBoostHealing(event: HealEvent, boostAmount: number): number {
    // looks like the scaling on the boost is linear, with max boost when target is at 0% and no boost when target is full
    const healthPercentMissingBeforeHeal =
      1 - (event.hitPoints - event.amount) / event.maxHitPoints;
    return calculateEffectiveHealing(event, boostAmount * healthPercentMissingBeforeHeal);
  }

  get totalHealing() {
    return this.rejuvBoostHealing + this.tranqBoostHealing;
  }

  statistic() {
    return (
      <Statistic
        size="flexible"
        position={STATISTIC_ORDER.OPTIONAL(7)} // number based on talent row
        category={STATISTIC_CATEGORY.TALENTS}
        tooltip={
          <>
            Breakdown by boosted spell:
            <ul>
              <li>
                <SpellLink id={SPELLS.REJUVENATION.id} />:{' '}
                <strong>{this.owner.formatItemHealingDone(this.rejuvBoostHealing)}</strong>
              </li>
              <li>
                <SpellLink id={SPELLS.TRANQUILITY_HEAL.id} />:{' '}
                <strong>{this.owner.formatItemHealingDone(this.tranqBoostHealing)}</strong>
              </li>
            </ul>
          </>
        }
      >
        <BoringSpellValueText spellId={TALENTS_DRUID.REGENESIS_TALENT.id}>
          <ItemPercentHealingDone amount={this.totalHealing} />
          <br />
        </BoringSpellValueText>
      </Statistic>
    );
  }
}

export default Regenesis;

{'fraction_non_alphanumeric': 0.10803531348196918, 'fraction_numerical': 0.005536435732455484, 'mean_word_length': 3.281870595771941, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5107471', 'n_tokens_mistral': 2307, 'n_tokens_neox': 2245, 'n_words': 418}