text: ### Generates resources/territory_type.js
  
  # (1) Download https://github.com/ufx/SaintCoinach/releases/latest
  # (2) SaintCoinach.Cmd.exe "C:\Program Files (x86)\SquareEnix\FINAL FANTASY XIV - A Realm Reborn"
  # (3) exd TerritoryType WeatherRate
  # (4) Run util/gen_territory_type.py path/to/TerritoryType.csv
  
  import argparse
  import csv
  import json
  import os
  import re
  
  def read_data(csvfile):
    all_rates = {}
    reader = csv.reader(csvfile)
    next(reader)
    keys = next(reader)
    next(reader)
  
    place_idx = keys.index('PlaceName')
    rate_idx = keys.index('WeatherRate')
  
    row_idx = 3
    for row in reader:
      row_idx += 1
      place = row[place_idx]
      if not place:
        continue
      rate = int(row[rate_idx])
  
      # Unknown conflicts:
      # TODO: Mist is 14/32
      # TODO: Diadem is 60/61/62/71
  
      # ignore many single weather types that are (likely?) used for instanced fights
      # TODO: If these ever change, consider
      ignore = [
        0, # fair skies
        28, # clouds
        36, # wind
        40, # fog
        42, # blizzards
        45, # tension
        58, # clear skies
        86, # umbral static
        88, # dimensional disruption
        89, # thunder
        92, # dimensional disruption
        95, # fair skies
      ]
      if rate in ignore:
       continue
  
      if place in all_rates:
        if all_rates[place] != rate:
          print('Discrepancy for ' + place + ', had: ' +
              str(all_rates[place]) + ', found: ' + str(rate) + ', row: ' + str(row_idx))
        continue
      all_rates[place] = rate
    return all_rates
  
  def write_file(output, all_rates):
    output.write("'use strict';\n\n")
    output.write('// Auto-generated from ' + __file__ + '\n');
    output.write('// DO NOT EDIT THIS FILE DIRECTLY\n\n');
    output.write('let gTerritoryWeather = ')
    str = json.dumps(all_rates,sort_keys=True,indent=2)
    # single quote style
    str = re.sub(r"'", '\\"', str)
    str = re.sub(r'"', "'", str)
    # add trailing commas
    str = re.sub(r"([0-9]|'|]|})\s*$", r"\1,", str, flags=re.MULTILINE)
    # remove final trailing comma
    str = re.sub(r",$", "", str)
    # make keys integers, remove leading zeroes.
    str = re.sub(r"'0*([0-9]+)': {", r"\1: {", str)
    output.write(str)
    output.write(';\n')
  
  def main(args):
    with open(args.file, 'r') as csvfile:
      all_rates = read_data(csvfile)
    with open(args.output, 'w') as output:
      write_file(output, all_rates)
  
  if __name__ == "__main__":
      example_usage = ""
  
      parser = argparse.ArgumentParser(
          description="Generates territory_type.js from exported TerritoryType.csv",
          epilog=example_usage,
          formatter_class=argparse.RawDescriptionHelpFormatter)
  
      parser.add_argument('-f', '--file', help="The TerritoryType.csv file")
      parser.add_argument('-o', '--output', help="The file to write");
  
      args = parser.parse_args()
  
      if not args.file:
        raise parser.error('Must pass a file.')
      if not args.output:
        args.output = os.path.join(os.path.dirname(__file__), '../resources/territory_type.js')
      main(args)
  