#!/usr/bin/env bash
#
# taup Bash Completion
# =======================
#
# Bash completion support for the `taup` command,
# generated by [picocli](https://picocli.info/) version 4.7.7-SNAPSHOT.
#
# Installation
# ------------
#
# 1. Source all completion scripts in your .bash_profile
#
#   cd $YOUR_APP_HOME/bin
#   for f in $(find . -name "*_completion"); do line=". $(pwd)/$f"; grep "$line" ~/.bash_profile || echo "$line" >> ~/.bash_profile; done
#
# 2. Open a new bash console, and type `taup [TAB][TAB]`
#
# 1a. Alternatively, if you have [bash-completion](https://github.com/scop/bash-completion) installed:
#     Place this file in a `bash-completion.d` folder:
#
#   * /etc/bash-completion.d
#   * /usr/local/etc/bash-completion.d
#   * ~/bash-completion.d
#
# Documentation
# -------------
# The script is called by bash whenever [TAB] or [TAB][TAB] is pressed after
# 'taup (..)'. By reading entered command line parameters,
# it determines possible bash completions and writes them to the COMPREPLY variable.
# Bash then completes the user input if only one entry is listed in the variable or
# shows the options if more than one is listed in COMPREPLY.
#
# References
# ----------
# [1] http://stackoverflow.com/a/12495480/1440785
# [2] http://tiswww.case.edu/php/chet/bash/FAQ
# [3] https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html
# [4] http://zsh.sourceforge.net/Doc/Release/Options.html#index-COMPLETE_005fALIASES
# [5] https://stackoverflow.com/questions/17042057/bash-check-element-in-array-for-elements-in-another-array/17042655#17042655
# [6] https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion.html#Programmable-Completion
# [7] https://stackoverflow.com/questions/3249432/can-a-bash-tab-completion-script-be-used-in-zsh/27853970#27853970
#

if [ -n "$BASH_VERSION" ]; then
  # Enable programmable completion facilities when using bash (see [3])
  shopt -s progcomp
elif [ -n "$ZSH_VERSION" ]; then
  # Make alias a distinct command for completion purposes when using zsh (see [4])
  setopt COMPLETE_ALIASES
  alias compopt=complete

  # Enable bash completion in zsh (see [7])
  # Only initialize completions module once to avoid unregistering existing completions.
  if ! type compdef > /dev/null; then
    autoload -U +X compinit && compinit
  fi
  autoload -U +X bashcompinit && bashcompinit
fi

# CompWordsContainsArray takes an array and then checks
# if all elements of this array are in the global COMP_WORDS array.
#
# Returns zero (no error) if all elements of the array are in the COMP_WORDS array,
# otherwise returns 1 (error).
function CompWordsContainsArray() {
  declare -a localArray
  localArray=("$@")
  local findme
  for findme in "${localArray[@]}"; do
    if ElementNotInCompWords "$findme"; then return 1; fi
  done
  return 0
}
function ElementNotInCompWords() {
  local findme="$1"
  local element
  for element in "${COMP_WORDS[@]}"; do
    if [[ "$findme" = "$element" ]]; then return 1; fi
  done
  return 0
}

# The `currentPositionalIndex` function calculates the index of the current positional parameter.
#
# currentPositionalIndex takes three parameters:
# the command name,
# a space-separated string with the names of options that take a parameter, and
# a space-separated string with the names of boolean options (that don't take any params).
# When done, this function echos the current positional index to std_out.
#
# Example usage:
# local currIndex=$(currentPositionalIndex "mysubcommand" "$ARG_OPTS" "$FLAG_OPTS")
function currentPositionalIndex() {
  local commandName="$1"
  local optionsWithArgs="$2"
  local booleanOptions="$3"
  local previousWord
  local result=0

  for i in $(seq $((COMP_CWORD - 1)) -1 0); do
    previousWord=${COMP_WORDS[i]}
    if [ "${previousWord}" = "$commandName" ]; then
      break
    fi
    if [[ "${optionsWithArgs}" =~ ${previousWord} ]]; then
      ((result-=2)) # Arg option and its value not counted as positional param
    elif [[ "${booleanOptions}" =~ ${previousWord} ]]; then
      ((result-=1)) # Flag option itself not counted as positional param
    fi
    ((result++))
  done
  echo "$result"
}

# compReplyArray generates a list of completion suggestions based on an array, ensuring all values are properly escaped.
#
# compReplyArray takes a single parameter: the array of options to be displayed
#
# The output is echoed to std_out, one option per line.
#
# Example usage:
# local options=("foo", "bar", "baz")
# local IFS=$'\n'
# COMPREPLY=($(compReplyArray "${options[@]}"))
function compReplyArray() {
  declare -a options
  options=("$@")
  local curr_word=${COMP_WORDS[COMP_CWORD]}
  local i
  local quoted
  local optionList=()

  for (( i=0; i<${#options[@]}; i++ )); do
    # Double escape, since we want escaped values, but compgen -W expands the argument
    printf -v quoted %q "${options[i]}"
    quoted=\'${quoted//\'/\'\\\'\'}\'

    optionList[i]=$quoted
  done

  # We also have to add another round of escaping to $curr_word.
  curr_word=${curr_word//\\/\\\\}
  curr_word=${curr_word//\'/\\\'}

  # Actually generate completions.
  local IFS=$'\n'
  echo -e "$(compgen -W "${optionList[*]}" -- "$curr_word")"
}

# Bash completion entry point function.
# _complete_taup finds which commands and subcommands have been specified
# on the command line and delegates to the appropriate function
# to generate possible options and subcommands for the last specified subcommand.
function _complete_taup() {
  # Edge case: if command line has no space after subcommand, then don't assume this subcommand is selected (remkop/picocli#1468).
  if [ "${COMP_LINE}" = "${COMP_WORDS[0]} create" ];    then _picocli_taup; return $?; fi
  if [ "${COMP_LINE}" = "${COMP_WORDS[0]} curve" ];    then _picocli_taup; return $?; fi
  if [ "${COMP_LINE}" = "${COMP_WORDS[0]} distaz" ];    then _picocli_taup; return $?; fi
  if [ "${COMP_LINE}" = "${COMP_WORDS[0]} discon" ];    then _picocli_taup; return $?; fi
  if [ "${COMP_LINE}" = "${COMP_WORDS[0]} find" ];    then _picocli_taup; return $?; fi
  if [ "${COMP_LINE}" = "${COMP_WORDS[0]} path" ];    then _picocli_taup; return $?; fi
  if [ "${COMP_LINE}" = "${COMP_WORDS[0]} phase" ];    then _picocli_taup; return $?; fi
  if [ "${COMP_LINE}" = "${COMP_WORDS[0]} pierce" ];    then _picocli_taup; return $?; fi
  if [ "${COMP_LINE}" = "${COMP_WORDS[0]} refltrans" ];    then _picocli_taup; return $?; fi
  if [ "${COMP_LINE}" = "${COMP_WORDS[0]} setms3" ];    then _picocli_taup; return $?; fi
  if [ "${COMP_LINE}" = "${COMP_WORDS[0]} setsac" ];    then _picocli_taup; return $?; fi
  if [ "${COMP_LINE}" = "${COMP_WORDS[0]} spikes" ];    then _picocli_taup; return $?; fi
  if [ "${COMP_LINE}" = "${COMP_WORDS[0]} table" ];    then _picocli_taup; return $?; fi
  if [ "${COMP_LINE}" = "${COMP_WORDS[0]} time" ];    then _picocli_taup; return $?; fi
  if [ "${COMP_LINE}" = "${COMP_WORDS[0]} velmerge" ];    then _picocli_taup; return $?; fi
  if [ "${COMP_LINE}" = "${COMP_WORDS[0]} velplot" ];    then _picocli_taup; return $?; fi
  if [ "${COMP_LINE}" = "${COMP_WORDS[0]} wavefront" ];    then _picocli_taup; return $?; fi
  if [ "${COMP_LINE}" = "${COMP_WORDS[0]} web" ];    then _picocli_taup; return $?; fi
  if [ "${COMP_LINE}" = "${COMP_WORDS[0]} generate-completion" ];    then _picocli_taup; return $?; fi
  if [ "${COMP_LINE}" = "${COMP_WORDS[0]} version" ];    then _picocli_taup; return $?; fi
  if [ "${COMP_LINE}" = "${COMP_WORDS[0]} help" ];    then _picocli_taup; return $?; fi

  # Find the longest sequence of subcommands and call the bash function for that subcommand.
  local cmds0=(create)
  local cmds1=(curve)
  local cmds2=(distaz)
  local cmds3=(discon)
  local cmds4=(find)
  local cmds5=(path)
  local cmds6=(phase)
  local cmds7=(pierce)
  local cmds8=(refltrans)
  local cmds9=(setms3)
  local cmds10=(setsac)
  local cmds11=(spikes)
  local cmds12=(table)
  local cmds13=(time)
  local cmds14=(velmerge)
  local cmds15=(velplot)
  local cmds16=(wavefront)
  local cmds17=(web)
  local cmds18=(generate-completion)
  local cmds19=(version)
  local cmds20=(help)

  if CompWordsContainsArray "${cmds20[@]}"; then _picocli_taup_help; return $?; fi
  if CompWordsContainsArray "${cmds19[@]}"; then _picocli_taup_version; return $?; fi
  if CompWordsContainsArray "${cmds18[@]}"; then _picocli_taup_generatecompletion; return $?; fi
  if CompWordsContainsArray "${cmds17[@]}"; then _picocli_taup_web; return $?; fi
  if CompWordsContainsArray "${cmds16[@]}"; then _picocli_taup_wavefront; return $?; fi
  if CompWordsContainsArray "${cmds15[@]}"; then _picocli_taup_velplot; return $?; fi
  if CompWordsContainsArray "${cmds14[@]}"; then _picocli_taup_velmerge; return $?; fi
  if CompWordsContainsArray "${cmds13[@]}"; then _picocli_taup_time; return $?; fi
  if CompWordsContainsArray "${cmds12[@]}"; then _picocli_taup_table; return $?; fi
  if CompWordsContainsArray "${cmds11[@]}"; then _picocli_taup_spikes; return $?; fi
  if CompWordsContainsArray "${cmds10[@]}"; then _picocli_taup_setsac; return $?; fi
  if CompWordsContainsArray "${cmds9[@]}"; then _picocli_taup_setms3; return $?; fi
  if CompWordsContainsArray "${cmds8[@]}"; then _picocli_taup_refltrans; return $?; fi
  if CompWordsContainsArray "${cmds7[@]}"; then _picocli_taup_pierce; return $?; fi
  if CompWordsContainsArray "${cmds6[@]}"; then _picocli_taup_phase; return $?; fi
  if CompWordsContainsArray "${cmds5[@]}"; then _picocli_taup_path; return $?; fi
  if CompWordsContainsArray "${cmds4[@]}"; then _picocli_taup_find; return $?; fi
  if CompWordsContainsArray "${cmds3[@]}"; then _picocli_taup_discon; return $?; fi
  if CompWordsContainsArray "${cmds2[@]}"; then _picocli_taup_distaz; return $?; fi
  if CompWordsContainsArray "${cmds1[@]}"; then _picocli_taup_curve; return $?; fi
  if CompWordsContainsArray "${cmds0[@]}"; then _picocli_taup_create; return $?; fi

  # No subcommands were specified; generate completions for the top-level command.
  _picocli_taup; return $?;
}

# Generates completions for the options and subcommands of the `taup` command.
function _picocli_taup() {
  # Get completion data
  local curr_word=${COMP_WORDS[COMP_CWORD]}

  local commands="create curve distaz discon find path phase pierce refltrans setms3 setsac spikes table time velmerge velplot wavefront web generate-completion version help"
  local flag_opts="-V --version --help"
  local arg_opts=""

  if [[ "${curr_word}" == -* ]]; then
    COMPREPLY=( $(compgen -W "${flag_opts} ${arg_opts}" -- "${curr_word}") )
  else
    local positionals=""
    local IFS=$'\n'
    COMPREPLY=( $(compgen -W "${commands// /$'\n'}${IFS}${positionals}" -- "${curr_word}") )
  fi
}

# Generates completions for the options and subcommands of the `create` subcommand.
function _picocli_taup_create() {
  # Get completion data
  local curr_word=${COMP_WORDS[COMP_CWORD]}
  local prev_word=${COMP_WORDS[COMP_CWORD-1]}

  local commands=""
  local flag_opts="--help --debug --verbose"
  local arg_opts="--prop --nd --tvel --mod --model"
  local modelName_option_args=("iasp91" "ak135" "prem" "ak135fcont" "ak135favg" "ak135fsyngine") # --model values

  type compopt &>/dev/null && compopt +o default

  case ${prev_word} in
    --prop)
      return
      ;;
    --nd)
      return
      ;;
    --tvel)
      return
      ;;
    --mod|--model)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${modelName_option_args[@]}" ) )
      return $?
      ;;
  esac

  if [[ "${curr_word}" == -* ]]; then
    COMPREPLY=( $(compgen -W "${flag_opts} ${arg_opts}" -- "${curr_word}") )
  else
    local positionals=""
    local IFS=$'\n'
    COMPREPLY=( $(compgen -W "${commands// /$'\n'}${IFS}${positionals}" -- "${curr_word}") )
  fi
}

# Generates completions for the options and subcommands of the `curve` subcommand.
function _picocli_taup_curve() {
  # Get completion data
  local curr_word=${COMP_WORDS[COMP_CWORD]}
  local prev_word=${COMP_WORDS[COMP_CWORD-1]}

  local commands=""
  local flag_opts="--help --debug --verbose --text --json --gmt --svg --html --text --json --gmt --svg --html --legend --xabs --yabs --xlog --ylog"
  local arg_opts="--prop --mod --model --stadepth --receiverdepth --scat --scatter -h --sourcedepth --evdepth --mod --model --stadepth --receiverdepth --scat --scatter -h --sourcedepth --evdepth --phasefile -p --phase --ph --attenuationfreq --numattenuationfreq --mw --strikediprake --az -o --output --mapwidth --mapwidthunit --color -x --xaxis -y --yaxis --xminmax --yminmax --rel --reddeg --redkm"
  local modelName_option_args=("iasp91" "ak135" "prem" "ak135fcont" "ak135favg" "ak135fsyngine") # --model values
  local modelName_option_args=("iasp91" "ak135" "prem" "ak135fcont" "ak135favg" "ak135fsyngine") # --model values
  local coloring_option_args=("auto" "wavetype" "phase" "none") # --color values
  local type_option_args=("radian" "radian180" "degree" "degree180" "kilometer" "kilometer180" "rayparamrad" "rayparamdeg" "rayparamkm" "time" "tau" "takeoffangle" "incidentangle" "turndepth" "amp" "amppsv" "ampsh" "geospread" "refltran" "refltranpsv" "refltransh" "index" "tstar" "attenuation" "theta" "energygeospread" "pathlength" "radiation" "radiationpsv" "radiationsh") # --xaxis values
  local type_option_args=("radian" "radian180" "degree" "degree180" "kilometer" "kilometer180" "rayparamrad" "rayparamdeg" "rayparamkm" "time" "tau" "takeoffangle" "incidentangle" "turndepth" "amp" "amppsv" "ampsh" "geospread" "refltran" "refltranpsv" "refltransh" "index" "tstar" "attenuation" "theta" "energygeospread" "pathlength" "radiation" "radiationpsv" "radiationsh") # --yaxis values

  type compopt &>/dev/null && compopt +o default

  case ${prev_word} in
    --prop)
      return
      ;;
    --mod|--model)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${modelName_option_args[@]}" ) )
      return $?
      ;;
    --stadepth|--receiverdepth)
      return
      ;;
    --scat|--scatter)
      return
      ;;
    -h|--sourcedepth|--evdepth)
      return
      ;;
    --mod|--model)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${modelName_option_args[@]}" ) )
      return $?
      ;;
    --stadepth|--receiverdepth)
      return
      ;;
    --scat|--scatter)
      return
      ;;
    -h|--sourcedepth|--evdepth)
      return
      ;;
    --phasefile)
      return
      ;;
    -p|--phase|--ph)
      return
      ;;
    --attenuationfreq)
      return
      ;;
    --numattenuationfreq)
      return
      ;;
    --mw)
      return
      ;;
    --strikediprake)
      return
      ;;
    --az)
      return
      ;;
    -o|--output)
      return
      ;;
    --mapwidth)
      return
      ;;
    --mapwidthunit)
      return
      ;;
    --color)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${coloring_option_args[@]}" ) )
      return $?
      ;;
    -x|--xaxis)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${type_option_args[@]}" ) )
      return $?
      ;;
    -y|--yaxis)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${type_option_args[@]}" ) )
      return $?
      ;;
    --xminmax)
      return
      ;;
    --yminmax)
      return
      ;;
    --rel)
      return
      ;;
    --reddeg)
      return
      ;;
    --redkm)
      return
      ;;
  esac

  if [[ "${curr_word}" == -* ]]; then
    COMPREPLY=( $(compgen -W "${flag_opts} ${arg_opts}" -- "${curr_word}") )
  else
    local positionals=""
    local IFS=$'\n'
    COMPREPLY=( $(compgen -W "${commands// /$'\n'}${IFS}${positionals}" -- "${curr_word}") )
  fi
}

# Generates completions for the options and subcommands of the `distaz` subcommand.
function _picocli_taup_distaz() {
  # Get completion data
  local curr_word=${COMP_WORDS[COMP_CWORD]}
  local prev_word=${COMP_WORDS[COMP_CWORD-1]}

  local commands=""
  local flag_opts="--help --debug --verbose --text --json --html --text --json --html --geodetic"
  local arg_opts="--prop -o --output --sta --station --evt --event --az --baz --eid --sid --qml --quakeml --staxml --geodeticflattening --deg --degree --degreerange --km --kilometer --kilometerrange --radius --mod --model"

  type compopt &>/dev/null && compopt +o default

  case ${prev_word} in
    --prop)
      return
      ;;
    -o|--output)
      return
      ;;
    --sta|--station)
      return
      ;;
    --evt|--event)
      return
      ;;
    --az)
      return
      ;;
    --baz)
      return
      ;;
    --eid)
      return
      ;;
    --sid)
      return
      ;;
    --qml|--quakeml)
      return
      ;;
    --staxml)
      return
      ;;
    --geodeticflattening)
      return
      ;;
    --deg|--degree)
      return
      ;;
    --degreerange)
      return
      ;;
    --km|--kilometer)
      return
      ;;
    --kilometerrange)
      return
      ;;
    --radius)
      return
      ;;
    --mod|--model)
      return
      ;;
  esac

  if [[ "${curr_word}" == -* ]]; then
    COMPREPLY=( $(compgen -W "${flag_opts} ${arg_opts}" -- "${curr_word}") )
  else
    local positionals=""
    local IFS=$'\n'
    COMPREPLY=( $(compgen -W "${commands// /$'\n'}${IFS}${positionals}" -- "${curr_word}") )
  fi
}

# Generates completions for the options and subcommands of the `discon` subcommand.
function _picocli_taup_discon() {
  # Get completion data
  local curr_word=${COMP_WORDS[COMP_CWORD]}
  local prev_word=${COMP_WORDS[COMP_CWORD-1]}

  local commands=""
  local flag_opts="--help --debug --verbose --text --json --html --text --json --html"
  local arg_opts="--prop --nd --tvel --mod --model -o --output"
  local model_option_args=("iasp91" "ak135" "prem" "ak135fcont" "ak135favg" "ak135fsyngine") # --model values

  type compopt &>/dev/null && compopt +o default

  case ${prev_word} in
    --prop)
      return
      ;;
    --nd)
      return
      ;;
    --tvel)
      return
      ;;
    --mod|--model)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${model_option_args[@]}" ) )
      return $?
      ;;
    -o|--output)
      return
      ;;
  esac

  if [[ "${curr_word}" == -* ]]; then
    COMPREPLY=( $(compgen -W "${flag_opts} ${arg_opts}" -- "${curr_word}") )
  else
    local positionals=""
    local IFS=$'\n'
    COMPREPLY=( $(compgen -W "${commands// /$'\n'}${IFS}${positionals}" -- "${curr_word}") )
  fi
}

# Generates completions for the options and subcommands of the `find` subcommand.
function _picocli_taup_find() {
  # Get completion data
  local curr_word=${COMP_WORDS[COMP_CWORD]}
  local prev_word=${COMP_WORDS[COMP_CWORD-1]}

  local commands=""
  local flag_opts="--help --debug --verbose --text --json --html --csv --text --json --html --csv --showrayparam --onlynameddiscon --pwaveonly --swaveonly --amp"
  local arg_opts="--prop --mod --model --stadepth --receiverdepth --scat --scatter -h --sourcedepth --evdepth --mod --model --stadepth --receiverdepth --scat --scatter -h --sourcedepth --evdepth --phasefile -p --phase --ph -o --output --max --rayparamdeg --rayparamkm --exclude --time --deltatime --attenuationfreq --numattenuationfreq --mw --strikediprake --az --deg --degree"
  local modelName_option_args=("iasp91" "ak135" "prem" "ak135fcont" "ak135favg" "ak135fsyngine") # --model values
  local modelName_option_args=("iasp91" "ak135" "prem" "ak135fcont" "ak135favg" "ak135fsyngine") # --model values

  type compopt &>/dev/null && compopt +o default

  case ${prev_word} in
    --prop)
      return
      ;;
    --mod|--model)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${modelName_option_args[@]}" ) )
      return $?
      ;;
    --stadepth|--receiverdepth)
      return
      ;;
    --scat|--scatter)
      return
      ;;
    -h|--sourcedepth|--evdepth)
      return
      ;;
    --mod|--model)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${modelName_option_args[@]}" ) )
      return $?
      ;;
    --stadepth|--receiverdepth)
      return
      ;;
    --scat|--scatter)
      return
      ;;
    -h|--sourcedepth|--evdepth)
      return
      ;;
    --phasefile)
      return
      ;;
    -p|--phase|--ph)
      return
      ;;
    -o|--output)
      return
      ;;
    --max)
      return
      ;;
    --rayparamdeg)
      return
      ;;
    --rayparamkm)
      return
      ;;
    --exclude)
      return
      ;;
    --time)
      return
      ;;
    --deltatime)
      return
      ;;
    --attenuationfreq)
      return
      ;;
    --numattenuationfreq)
      return
      ;;
    --mw)
      return
      ;;
    --strikediprake)
      return
      ;;
    --az)
      return
      ;;
    --deg|--degree)
      return
      ;;
  esac

  if [[ "${curr_word}" == -* ]]; then
    COMPREPLY=( $(compgen -W "${flag_opts} ${arg_opts}" -- "${curr_word}") )
  else
    local positionals=""
    local IFS=$'\n'
    COMPREPLY=( $(compgen -W "${commands// /$'\n'}${IFS}${positionals}" -- "${curr_word}") )
  fi
}

# Generates completions for the options and subcommands of the `path` subcommand.
function _picocli_taup_path() {
  # Get completion data
  local curr_word=${COMP_WORDS[COMP_CWORD]}
  local prev_word=${COMP_WORDS[COMP_CWORD-1]}

  local commands=""
  local flag_opts="--help --debug --verbose --allindex --allindex --geodetic --legend --label --onlynameddiscon --text --json --gmt --svg --html --text --json --gmt --svg --html --withtime"
  local arg_opts="--prop --mod --model --stadepth --receiverdepth --scat --scatter -h --sourcedepth --evdepth --mod --model --stadepth --receiverdepth --scat --scatter -h --sourcedepth --evdepth --phasefile -p --phase --ph --deg --degree --degreerange --km --kilometer --kilometerrange --exactdegree --exactdegreerange --exactkilometer --exactkilometerrange --takeoff --takeoffrange --incident --incidentrange --rayparamrad --rayparamdeg --rayparamkm --rayparamidx --sta --station --evt --event --az --baz --deg --degree --degreerange --km --kilometer --kilometerrange --exactdegree --exactdegreerange --exactkilometer --exactkilometerrange --takeoff --takeoffrange --incident --incidentrange --rayparamrad --rayparamdeg --rayparamkm --rayparamidx --sta --station --evt --event --az --baz --geodeticflattening --eid --sid --qml --quakeml --staxml --color --yaxis --xaxis --degminmax --depthminmax -o --output --mapwidth --mapwidthunit --maxpathinc"
  local modelName_option_args=("iasp91" "ak135" "prem" "ak135fcont" "ak135favg" "ak135fsyngine") # --model values
  local modelName_option_args=("iasp91" "ak135" "prem" "ak135fcont" "ak135favg" "ak135fsyngine") # --model values
  local coloring_option_args=("auto" "wavetype" "phase" "none") # --color values
  local type_option_args=("depth" "radius") # --yaxis values
  local type_option_args=("degree" "radian" "kilometer") # --xaxis values

  type compopt &>/dev/null && compopt +o default

  case ${prev_word} in
    --prop)
      return
      ;;
    --mod|--model)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${modelName_option_args[@]}" ) )
      return $?
      ;;
    --stadepth|--receiverdepth)
      return
      ;;
    --scat|--scatter)
      return
      ;;
    -h|--sourcedepth|--evdepth)
      return
      ;;
    --mod|--model)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${modelName_option_args[@]}" ) )
      return $?
      ;;
    --stadepth|--receiverdepth)
      return
      ;;
    --scat|--scatter)
      return
      ;;
    -h|--sourcedepth|--evdepth)
      return
      ;;
    --phasefile)
      return
      ;;
    -p|--phase|--ph)
      return
      ;;
    --deg|--degree)
      return
      ;;
    --degreerange)
      return
      ;;
    --km|--kilometer)
      return
      ;;
    --kilometerrange)
      return
      ;;
    --exactdegree)
      return
      ;;
    --exactdegreerange)
      return
      ;;
    --exactkilometer)
      return
      ;;
    --exactkilometerrange)
      return
      ;;
    --takeoff)
      return
      ;;
    --takeoffrange)
      return
      ;;
    --incident)
      return
      ;;
    --incidentrange)
      return
      ;;
    --rayparamrad)
      return
      ;;
    --rayparamdeg)
      return
      ;;
    --rayparamkm)
      return
      ;;
    --rayparamidx)
      return
      ;;
    --sta|--station)
      return
      ;;
    --evt|--event)
      return
      ;;
    --az)
      return
      ;;
    --baz)
      return
      ;;
    --deg|--degree)
      return
      ;;
    --degreerange)
      return
      ;;
    --km|--kilometer)
      return
      ;;
    --kilometerrange)
      return
      ;;
    --exactdegree)
      return
      ;;
    --exactdegreerange)
      return
      ;;
    --exactkilometer)
      return
      ;;
    --exactkilometerrange)
      return
      ;;
    --takeoff)
      return
      ;;
    --takeoffrange)
      return
      ;;
    --incident)
      return
      ;;
    --incidentrange)
      return
      ;;
    --rayparamrad)
      return
      ;;
    --rayparamdeg)
      return
      ;;
    --rayparamkm)
      return
      ;;
    --rayparamidx)
      return
      ;;
    --sta|--station)
      return
      ;;
    --evt|--event)
      return
      ;;
    --az)
      return
      ;;
    --baz)
      return
      ;;
    --geodeticflattening)
      return
      ;;
    --eid)
      return
      ;;
    --sid)
      return
      ;;
    --qml|--quakeml)
      return
      ;;
    --staxml)
      return
      ;;
    --color)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${coloring_option_args[@]}" ) )
      return $?
      ;;
    --yaxis)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${type_option_args[@]}" ) )
      return $?
      ;;
    --xaxis)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${type_option_args[@]}" ) )
      return $?
      ;;
    --degminmax)
      return
      ;;
    --depthminmax)
      return
      ;;
    -o|--output)
      return
      ;;
    --mapwidth)
      return
      ;;
    --mapwidthunit)
      return
      ;;
    --maxpathinc)
      return
      ;;
  esac

  if [[ "${curr_word}" == -* ]]; then
    COMPREPLY=( $(compgen -W "${flag_opts} ${arg_opts}" -- "${curr_word}") )
  else
    local positionals=""
    local IFS=$'\n'
    COMPREPLY=( $(compgen -W "${commands// /$'\n'}${IFS}${positionals}" -- "${curr_word}") )
  fi
}

# Generates completions for the options and subcommands of the `phase` subcommand.
function _picocli_taup_phase() {
  # Get completion data
  local curr_word=${COMP_WORDS[COMP_CWORD]}
  local prev_word=${COMP_WORDS[COMP_CWORD-1]}

  local commands=""
  local flag_opts="--help --debug --verbose --text --json --html --text --json --html"
  local arg_opts="--prop --mod --model --stadepth --receiverdepth --scat --scatter -h --sourcedepth --evdepth --mod --model --stadepth --receiverdepth --scat --scatter -h --sourcedepth --evdepth --phasefile -p --phase --ph -o --output"
  local modelName_option_args=("iasp91" "ak135" "prem" "ak135fcont" "ak135favg" "ak135fsyngine") # --model values
  local modelName_option_args=("iasp91" "ak135" "prem" "ak135fcont" "ak135favg" "ak135fsyngine") # --model values

  type compopt &>/dev/null && compopt +o default

  case ${prev_word} in
    --prop)
      return
      ;;
    --mod|--model)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${modelName_option_args[@]}" ) )
      return $?
      ;;
    --stadepth|--receiverdepth)
      return
      ;;
    --scat|--scatter)
      return
      ;;
    -h|--sourcedepth|--evdepth)
      return
      ;;
    --mod|--model)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${modelName_option_args[@]}" ) )
      return $?
      ;;
    --stadepth|--receiverdepth)
      return
      ;;
    --scat|--scatter)
      return
      ;;
    -h|--sourcedepth|--evdepth)
      return
      ;;
    --phasefile)
      return
      ;;
    -p|--phase|--ph)
      return
      ;;
    -o|--output)
      return
      ;;
  esac

  if [[ "${curr_word}" == -* ]]; then
    COMPREPLY=( $(compgen -W "${flag_opts} ${arg_opts}" -- "${curr_word}") )
  else
    local positionals=""
    local IFS=$'\n'
    COMPREPLY=( $(compgen -W "${commands// /$'\n'}${IFS}${positionals}" -- "${curr_word}") )
  fi
}

# Generates completions for the options and subcommands of the `pierce` subcommand.
function _picocli_taup_pierce() {
  # Get completion data
  local curr_word=${COMP_WORDS[COMP_CWORD]}
  local prev_word=${COMP_WORDS[COMP_CWORD-1]}

  local commands=""
  local flag_opts="--help --debug --verbose --allindex --allindex --geodetic --text --json --html --text --json --html --first --onlyfirst --amp --turn --rev --under --nodiscon"
  local arg_opts="--prop --mod --model --stadepth --receiverdepth --scat --scatter -h --sourcedepth --evdepth --mod --model --stadepth --receiverdepth --scat --scatter -h --sourcedepth --evdepth --phasefile -p --phase --ph --deg --degree --degreerange --km --kilometer --kilometerrange --exactdegree --exactdegreerange --exactkilometer --exactkilometerrange --takeoff --takeoffrange --incident --incidentrange --rayparamrad --rayparamdeg --rayparamkm --rayparamidx --sta --station --evt --event --az --baz --deg --degree --degreerange --km --kilometer --kilometerrange --exactdegree --exactdegreerange --exactkilometer --exactkilometerrange --takeoff --takeoffrange --incident --incidentrange --rayparamrad --rayparamdeg --rayparamkm --rayparamidx --sta --station --evt --event --az --baz --geodeticflattening --eid --sid --qml --quakeml --staxml -o --output --attenuationfreq --numattenuationfreq --mw --strikediprake --pierce"
  local modelName_option_args=("iasp91" "ak135" "prem" "ak135fcont" "ak135favg" "ak135fsyngine") # --model values
  local modelName_option_args=("iasp91" "ak135" "prem" "ak135fcont" "ak135favg" "ak135fsyngine") # --model values

  type compopt &>/dev/null && compopt +o default

  case ${prev_word} in
    --prop)
      return
      ;;
    --mod|--model)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${modelName_option_args[@]}" ) )
      return $?
      ;;
    --stadepth|--receiverdepth)
      return
      ;;
    --scat|--scatter)
      return
      ;;
    -h|--sourcedepth|--evdepth)
      return
      ;;
    --mod|--model)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${modelName_option_args[@]}" ) )
      return $?
      ;;
    --stadepth|--receiverdepth)
      return
      ;;
    --scat|--scatter)
      return
      ;;
    -h|--sourcedepth|--evdepth)
      return
      ;;
    --phasefile)
      return
      ;;
    -p|--phase|--ph)
      return
      ;;
    --deg|--degree)
      return
      ;;
    --degreerange)
      return
      ;;
    --km|--kilometer)
      return
      ;;
    --kilometerrange)
      return
      ;;
    --exactdegree)
      return
      ;;
    --exactdegreerange)
      return
      ;;
    --exactkilometer)
      return
      ;;
    --exactkilometerrange)
      return
      ;;
    --takeoff)
      return
      ;;
    --takeoffrange)
      return
      ;;
    --incident)
      return
      ;;
    --incidentrange)
      return
      ;;
    --rayparamrad)
      return
      ;;
    --rayparamdeg)
      return
      ;;
    --rayparamkm)
      return
      ;;
    --rayparamidx)
      return
      ;;
    --sta|--station)
      return
      ;;
    --evt|--event)
      return
      ;;
    --az)
      return
      ;;
    --baz)
      return
      ;;
    --deg|--degree)
      return
      ;;
    --degreerange)
      return
      ;;
    --km|--kilometer)
      return
      ;;
    --kilometerrange)
      return
      ;;
    --exactdegree)
      return
      ;;
    --exactdegreerange)
      return
      ;;
    --exactkilometer)
      return
      ;;
    --exactkilometerrange)
      return
      ;;
    --takeoff)
      return
      ;;
    --takeoffrange)
      return
      ;;
    --incident)
      return
      ;;
    --incidentrange)
      return
      ;;
    --rayparamrad)
      return
      ;;
    --rayparamdeg)
      return
      ;;
    --rayparamkm)
      return
      ;;
    --rayparamidx)
      return
      ;;
    --sta|--station)
      return
      ;;
    --evt|--event)
      return
      ;;
    --az)
      return
      ;;
    --baz)
      return
      ;;
    --geodeticflattening)
      return
      ;;
    --eid)
      return
      ;;
    --sid)
      return
      ;;
    --qml|--quakeml)
      return
      ;;
    --staxml)
      return
      ;;
    -o|--output)
      return
      ;;
    --attenuationfreq)
      return
      ;;
    --numattenuationfreq)
      return
      ;;
    --mw)
      return
      ;;
    --strikediprake)
      return
      ;;
    --pierce)
      return
      ;;
  esac

  if [[ "${curr_word}" == -* ]]; then
    COMPREPLY=( $(compgen -W "${flag_opts} ${arg_opts}" -- "${curr_word}") )
  else
    local positionals=""
    local IFS=$'\n'
    COMPREPLY=( $(compgen -W "${commands// /$'\n'}${IFS}${positionals}" -- "${curr_word}") )
  fi
}

# Generates completions for the options and subcommands of the `refltrans` subcommand.
function _picocli_taup_refltrans() {
  # Get completion data
  local curr_word=${COMP_WORDS[COMP_CWORD]}
  local prev_word=${COMP_WORDS[COMP_CWORD-1]}

  local commands=""
  local flag_opts="--help --debug --verbose --text --json --gmt --svg --html --text --json --gmt --svg --html --legend --angles --down --up --pwave --swave --shwave --energyflux --fsrf --abs"
  local arg_opts="--prop -o --output --mapwidth --mapwidthunit --mod --model --stadepth --receiverdepth --scat --scatter -h --sourcedepth --evdepth --mod --model --stadepth --receiverdepth --scat --scatter -h --sourcedepth --evdepth --depth --layer --anglestep --rpstep -x -y --xminmax --yminmax"
  local modelName_option_args=("iasp91" "ak135" "prem" "ak135fcont" "ak135favg" "ak135fsyngine") # --model values
  local modelName_option_args=("iasp91" "ak135" "prem" "ak135fcont" "ak135favg" "ak135fsyngine") # --model values
  local type_option_args=("degree" "rayparam") # -x values
  local type_option_args=("Rpp" "Rps" "Rsp" "Rss" "Tpp" "Tps" "Tsp" "Tss" "Rshsh" "Tshsh" "RppEnergy" "TppEnergy" "RpsEnergy" "TpsEnergy" "RspEnergy" "TspEnergy" "RssEnergy" "TssEnergy" "RshshEnergy" "TshshEnergy" "RpAngle" "RsAngle" "TpAngle" "TsAngle" "FreeRecFuncPr" "FreeRecFuncSvr" "FreeRecFuncPz" "FreeRecFuncSvz" "FreeRecFuncSh") # -y values

  type compopt &>/dev/null && compopt +o default

  case ${prev_word} in
    --prop)
      return
      ;;
    -o|--output)
      return
      ;;
    --mapwidth)
      return
      ;;
    --mapwidthunit)
      return
      ;;
    --mod|--model)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${modelName_option_args[@]}" ) )
      return $?
      ;;
    --stadepth|--receiverdepth)
      return
      ;;
    --scat|--scatter)
      return
      ;;
    -h|--sourcedepth|--evdepth)
      return
      ;;
    --mod|--model)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${modelName_option_args[@]}" ) )
      return $?
      ;;
    --stadepth|--receiverdepth)
      return
      ;;
    --scat|--scatter)
      return
      ;;
    -h|--sourcedepth|--evdepth)
      return
      ;;
    --depth)
      return
      ;;
    --layer)
      return
      ;;
    --anglestep)
      return
      ;;
    --rpstep)
      return
      ;;
    -x)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${type_option_args[@]}" ) )
      return $?
      ;;
    -y)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${type_option_args[@]}" ) )
      return $?
      ;;
    --xminmax)
      return
      ;;
    --yminmax)
      return
      ;;
  esac

  if [[ "${curr_word}" == -* ]]; then
    COMPREPLY=( $(compgen -W "${flag_opts} ${arg_opts}" -- "${curr_word}") )
  else
    local positionals=""
    local IFS=$'\n'
    COMPREPLY=( $(compgen -W "${commands// /$'\n'}${IFS}${positionals}" -- "${curr_word}") )
  fi
}

# Generates completions for the options and subcommands of the `setms3` subcommand.
function _picocli_taup_setms3() {
  # Get completion data
  local curr_word=${COMP_WORDS[COMP_CWORD]}
  local prev_word=${COMP_WORDS[COMP_CWORD-1]}

  local commands=""
  local flag_opts="--help --debug --verbose --geodetic --amp"
  local arg_opts="--prop --mod --model --stadepth --receiverdepth --scat --scatter -h --sourcedepth --evdepth --mod --model --stadepth --receiverdepth --scat --scatter -h --sourcedepth --evdepth --phasefile -p --phase --ph --eid --sid --qml --quakeml --staxml --geodeticflattening --attenuationfreq --numattenuationfreq --mw --strikediprake --taupeh --qmltol"
  local modelName_option_args=("iasp91" "ak135" "prem" "ak135fcont" "ak135favg" "ak135fsyngine") # --model values
  local modelName_option_args=("iasp91" "ak135" "prem" "ak135fcont" "ak135favg" "ak135fsyngine") # --model values

  type compopt &>/dev/null && compopt +o default

  case ${prev_word} in
    --prop)
      return
      ;;
    --mod|--model)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${modelName_option_args[@]}" ) )
      return $?
      ;;
    --stadepth|--receiverdepth)
      return
      ;;
    --scat|--scatter)
      return
      ;;
    -h|--sourcedepth|--evdepth)
      return
      ;;
    --mod|--model)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${modelName_option_args[@]}" ) )
      return $?
      ;;
    --stadepth|--receiverdepth)
      return
      ;;
    --scat|--scatter)
      return
      ;;
    -h|--sourcedepth|--evdepth)
      return
      ;;
    --phasefile)
      return
      ;;
    -p|--phase|--ph)
      return
      ;;
    --eid)
      return
      ;;
    --sid)
      return
      ;;
    --qml|--quakeml)
      return
      ;;
    --staxml)
      return
      ;;
    --geodeticflattening)
      return
      ;;
    --attenuationfreq)
      return
      ;;
    --numattenuationfreq)
      return
      ;;
    --mw)
      return
      ;;
    --strikediprake)
      return
      ;;
    --taupeh)
      return
      ;;
    --qmltol)
      return
      ;;
  esac

  if [[ "${curr_word}" == -* ]]; then
    COMPREPLY=( $(compgen -W "${flag_opts} ${arg_opts}" -- "${curr_word}") )
  else
    local positionals=""
    local IFS=$'\n'
    COMPREPLY=( $(compgen -W "${commands// /$'\n'}${IFS}${positionals}" -- "${curr_word}") )
  fi
}

# Generates completions for the options and subcommands of the `setsac` subcommand.
function _picocli_taup_setsac() {
  # Get completion data
  local curr_word=${COMP_WORDS[COMP_CWORD]}
  local prev_word=${COMP_WORDS[COMP_CWORD-1]}

  local commands=""
  local flag_opts="--help --debug --verbose --geodetic --evdpkm"
  local arg_opts="--prop --mod --model --stadepth --receiverdepth --scat --scatter -h --sourcedepth --evdepth --mod --model --stadepth --receiverdepth --scat --scatter -h --sourcedepth --evdepth --phasefile -p --phase --ph --geodeticflattening"
  local modelName_option_args=("iasp91" "ak135" "prem" "ak135fcont" "ak135favg" "ak135fsyngine") # --model values
  local modelName_option_args=("iasp91" "ak135" "prem" "ak135fcont" "ak135favg" "ak135fsyngine") # --model values

  type compopt &>/dev/null && compopt +o default

  case ${prev_word} in
    --prop)
      return
      ;;
    --mod|--model)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${modelName_option_args[@]}" ) )
      return $?
      ;;
    --stadepth|--receiverdepth)
      return
      ;;
    --scat|--scatter)
      return
      ;;
    -h|--sourcedepth|--evdepth)
      return
      ;;
    --mod|--model)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${modelName_option_args[@]}" ) )
      return $?
      ;;
    --stadepth|--receiverdepth)
      return
      ;;
    --scat|--scatter)
      return
      ;;
    -h|--sourcedepth|--evdepth)
      return
      ;;
    --phasefile)
      return
      ;;
    -p|--phase|--ph)
      return
      ;;
    --geodeticflattening)
      return
      ;;
  esac

  if [[ "${curr_word}" == -* ]]; then
    COMPREPLY=( $(compgen -W "${flag_opts} ${arg_opts}" -- "${curr_word}") )
  else
    local positionals=""
    local IFS=$'\n'
    COMPREPLY=( $(compgen -W "${commands// /$'\n'}${IFS}${positionals}" -- "${curr_word}") )
  fi
}

# Generates completions for the options and subcommands of the `spikes` subcommand.
function _picocli_taup_spikes() {
  # Get completion data
  local curr_word=${COMP_WORDS[COMP_CWORD]}
  local prev_word=${COMP_WORDS[COMP_CWORD-1]}

  local commands=""
  local flag_opts="--help --debug --verbose --ms3 --sac --ms3 --sac --geodetic"
  local arg_opts="--prop --mod --model --stadepth --receiverdepth --scat --scatter -h --sourcedepth --evdepth --mod --model --stadepth --receiverdepth --scat --scatter -h --sourcedepth --evdepth --phasefile -p --phase --ph --attenuationfreq --numattenuationfreq --mw --strikediprake --otime -o --output sps --pulsewidth --deg --degree --degreerange --km --kilometer --kilometerrange --sta --station --evt --event --az --baz --geodeticflattening --eid --sid --qml --quakeml --staxml"
  local modelName_option_args=("iasp91" "ak135" "prem" "ak135fcont" "ak135favg" "ak135fsyngine") # --model values
  local modelName_option_args=("iasp91" "ak135" "prem" "ak135fcont" "ak135favg" "ak135fsyngine") # --model values

  type compopt &>/dev/null && compopt +o default

  case ${prev_word} in
    --prop)
      return
      ;;
    --mod|--model)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${modelName_option_args[@]}" ) )
      return $?
      ;;
    --stadepth|--receiverdepth)
      return
      ;;
    --scat|--scatter)
      return
      ;;
    -h|--sourcedepth|--evdepth)
      return
      ;;
    --mod|--model)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${modelName_option_args[@]}" ) )
      return $?
      ;;
    --stadepth|--receiverdepth)
      return
      ;;
    --scat|--scatter)
      return
      ;;
    -h|--sourcedepth|--evdepth)
      return
      ;;
    --phasefile)
      return
      ;;
    -p|--phase|--ph)
      return
      ;;
    --attenuationfreq)
      return
      ;;
    --numattenuationfreq)
      return
      ;;
    --mw)
      return
      ;;
    --strikediprake)
      return
      ;;
    --otime)
      return
      ;;
    -o|--output)
      return
      ;;
    sps)
      return
      ;;
    --pulsewidth)
      return
      ;;
    --deg|--degree)
      return
      ;;
    --degreerange)
      return
      ;;
    --km|--kilometer)
      return
      ;;
    --kilometerrange)
      return
      ;;
    --sta|--station)
      return
      ;;
    --evt|--event)
      return
      ;;
    --az)
      return
      ;;
    --baz)
      return
      ;;
    --geodeticflattening)
      return
      ;;
    --eid)
      return
      ;;
    --sid)
      return
      ;;
    --qml|--quakeml)
      return
      ;;
    --staxml)
      return
      ;;
  esac

  if [[ "${curr_word}" == -* ]]; then
    COMPREPLY=( $(compgen -W "${flag_opts} ${arg_opts}" -- "${curr_word}") )
  else
    local positionals=""
    local IFS=$'\n'
    COMPREPLY=( $(compgen -W "${commands// /$'\n'}${IFS}${positionals}" -- "${curr_word}") )
  fi
}

# Generates completions for the options and subcommands of the `table` subcommand.
function _picocli_taup_table() {
  # Get completion data
  local curr_word=${COMP_WORDS[COMP_CWORD]}
  local prev_word=${COMP_WORDS[COMP_CWORD-1]}

  local commands=""
  local flag_opts="--help --debug --verbose --text --generic --json --html --csv --locsat --text --generic --json --html --csv --locsat"
  local arg_opts="--prop -o --output --mod --model --stadepth --receiverdepth --scat --scatter --phasefile -p --phase --ph --header"
  local modelName_option_args=("iasp91" "ak135" "prem" "ak135fcont" "ak135favg" "ak135fsyngine") # --model values

  type compopt &>/dev/null && compopt +o default

  case ${prev_word} in
    --prop)
      return
      ;;
    -o|--output)
      return
      ;;
    --mod|--model)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${modelName_option_args[@]}" ) )
      return $?
      ;;
    --stadepth|--receiverdepth)
      return
      ;;
    --scat|--scatter)
      return
      ;;
    --phasefile)
      return
      ;;
    -p|--phase|--ph)
      return
      ;;
    --header)
      return
      ;;
  esac

  if [[ "${curr_word}" == -* ]]; then
    COMPREPLY=( $(compgen -W "${flag_opts} ${arg_opts}" -- "${curr_word}") )
  else
    local positionals=""
    local IFS=$'\n'
    COMPREPLY=( $(compgen -W "${commands// /$'\n'}${IFS}${positionals}" -- "${curr_word}") )
  fi
}

# Generates completions for the options and subcommands of the `time` subcommand.
function _picocli_taup_time() {
  # Get completion data
  local curr_word=${COMP_WORDS[COMP_CWORD]}
  local prev_word=${COMP_WORDS[COMP_CWORD-1]}

  local commands=""
  local flag_opts="--help --debug --verbose --allindex --allindex --geodetic --rayp --onlyrayp --time --onlytime --first --onlyfirst --amp --text --json --html --csv --text --json --html --csv"
  local arg_opts="--prop --mod --model --stadepth --receiverdepth --scat --scatter -h --sourcedepth --evdepth --mod --model --stadepth --receiverdepth --scat --scatter -h --sourcedepth --evdepth --phasefile -p --phase --ph --deg --degree --degreerange --km --kilometer --kilometerrange --exactdegree --exactdegreerange --exactkilometer --exactkilometerrange --takeoff --takeoffrange --incident --incidentrange --rayparamrad --rayparamdeg --rayparamkm --rayparamidx --sta --station --evt --event --az --baz --deg --degree --degreerange --km --kilometer --kilometerrange --exactdegree --exactdegreerange --exactkilometer --exactkilometerrange --takeoff --takeoffrange --incident --incidentrange --rayparamrad --rayparamdeg --rayparamkm --rayparamidx --sta --station --evt --event --az --baz --geodeticflattening --eid --sid --qml --quakeml --staxml --attenuationfreq --numattenuationfreq --mw --strikediprake --rel -o --output"
  local modelName_option_args=("iasp91" "ak135" "prem" "ak135fcont" "ak135favg" "ak135fsyngine") # --model values
  local modelName_option_args=("iasp91" "ak135" "prem" "ak135fcont" "ak135favg" "ak135fsyngine") # --model values

  type compopt &>/dev/null && compopt +o default

  case ${prev_word} in
    --prop)
      return
      ;;
    --mod|--model)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${modelName_option_args[@]}" ) )
      return $?
      ;;
    --stadepth|--receiverdepth)
      return
      ;;
    --scat|--scatter)
      return
      ;;
    -h|--sourcedepth|--evdepth)
      return
      ;;
    --mod|--model)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${modelName_option_args[@]}" ) )
      return $?
      ;;
    --stadepth|--receiverdepth)
      return
      ;;
    --scat|--scatter)
      return
      ;;
    -h|--sourcedepth|--evdepth)
      return
      ;;
    --phasefile)
      return
      ;;
    -p|--phase|--ph)
      return
      ;;
    --deg|--degree)
      return
      ;;
    --degreerange)
      return
      ;;
    --km|--kilometer)
      return
      ;;
    --kilometerrange)
      return
      ;;
    --exactdegree)
      return
      ;;
    --exactdegreerange)
      return
      ;;
    --exactkilometer)
      return
      ;;
    --exactkilometerrange)
      return
      ;;
    --takeoff)
      return
      ;;
    --takeoffrange)
      return
      ;;
    --incident)
      return
      ;;
    --incidentrange)
      return
      ;;
    --rayparamrad)
      return
      ;;
    --rayparamdeg)
      return
      ;;
    --rayparamkm)
      return
      ;;
    --rayparamidx)
      return
      ;;
    --sta|--station)
      return
      ;;
    --evt|--event)
      return
      ;;
    --az)
      return
      ;;
    --baz)
      return
      ;;
    --deg|--degree)
      return
      ;;
    --degreerange)
      return
      ;;
    --km|--kilometer)
      return
      ;;
    --kilometerrange)
      return
      ;;
    --exactdegree)
      return
      ;;
    --exactdegreerange)
      return
      ;;
    --exactkilometer)
      return
      ;;
    --exactkilometerrange)
      return
      ;;
    --takeoff)
      return
      ;;
    --takeoffrange)
      return
      ;;
    --incident)
      return
      ;;
    --incidentrange)
      return
      ;;
    --rayparamrad)
      return
      ;;
    --rayparamdeg)
      return
      ;;
    --rayparamkm)
      return
      ;;
    --rayparamidx)
      return
      ;;
    --sta|--station)
      return
      ;;
    --evt|--event)
      return
      ;;
    --az)
      return
      ;;
    --baz)
      return
      ;;
    --geodeticflattening)
      return
      ;;
    --eid)
      return
      ;;
    --sid)
      return
      ;;
    --qml|--quakeml)
      return
      ;;
    --staxml)
      return
      ;;
    --attenuationfreq)
      return
      ;;
    --numattenuationfreq)
      return
      ;;
    --mw)
      return
      ;;
    --strikediprake)
      return
      ;;
    --rel)
      return
      ;;
    -o|--output)
      return
      ;;
  esac

  if [[ "${curr_word}" == -* ]]; then
    COMPREPLY=( $(compgen -W "${flag_opts} ${arg_opts}" -- "${curr_word}") )
  else
    local positionals=""
    local IFS=$'\n'
    COMPREPLY=( $(compgen -W "${commands// /$'\n'}${IFS}${positionals}" -- "${curr_word}") )
  fi
}

# Generates completions for the options and subcommands of the `velmerge` subcommand.
function _picocli_taup_velmerge() {
  # Get completion data
  local curr_word=${COMP_WORDS[COMP_CWORD]}
  local prev_word=${COMP_WORDS[COMP_CWORD-1]}

  local commands=""
  local flag_opts="--help --debug --verbose --smoothtop --smoothbot"
  local arg_opts="--prop --nd --tvel --mod --model --ndmerge --tvelmerge --modmerge --elev -o --output"
  local modelName_option_args=("iasp91" "ak135" "prem" "ak135fcont" "ak135favg" "ak135fsyngine") # --model values

  type compopt &>/dev/null && compopt +o default

  case ${prev_word} in
    --prop)
      return
      ;;
    --nd)
      return
      ;;
    --tvel)
      return
      ;;
    --mod|--model)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${modelName_option_args[@]}" ) )
      return $?
      ;;
    --ndmerge)
      return
      ;;
    --tvelmerge)
      return
      ;;
    --modmerge)
      return
      ;;
    --elev)
      return
      ;;
    -o|--output)
      return
      ;;
  esac

  if [[ "${curr_word}" == -* ]]; then
    COMPREPLY=( $(compgen -W "${flag_opts} ${arg_opts}" -- "${curr_word}") )
  else
    local positionals=""
    local IFS=$'\n'
    COMPREPLY=( $(compgen -W "${commands// /$'\n'}${IFS}${positionals}" -- "${curr_word}") )
  fi
}

# Generates completions for the options and subcommands of the `velplot` subcommand.
function _picocli_taup_velplot() {
  # Get completion data
  local curr_word=${COMP_WORDS[COMP_CWORD]}
  local prev_word=${COMP_WORDS[COMP_CWORD-1]}

  local commands=""
  local flag_opts="--help --debug --verbose --text --json --gmt --svg --html --csv --nameddiscon --text --json --gmt --svg --html --csv --nameddiscon --legend"
  local arg_opts="--prop --nd --tvel --mod --model -o --output --mapwidth --mapwidthunit -x --xaxis -y --yaxis --xminmax --yminmax"
  local model_option_args=("iasp91" "ak135" "prem" "ak135fcont" "ak135favg" "ak135fsyngine") # --model values
  local type_option_args=("depth" "radius" "velocity" "Vp" "Vs" "slownessdeg" "slownessdeg_p" "slownessdeg_s" "slownessrad" "slownessrad_p" "slownessrad_s" "density" "velocity_density" "Qp" "Qs" "Q" "vpvs" "vpdensity" "vsdensity" "poisson" "shearmodulus" "lambda" "bulkmodulus" "youngsmodulus") # --xaxis values
  local type_option_args=("depth" "radius" "velocity" "Vp" "Vs" "slownessdeg" "slownessdeg_p" "slownessdeg_s" "slownessrad" "slownessrad_p" "slownessrad_s" "density" "velocity_density" "Qp" "Qs" "Q" "vpvs" "vpdensity" "vsdensity" "poisson" "shearmodulus" "lambda" "bulkmodulus" "youngsmodulus") # --yaxis values

  type compopt &>/dev/null && compopt +o default

  case ${prev_word} in
    --prop)
      return
      ;;
    --nd)
      return
      ;;
    --tvel)
      return
      ;;
    --mod|--model)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${model_option_args[@]}" ) )
      return $?
      ;;
    -o|--output)
      return
      ;;
    --mapwidth)
      return
      ;;
    --mapwidthunit)
      return
      ;;
    -x|--xaxis)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${type_option_args[@]}" ) )
      return $?
      ;;
    -y|--yaxis)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${type_option_args[@]}" ) )
      return $?
      ;;
    --xminmax)
      return
      ;;
    --yminmax)
      return
      ;;
  esac

  if [[ "${curr_word}" == -* ]]; then
    COMPREPLY=( $(compgen -W "${flag_opts} ${arg_opts}" -- "${curr_word}") )
  else
    local positionals=""
    local IFS=$'\n'
    COMPREPLY=( $(compgen -W "${commands// /$'\n'}${IFS}${positionals}" -- "${curr_word}") )
  fi
}

# Generates completions for the options and subcommands of the `wavefront` subcommand.
function _picocli_taup_wavefront() {
  # Get completion data
  local curr_word=${COMP_WORDS[COMP_CWORD]}
  local prev_word=${COMP_WORDS[COMP_CWORD-1]}

  local commands=""
  local flag_opts="--help --debug --verbose --legend --onlynameddiscon --text --json --gmt --svg --html --text --json --gmt --svg --html --timefiles --negdist"
  local arg_opts="--prop --mod --model --stadepth --receiverdepth --scat --scatter -h --sourcedepth --evdepth --mod --model --stadepth --receiverdepth --scat --scatter -h --sourcedepth --evdepth --phasefile -p --phase --ph --color --yaxis --xaxis --degminmax --depthminmax -o --output --mapwidth --mapwidthunit --timestep"
  local modelName_option_args=("iasp91" "ak135" "prem" "ak135fcont" "ak135favg" "ak135fsyngine") # --model values
  local modelName_option_args=("iasp91" "ak135" "prem" "ak135fcont" "ak135favg" "ak135fsyngine") # --model values
  local coloring_option_args=("auto" "wavetype" "phase" "none") # --color values
  local type_option_args=("depth" "radius") # --yaxis values
  local type_option_args=("degree" "radian" "kilometer") # --xaxis values

  type compopt &>/dev/null && compopt +o default

  case ${prev_word} in
    --prop)
      return
      ;;
    --mod|--model)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${modelName_option_args[@]}" ) )
      return $?
      ;;
    --stadepth|--receiverdepth)
      return
      ;;
    --scat|--scatter)
      return
      ;;
    -h|--sourcedepth|--evdepth)
      return
      ;;
    --mod|--model)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${modelName_option_args[@]}" ) )
      return $?
      ;;
    --stadepth|--receiverdepth)
      return
      ;;
    --scat|--scatter)
      return
      ;;
    -h|--sourcedepth|--evdepth)
      return
      ;;
    --phasefile)
      return
      ;;
    -p|--phase|--ph)
      return
      ;;
    --color)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${coloring_option_args[@]}" ) )
      return $?
      ;;
    --yaxis)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${type_option_args[@]}" ) )
      return $?
      ;;
    --xaxis)
      local IFS=$'\n'
      COMPREPLY=( $( compReplyArray "${type_option_args[@]}" ) )
      return $?
      ;;
    --degminmax)
      return
      ;;
    --depthminmax)
      return
      ;;
    -o|--output)
      return
      ;;
    --mapwidth)
      return
      ;;
    --mapwidthunit)
      return
      ;;
    --timestep)
      return
      ;;
  esac

  if [[ "${curr_word}" == -* ]]; then
    COMPREPLY=( $(compgen -W "${flag_opts} ${arg_opts}" -- "${curr_word}") )
  else
    local positionals=""
    local IFS=$'\n'
    COMPREPLY=( $(compgen -W "${commands// /$'\n'}${IFS}${positionals}" -- "${curr_word}") )
  fi
}

# Generates completions for the options and subcommands of the `web` subcommand.
function _picocli_taup_web() {
  # Get completion data
  local curr_word=${COMP_WORDS[COMP_CWORD]}
  local prev_word=${COMP_WORDS[COMP_CWORD-1]}

  local commands=""
  local flag_opts="--nodefaultmodels --open --debug --verbose"
  local arg_opts="-p --port --host --namespace --models"

  type compopt &>/dev/null && compopt +o default

  case ${prev_word} in
    -p|--port)
      return
      ;;
    --host)
      return
      ;;
    --namespace)
      return
      ;;
    --models)
      return
      ;;
  esac

  if [[ "${curr_word}" == -* ]]; then
    COMPREPLY=( $(compgen -W "${flag_opts} ${arg_opts}" -- "${curr_word}") )
  else
    local positionals=""
    local IFS=$'\n'
    COMPREPLY=( $(compgen -W "${commands// /$'\n'}${IFS}${positionals}" -- "${curr_word}") )
  fi
}

# Generates completions for the options and subcommands of the `generate-completion` subcommand.
function _picocli_taup_generatecompletion() {
  # Get completion data
  local curr_word=${COMP_WORDS[COMP_CWORD]}

  local commands=""
  local flag_opts="-h --help -V --version"
  local arg_opts=""

  if [[ "${curr_word}" == -* ]]; then
    COMPREPLY=( $(compgen -W "${flag_opts} ${arg_opts}" -- "${curr_word}") )
  else
    local positionals=""
    local IFS=$'\n'
    COMPREPLY=( $(compgen -W "${commands// /$'\n'}${IFS}${positionals}" -- "${curr_word}") )
  fi
}

# Generates completions for the options and subcommands of the `version` subcommand.
function _picocli_taup_version() {
  # Get completion data
  local curr_word=${COMP_WORDS[COMP_CWORD]}
  local prev_word=${COMP_WORDS[COMP_CWORD-1]}

  local commands=""
  local flag_opts="--help --debug --verbose --text --json --html --text --json --html"
  local arg_opts="--prop -o --output"

  type compopt &>/dev/null && compopt +o default

  case ${prev_word} in
    --prop)
      return
      ;;
    -o|--output)
      return
      ;;
  esac

  if [[ "${curr_word}" == -* ]]; then
    COMPREPLY=( $(compgen -W "${flag_opts} ${arg_opts}" -- "${curr_word}") )
  else
    local positionals=""
    local IFS=$'\n'
    COMPREPLY=( $(compgen -W "${commands// /$'\n'}${IFS}${positionals}" -- "${curr_word}") )
  fi
}

# Generates completions for the options and subcommands of the `help` subcommand.
function _picocli_taup_help() {
  # Get completion data
  local curr_word=${COMP_WORDS[COMP_CWORD]}

  local commands="create curve distaz discon find path phase pierce refltrans setms3 setsac spikes table time velmerge velplot wavefront web generate-completion version"
  local flag_opts="-h --help"
  local arg_opts=""

  if [[ "${curr_word}" == -* ]]; then
    COMPREPLY=( $(compgen -W "${flag_opts} ${arg_opts}" -- "${curr_word}") )
  else
    local positionals=""
    local IFS=$'\n'
    COMPREPLY=( $(compgen -W "${commands// /$'\n'}${IFS}${positionals}" -- "${curr_word}") )
  fi
}

# Define a completion specification (a compspec) for the
# `taup`, `taup.sh`, and `taup.bash` commands.
# Uses the bash `complete` builtin (see [6]) to specify that shell function
# `_complete_taup` is responsible for generating possible completions for the
# current word on the command line.
# The `-o default` option means that if the function generated no matches, the
# default Bash completions and the Readline default filename completions are performed.
complete -F _complete_taup -o default taup taup.sh taup.bash
