<commit_before>'use strict';

let findSafeDir = (data) => {
  // Tethers are ordered with all East tethers first. This *doesn't* mean that the East
  // or West tethers are themselves in order within their half!
  // The eight scale entities are listed in the data object, with West at indices 0-3,
  // under data.scaleSophias.
  let safeDir = 0;
  // If there's a side with more tethers, we know for sure that's the safe side.
  // This will give us the tilt direction for all but the 1/1, 2/2, and 3/3 cases.
  // The safe side is represented here by whether safeDir is positive or negative.
  // (West/negative, East/positive.)
  for (let tether of data.quasarTethers)
    safeDir += data.scaleSophias.indexOf(tether) < 4 ? -1 : 1;
  return safeDir;
};

let callSafeDir = (callIndex) => {
  return {
    '2': { en: 'Go East (Hard Tilt)', cn: '去东边（大倾斜）' },
    '1': { en: 'Go East (Soft Tilt)', cn: '去东边（小倾斜）' },
    '-2': { en: 'Go West (Hard Tilt)', cn: '去西边（大倾斜）' },
    '-1': { en: 'Go West (Soft Tilt)', cn: '去西边（小倾斜）' },
    // Stringified because Javascript doesn't do negative-integer key values.
  }[callIndex.toString()];
};


[{
  zoneRegex: {
    en: /^Containment Bay P1T6 \(Extreme\)$/,
    cn: /^索菲娅歼殛战$/,
  },
  timelineFile: 'sophia-ex.txt',
  timelineTriggers: [
    {
      // Gnosis does in fact have a cast time, but it's only 2.7 seconds.
      // It's safer to warn via the timeline.
      id: 'SophiaEX Gnosis',
      regex: /Gnosis/,
      beforeSeconds: 5,
      response: Responses.knockback(),
    },
    {
      // Onrush also has a 2.7 second cast time and thus is best notified from the timeline.
      id: 'SophiaEX Onrush',
      regex: /Onrush/,
      beforeSeconds: 5,
      infoText: {
        en: 'Avoid Dash Attack',
        cn: '躲避击飞',
      },
    },
    {
      id: 'SophiaEX Cintamani',
      regex: /Cintamani/,
      beforeSeconds: 4,
      condition: Conditions.caresAboutAOE(),
      response: Responses.aoe(),
    },
    {
      id: 'SophiaEX Dischordant Cleansing',
      regex: /Dischordant Cleansing/,
      beforeSeconds: 6,
      alertText: {
        en: 'Stack With Partner',
        de: 'Mit Partner stacken',
        fr: 'Packez-vous avec votre partenaire',
        ja: '白黒合わせて',
        cn: '黑白配',
        ko: '흑백 파트너랑 모이기',
      },
    },
    {
      id: 'SophiaEX Quasar Bait',
      regex: /Quasar \(Snapshot\)/,
      beforeSeconds: 6,
      infoText: {
        en: 'Bait Quasar Meteors',
        cn: '诱导陨石',
      },
    },
  ],
  triggers: [
    {
      id: 'SophiaEX Tank Buster',
      netRegex: NetRegexes.startsUsing({ id: '19C4', source: 'Sophia' }),
      netRegexDe: NetRegexes.startsUsing({ id: '19C4', source: 'Sophia' }),
      netRegexFr: NetRegexes.startsUsing({ id: '19C4', source: 'Sophia' }),
      netRegexJa: NetRegexes.startsUsing({ id: '19C4', source: 'ソフィア' }),
      netRegexCn: NetRegexes.startsUsing({ id: '19C4', source: '索菲娅' }),
      netRegexKo: NetRegexes.startsUsing({ id: '19C4', source: '소피아' }),
      condition: function(data) {
        return data.role == 'tank' || data.role == 'healer';
      },
      response: Responses.tankBusterSwap(),
    },
    {
      id: 'SophiaEX Thunder 2',
      netRegex: NetRegexes.startsUsing({ id: '19B0', source: 'Sophia', capture: false }),
      netRegexDe: NetRegexes.startsUsing({ id: '19B0', source: 'Sophia', capture: false }),
      netRegexFr: NetRegexes.startsUsing({ id: '19B0', source: 'Sophia', capture: false }),
      netRegexJa: NetRegexes.startsUsing({ id: '19B0', source: 'ソフィア', capture: false }),
      netRegexCn: NetRegexes.startsUsing({ id: '19B0', source: '索菲娅', capture: false }),
      netRegexKo: NetRegexes.startsUsing({ id: '19B0', source: '소피아', capture: false }),
      response: Responses.awayFromFront(),
    },
    {
      id: 'SophiaEX Thunder 3',
      netRegex: NetRegexes.startsUsing({ id: '19AC', source: 'Sophia', capture: false }),
      netRegexDe: NetRegexes.startsUsing({ id: '19AC', source: 'Sophia', capture: false }),
      netRegexFr: NetRegexes.startsUsing({ id: '19AC', source: 'Sophia', capture: false }),
      netRegexJa: NetRegexes.startsUsing({ id: '19AC', source: 'ソフィア', capture: false }),
      netRegexCn: NetRegexes.startsUsing({ id: '19AC', source: '索菲娅', capture: false }),
      netRegexKo: NetRegexes.startsUsing({ id: '19AC', source: '소피아', capture: false }),
      response: Responses.getUnder(),
    },
    {
      // Technically this one does have a telegraph, but it feels really weird
      // to have Thunder 3 with popup text and this one not.
      id: 'SophiaEX Aero 3',
      netRegex: NetRegexes.startsUsing({ id: '19AE', source: 'Sophia', capture: false }),
      netRegexDe: NetRegexes.startsUsing({ id: '19AE', source: 'Sophia', capture: false }),
      netRegexFr: NetRegexes.startsUsing({ id: '19AE', source: 'Sophia', capture: false }),
      netRegexCn: NetRegexes.startsUsing({ id: '19AE', source: '索菲娅', capture: false }),
      netRegexJa: NetRegexes.startsUsing({ id: '19AE', source: 'ソフィア', capture: false }),
      netRegexKo: NetRegexes.startsUsing({ id: '19AE', source: '소피아', capture: false }),
      response: Responses.getOut(),
    },
    {
      id: 'SophiaEX Divine Spark',
      netRegex: NetRegexes.startsUsing({ id: '19B6', source: 'The Second Demiurge', capture: false }),
      netRegexDe: NetRegexes.startsUsing({ id: '19B6', source: 'Zweit(?:e|er|es|en) Demiurg', capture: false }),
      netRegexFr: NetRegexes.startsUsing({ id: '19B6', source: 'Second Démiurge', capture: false }),
      netRegexJa: NetRegexes.startsUsing({ id: '19B6', source: '二の従者', capture: false }),
      netRegexCn: NetRegexes.startsUsing({ id: '19B6', source: '信徒其二', capture: false }),
      netRegexKo: NetRegexes.startsUsing({ id: '19B6', source: '제2신도', capture: false }),
      response: Responses.lookAway(),
    },
    {
      id: 'SophiaEX Gnostic Rant',
      netRegex: NetRegexes.startsUsing({ id: '19B8', source: 'The Third Demiurge', capture: false }),
      netRegexDe: NetRegexes.startsUsing({ id: '19B8', source: 'Dritt(?:e|er|es|en) Demiurg', capture: false }),
      netRegexFr: NetRegexes.startsUsing({ id: '19B8', source: 'Troisième Démiurge', capture: false }),
      netRegexJa: NetRegexes.startsUsing({ id: '19B8', source: '三の従者', capture: false }),
      netRegexCn: NetRegexes.startsUsing({ id: '19B8', source: '信徒其三', capture: false }),
      netRegexKo: NetRegexes.startsUsing({ id: '19B8', source: '제3신도', capture: false }),
      infoText: {
        en: 'Get behind lancer',
        cn: '躲在3号小怪后',
      },
    },
    {
      id: 'SophiaEX Infusion',
      netRegex: NetRegexes.startsUsing({ id: '1988', source: 'The First Demiurge' }),
      netRegexDe: NetRegexes.startsUsing({ id: '1988', source: 'Erst(?:e|er|es|en) Demiurg' }),
      netRegexFr: NetRegexes.startsUsing({ id: '1988', source: 'Premier Démiurge' }),
      netRegexJa: NetRegexes.startsUsing({ id: '1988', source: '一の従者' }),
      netRegexCn: NetRegexes.startsUsing({ id: '1988', source: '信徒其一' }),
      netRegexKo: NetRegexes.startsUsing({ id: '1988', source: '제1신도' }),
      infoText: function(data, matches) {
        if (Conditions.targetIsYou()) {
          return {
            en: 'Infusion on YOU',
          };
        }
        return {
          en: 'Infusion on ' + data.ShortName(matches.target),
        };
      },
    },
    {
      // The Aion Teleos clones have 10 fixed points where they can appear, but not all
      // combinations are valid:<commit_msg>CN translation for SophiaEX Infusion's trigger (#1446)<commit_after>'use strict';

let findSafeDir = (data) => {
  // Tethers are ordered with all East tethers first. This *doesn't* mean that the East
  // or West tethers are themselves in order within their half!
  // The eight scale entities are listed in the data object, with West at indices 0-3,
  // under data.scaleSophias.
  let safeDir = 0;
  // If there's a side with more tethers, we know for sure that's the safe side.
  // This will give us the tilt direction for all but the 1/1, 2/2, and 3/3 cases.
  // The safe side is represented here by whether safeDir is positive or negative.
  // (West/negative, East/positive.)
  for (let tether of data.quasarTethers)
    safeDir += data.scaleSophias.indexOf(tether) < 4 ? -1 : 1;
  return safeDir;
};

let callSafeDir = (callIndex) => {
  return {
    '2': { en: 'Go East (Hard Tilt)', cn: '去东边（大倾斜）' },
    '1': { en: 'Go East (Soft Tilt)', cn: '去东边（小倾斜）' },
    '-2': { en: 'Go West (Hard Tilt)', cn: '去西边（大倾斜）' },
    '-1': { en: 'Go West (Soft Tilt)', cn: '去西边（小倾斜）' },
    // Stringified because Javascript doesn't do negative-integer key values.
  }[callIndex.toString()];
};


[{
  zoneRegex: {
    en: /^Containment Bay P1T6 \(Extreme\)$/,
    cn: /^索菲娅歼殛战$/,
  },
  timelineFile: 'sophia-ex.txt',
  timelineTriggers: [
    {
      // Gnosis does in fact have a cast time, but it's only 2.7 seconds.
      // It's safer to warn via the timeline.
      id: 'SophiaEX Gnosis',
      regex: /Gnosis/,
      beforeSeconds: 5,
      response: Responses.knockback(),
    },
    {
      // Onrush also has a 2.7 second cast time and thus is best notified from the timeline.
      id: 'SophiaEX Onrush',
      regex: /Onrush/,
      beforeSeconds: 5,
      infoText: {
        en: 'Avoid Dash Attack',
        cn: '躲避击飞',
      },
    },
    {
      id: 'SophiaEX Cintamani',
      regex: /Cintamani/,
      beforeSeconds: 4,
      condition: Conditions.caresAboutAOE(),
      response: Responses.aoe(),
    },
    {
      id: 'SophiaEX Dischordant Cleansing',
      regex: /Dischordant Cleansing/,
      beforeSeconds: 6,
      alertText: {
        en: 'Stack With Partner',
        de: 'Mit Partner stacken',
        fr: 'Packez-vous avec votre partenaire',
        ja: '白黒合わせて',
        cn: '黑白配',
        ko: '흑백 파트너랑 모이기',
      },
    },
    {
      id: 'SophiaEX Quasar Bait',
      regex: /Quasar \(Snapshot\)/,
      beforeSeconds: 6,
      infoText: {
        en: 'Bait Quasar Meteors',
        cn: '诱导陨石',
      },
    },
  ],
  triggers: [
    {
      id: 'SophiaEX Tank Buster',
      netRegex: NetRegexes.startsUsing({ id: '19C4', source: 'Sophia' }),
      netRegexDe: NetRegexes.startsUsing({ id: '19C4', source: 'Sophia' }),
      netRegexFr: NetRegexes.startsUsing({ id: '19C4', source: 'Sophia' }),
      netRegexJa: NetRegexes.startsUsing({ id: '19C4', source: 'ソフィア' }),
      netRegexCn: NetRegexes.startsUsing({ id: '19C4', source: '索菲娅' }),
      netRegexKo: NetRegexes.startsUsing({ id: '19C4', source: '소피아' }),
      condition: function(data) {
        return data.role == 'tank' || data.role == 'healer';
      },
      response: Responses.tankBusterSwap(),
    },
    {
      id: 'SophiaEX Thunder 2',
      netRegex: NetRegexes.startsUsing({ id: '19B0', source: 'Sophia', capture: false }),
      netRegexDe: NetRegexes.startsUsing({ id: '19B0', source: 'Sophia', capture: false }),
      netRegexFr: NetRegexes.startsUsing({ id: '19B0', source: 'Sophia', capture: false }),
      netRegexJa: NetRegexes.startsUsing({ id: '19B0', source: 'ソフィア', capture: false }),
      netRegexCn: NetRegexes.startsUsing({ id: '19B0', source: '索菲娅', capture: false }),
      netRegexKo: NetRegexes.startsUsing({ id: '19B0', source: '소피아', capture: false }),
      response: Responses.awayFromFront(),
    },
    {
      id: 'SophiaEX Thunder 3',
      netRegex: NetRegexes.startsUsing({ id: '19AC', source: 'Sophia', capture: false }),
      netRegexDe: NetRegexes.startsUsing({ id: '19AC', source: 'Sophia', capture: false }),
      netRegexFr: NetRegexes.startsUsing({ id: '19AC', source: 'Sophia', capture: false }),
      netRegexJa: NetRegexes.startsUsing({ id: '19AC', source: 'ソフィア', capture: false }),
      netRegexCn: NetRegexes.startsUsing({ id: '19AC', source: '索菲娅', capture: false }),
      netRegexKo: NetRegexes.startsUsing({ id: '19AC', source: '소피아', capture: false }),
      response: Responses.getUnder(),
    },
    {
      // Technically this one does have a telegraph, but it feels really weird
      // to have Thunder 3 with popup text and this one not.
      id: 'SophiaEX Aero 3',
      netRegex: NetRegexes.startsUsing({ id: '19AE', source: 'Sophia', capture: false }),
      netRegexDe: NetRegexes.startsUsing({ id: '19AE', source: 'Sophia', capture: false }),
      netRegexFr: NetRegexes.startsUsing({ id: '19AE', source: 'Sophia', capture: false }),
      netRegexCn: NetRegexes.startsUsing({ id: '19AE', source: '索菲娅', capture: false }),
      netRegexJa: NetRegexes.startsUsing({ id: '19AE', source: 'ソフィア', capture: false }),
      netRegexKo: NetRegexes.startsUsing({ id: '19AE', source: '소피아', capture: false }),
      response: Responses.getOut(),
    },
    {
      id: 'SophiaEX Divine Spark',
      netRegex: NetRegexes.startsUsing({ id: '19B6', source: 'The Second Demiurge', capture: false }),
      netRegexDe: NetRegexes.startsUsing({ id: '19B6', source: 'Zweit(?:e|er|es|en) Demiurg', capture: false }),
      netRegexFr: NetRegexes.startsUsing({ id: '19B6', source: 'Second Démiurge', capture: false }),
      netRegexJa: NetRegexes.startsUsing({ id: '19B6', source: '二の従者', capture: false }),
      netRegexCn: NetRegexes.startsUsing({ id: '19B6', source: '信徒其二', capture: false }),
      netRegexKo: NetRegexes.startsUsing({ id: '19B6', source: '제2신도', capture: false }),
      response: Responses.lookAway(),
    },
    {
      id: 'SophiaEX Gnostic Rant',
      netRegex: NetRegexes.startsUsing({ id: '19B8', source: 'The Third Demiurge', capture: false }),
      netRegexDe: NetRegexes.startsUsing({ id: '19B8', source: 'Dritt(?:e|er|es|en) Demiurg', capture: false }),
      netRegexFr: NetRegexes.startsUsing({ id: '19B8', source: 'Troisième Démiurge', capture: false }),
      netRegexJa: NetRegexes.startsUsing({ id: '19B8', source: '三の従者', capture: false }),
      netRegexCn: NetRegexes.startsUsing({ id: '19B8', source: '信徒其三', capture: false }),
      netRegexKo: NetRegexes.startsUsing({ id: '19B8', source: '제3신도', capture: false }),
      infoText: {
        en: 'Get behind lancer',
        cn: '躲在3号小怪后',
      },
    },
    {
      id: 'SophiaEX Infusion',
      netRegex: NetRegexes.startsUsing({ id: '1988', source: 'The First Demiurge' }),
      netRegexDe: NetRegexes.startsUsing({ id: '1988', source: 'Erst(?:e|er|es|en) Demiurg' }),
      netRegexFr: NetRegexes.startsUsing({ id: '1988', source: 'Premier Démiurge' }),
      netRegexJa: NetRegexes.startsUsing({ id: '1988', source: '一の従者' }),
      netRegexCn: NetRegexes.startsUsing({ id: '1988', source: '信徒其一' }),
      netRegexKo: NetRegexes.startsUsing({ id: '1988', source: '제1신도' }),
      infoText: function(data, matches) {
        if (Conditions.targetIsYou()) {
          return {
            en: 'Infusion on YOU',
            cn: '冲锋点名',
          };
        }
        return {
          en: 'Infusion on ' + data.ShortName(matches.target),
          cn: '冲锋点' + data.ShortName(matches.target),
        };
      },
    },
    {
      // The Aion Teleos clones have 10 fixed points where they can appear, but not all
      // combinations are valid:
{'fraction_non_alphanumeric': 0.1561444186816827, 'fraction_numerical': 0.021066578337197748, 'mean_word_length': 2.9778656126482215, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, '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': '1356994', 'n_tokens_mistral': 5745, 'n_tokens_neox': 5625, 'n_words': 1434}