code: function parseTemplate (str) {
    var fields = []
    var char = ''
    var pos = 0
    var prefix = ''
    var match = null
    var input
  
    while (true) { // eslint-disable-line no-constant-condition
      char = str[pos]
  
      if (!char) {
        fields.push({
          prefix: prefix,
          placeholder: null
        })
        break
      } else if (char === '[') {
        input = str.slice(pos)
        match = SIMPLE_PLACEHOLDER_RX.exec(input)
        if (match) {
          fields.push({
            prefix: prefix,
            placeholder: match[1].toLowerCase()
          })
          pos += match[0].length
          prefix = ''
          continue
        }
  
        match = HASH_PLACEHOLDER_RX.exec(input)
        if (match) {
          fields.push({
            prefix: prefix,
            placeholder: match[1].toLowerCase(),
            width: parseInt(match[2] || 0, 10)
          })
          pos += match[0].length
          prefix = ''
          continue
        }
      }
      prefix += char
      pos++
    }
  
    return fields
  }
docs: Loop over the template string and return an array of objects in the form:
  {
  prefix: 'literal text',
  placeholder: 'replacement field name'
  [, width: maximum hash length for hash & chunkhash placeholders]
  }
  
  The values in the object conceptually represent a span of literal text followed by a single replacement field.
  If there is no literal text (which can happen if two replacement fields occur consecutively),
  then prefix will be an empty string.
  If there is no replacement field, then the value of placeholder will be null.
  If the value of placeholder is either 'hash' or 'chunkhash', then width will be a positive integer.
  Otherwise it will be left undefined.