Browse Source

Initial Commit

master
Gregory Rudolph 3 years ago
commit
122e0564cc
Signed by: rudi
GPG Key ID: EF64F3CBD1A1EBDD
  1. 229
      botCommands.go
  2. 361
      commands.go
  3. 13
      go.mod
  4. 393
      go.sum
  5. BIN
      helabot
  6. 35
      login.go
  7. 113
      main.go
  8. 204
      teslabot.log
  9. 9
      types.go

229
botCommands.go

@ -0,0 +1,229 @@ @@ -0,0 +1,229 @@
package main
import "samhofi.us/x/keybase/v2/types/chat1"
func setupCommands() {
authenticate := BotCommand{
Advert: chat1.AdvertiseCommandAPIParam{
Typ: "public",
Commands: []chat1.UserBotCommandInput{
{
Name: "authenticate",
Description: "Authenticate with Tesla, please use exploding message.",
Usage: "email@example.com Pa$$w0rd",
},
},
},
Triggers: []string{"authenticate", "auth"},
Exec: authenticate,
}
commands = append(commands, authenticate)
reset := BotCommand{
Advert: chat1.AdvertiseCommandAPIParam{
Typ: "public",
Commands: []chat1.UserBotCommandInput{
{
Name: "reset",
Description: "reset bot data",
Usage: "",
},
},
},
Triggers: []string{"reset"},
Exec: reset,
}
commands = append(commands, reset)
list := BotCommand{
Advert: chat1.AdvertiseCommandAPIParam{
Typ: "public",
Commands: []chat1.UserBotCommandInput{
{
Name: "list",
Description: "list account vehicles",
Usage: "",
},
},
},
Triggers: []string{"list", "cars"},
Exec: listVehicles,
}
commands = append(commands, list)
honk := BotCommand{
Advert: chat1.AdvertiseCommandAPIParam{
Typ: "public",
Commands: []chat1.UserBotCommandInput{
{
Name: "honk",
Description: "honk your vehicle horn",
Usage: "",
},
},
},
Triggers: []string{"honk", "beep"},
Exec: honk,
}
commands = append(commands, honk)
charge := BotCommand{
Advert: chat1.AdvertiseCommandAPIParam{
Typ: "public",
Commands: []chat1.UserBotCommandInput{
{
Name: "charge",
Description: "charge status",
Usage: "",
},
},
},
Triggers: []string{"charge", "battery"},
Exec: chargeStatus,
}
commands = append(commands, charge)
flash := BotCommand{
Advert: chat1.AdvertiseCommandAPIParam{
Typ: "public",
Commands: []chat1.UserBotCommandInput{
{
Name: "flash",
Description: "flash your lights",
Usage: "",
},
},
},
Triggers: []string{"flash", "blink"},
Exec: flashLights,
}
commands = append(commands, flash)
climate := BotCommand{
Advert: chat1.AdvertiseCommandAPIParam{
Typ: "public",
Commands: []chat1.UserBotCommandInput{
{
Name: "climate",
Description: "Set the climate temp, or turn 'on' or 'off'",
Usage: "64",
},
},
},
Triggers: []string{"climate", "ac"},
Exec: setClimate,
}
commands = append(commands, climate)
temp := BotCommand{
Advert: chat1.AdvertiseCommandAPIParam{
Typ: "public",
Commands: []chat1.UserBotCommandInput{
{
Name: "temp",
Description: "Get current temp state/settings",
Usage: "",
},
},
},
Triggers: []string{"temp", "currenttemp"},
Exec: currentTemp,
}
commands = append(commands, temp)
lock := BotCommand{
Advert: chat1.AdvertiseCommandAPIParam{
Typ: "public",
Commands: []chat1.UserBotCommandInput{
{
Name: "lock",
Description: "Lock your vehicle",
Usage: "",
},
},
},
Triggers: []string{"lock"},
Exec: lockVehicle,
}
commands = append(commands, lock)
unlock := BotCommand{
Advert: chat1.AdvertiseCommandAPIParam{
Typ: "public",
Commands: []chat1.UserBotCommandInput{
{
Name: "unlock",
Description: "Unlock your vehicle",
Usage: "",
},
},
},
Triggers: []string{"unlock"},
Exec: unlockVehicle,
}
commands = append(commands, unlock)
enableStart := BotCommand{
Advert: chat1.AdvertiseCommandAPIParam{
Typ: "public",
Commands: []chat1.UserBotCommandInput{
{
Name: "enablestart",
Description: "Enable starting your vehicle",
Usage: "accept Pa$$w0rd",
},
},
},
Triggers: []string{"enablestart", "enable"},
Exec: enableStart,
}
commands = append(commands, enableStart)
disableStart := BotCommand{
Advert: chat1.AdvertiseCommandAPIParam{
Typ: "public",
Commands: []chat1.UserBotCommandInput{
{
Name: "disablestart",
Description: "Remove your password from KVStore",
Usage: "",
},
},
},
Triggers: []string{"disable", "disablestart"},
Exec: disableStart,
}
commands = append(commands, disableStart)
start := BotCommand{
Advert: chat1.AdvertiseCommandAPIParam{
Typ: "public",
Commands: []chat1.UserBotCommandInput{
{
Name: "start",
Description: "Start your vehicle, if enabled",
Usage: "",
},
},
},
Triggers: []string{"start", "remotestart"},
Exec: startVehicle,
}
commands = append(commands, start)
trunk := BotCommand{
Advert: chat1.AdvertiseCommandAPIParam{
Typ: "public",
Commands: []chat1.UserBotCommandInput{
{
Name: "trunk",
Description: "Open your trunk, front or rear",
Usage: "front",
},
},
},
Triggers: []string{"trunk", "boot"},
Exec: openTrunk,
}
commands = append(commands, trunk)
}

361
commands.go

@ -0,0 +1,361 @@ @@ -0,0 +1,361 @@
package main
import (
"context"
"fmt"
"strconv"
"strings"
"github.com/google/uuid"
"samhofi.us/x/keybase/v2/types/chat1"
)
func reset(m chat1.MsgSummary) {
_, err := k.KVDelete(&m.Channel.Name, "teslabot", "authtok")
if err != nil {
tracker := uuid.NewString()
k.SendMessageByConvID(m.ConvID, "There was an error resetting your authentication. Contact @rudi9719 for more information with code %+v", tracker)
log.LogError("%+v: %+v", tracker, err)
return
}
_, err = k.KVDelete(&m.Channel.Name, "teslabot", "startPass")
if err != nil {
tracker := uuid.NewString()
k.SendMessageByConvID(m.ConvID, "There was an error resetting your authentication. Contact @rudi9719 for more information with code %+v", tracker)
log.LogError("%+v: %+v", tracker, err)
return
}
}
func authenticate(m chat1.MsgSummary) {
defer log.PanicSafe()
if isAuthenticated(m) {
k.SendMessageByConvID(m.ConvID, "You have already authenticated (please use !reset to reset.")
return
}
if !m.IsEphemeral {
k.SendMessageByConvID(m.ConvID, "Please remember to delete your message after we have authenticated!")
}
parts := strings.Split(m.Content.Text.Body, " ")
if len(parts) != 3 {
k.SendMessageByConvID(m.ConvID, "Invalid input for command authenticate. Requires username and password. This information is not stored in keybase, or logged.")
return
}
username := parts[1]
password := parts[2]
t, err := login(context.Background(), username, password)
if err != nil {
tracker := uuid.NewString()
k.SendMessageByConvID(m.ConvID, "There was an error logging in. Contact @rudi9719 for more information with code %+v", tracker)
log.LogError("%+v: %+v", tracker, err)
return
}
log.LogDebug("Token created for %+v", m.Sender.Username)
_, err = k.KVPut(&m.Channel.Name, "teslabot", "authtok", t)
if err != nil {
tracker := uuid.NewString()
k.SendMessageByConvID(m.ConvID, "There was an error storing your auth token. Contact @rudi9719 for more information with code %+v", tracker)
log.LogError("%+v: %+v", tracker, err)
return
}
k.ReactByConvID(m.ConvID, m.Id, ":car:")
k.DeleteByConvID(m.ConvID, m.Id)
k.SendMessageByConvID(m.ConvID, "You're all set!")
}
func listVehicles(m chat1.MsgSummary) {
c := getTeslaClient(m)
if c == nil {
return
}
v, err := c.Vehicles()
if err != nil {
tracker := uuid.NewString()
k.SendMessageByConvID(m.ConvID, "There was an error listing vehicles. Contact @rudi9719 for more information with code %+v", tracker)
log.LogError("%+v: %+v", tracker, err)
return
}
ret := "Detected vehicles for account: ```"
for _, v := range v {
ret += fmt.Sprintf("VIN: %s\n", v.Vin)
ret += fmt.Sprintf("Name: %s\n\n", v.DisplayName)
}
ret += "```"
k.SendMessageByConvID(m.ConvID, ret)
}
func honk(m chat1.MsgSummary) {
v := getVehicle(m)
if v == nil {
return
}
err := v.HonkHorn()
if err != nil {
tracker := uuid.NewString()
k.SendMessageByConvID(m.ConvID, "There was an error honking your horn. Contact @rudi9719 for more information with code %+v", tracker)
log.LogError("%+v: %+v", tracker, err)
return
}
k.SendMessageByConvID(m.ConvID, "I've honked your horn!")
}
func chargeStatus(m chat1.MsgSummary) {
v := getVehicle(m)
if v == nil {
return
}
state, err := v.ChargeState()
if err != nil {
tracker := uuid.NewString()
k.SendMessageByConvID(m.ConvID, "There was an error getting charge state. Contact @rudi9719 for more information with code %+v", tracker)
log.LogError("%+v: %+v", tracker, err)
return
}
ret := fmt.Sprintf("Status for %+v: ```", v.DisplayName)
ret += fmt.Sprintf("\nCurrent Charge: %+v (%+vmi)", state.BatteryLevel, state.BatteryRange)
ret += fmt.Sprintf("\nCharging State: %+v", state.ChargingState)
ret += fmt.Sprintf("\nTime to full: %+vmin", state.MinutesToFullCharge)
ret += fmt.Sprintf("\nConnected Cable: %+v", state.ConnChargeCable)
if state.FastChargerPresent {
ret += fmt.Sprintf("\nFast Charger: %+v %+v", state.FastChargerBrand, state.FastChargerType)
}
ret += "```\n"
if state.BatteryHeaterOn {
ret += "The battery heater is on. "
}
if state.ChargePortDoorOpen {
ret += "The charge port is open. "
}
k.SendMessageByConvID(m.ConvID, ret)
}
func flashLights(m chat1.MsgSummary) {
v := getVehicle(m)
if v == nil {
return
}
err := v.FlashLights()
if err != nil {
tracker := uuid.NewString()
k.SendMessageByConvID(m.ConvID, "There was an error flashing your lights. Contact @rudi9719 for more information with code %+v", tracker)
log.LogError("%+v: %+v", tracker, err)
return
}
k.SendMessageByConvID(m.ConvID, "I've flashed your lights!")
}
func currentTemp(m chat1.MsgSummary) {
v := getVehicle(m)
if v == nil {
return
}
guiSettings, err := v.GuiSettings()
if err != nil {
tracker := uuid.NewString()
k.SendMessageByConvID(m.ConvID, "There was an error getting your preferences. Contact @rudi9719 for more information with code %+v", tracker)
log.LogError("%+v: %+v", tracker, err)
return
}
climateState, err := v.ClimateState()
if err != nil {
tracker := uuid.NewString()
k.SendMessageByConvID(m.ConvID, "There was an error getting your Climate State. Contact @rudi9719 for more information with code %+v", tracker)
log.LogError("%+v: %+v", tracker, err)
return
}
tempSetting := climateState.DriverTempSetting
insideTemp := climateState.InsideTemp
if guiSettings.GuiTemperatureUnits == "F" {
tempSetting = (climateState.DriverTempSetting * 1.8) + 32
insideTemp = (climateState.InsideTemp * 1.8) + 32
}
if climateState.IsClimateOn {
k.SendMessageByConvID(m.ConvID, "Your climate on and set to %+v, current temp is: %+v inside %+v",
tempSetting, insideTemp, v.DisplayName)
} else {
k.SendMessageByConvID(m.ConvID, "Your climate off but set to %+v, current temp is %+v inside %+v",
tempSetting, insideTemp, v.DisplayName)
}
}
func setClimate(m chat1.MsgSummary) {
v := getVehicle(m)
if v == nil {
return
}
guiSettings, err := v.GuiSettings()
if err != nil {
tracker := uuid.NewString()
k.SendMessageByConvID(m.ConvID, "There was an error getting your preferences. Contact @rudi9719 for more information with code %+v", tracker)
log.LogError("%+v: %+v", tracker, err)
return
}
parts := strings.Split(m.Content.Text.Body, " ")
for _, val := range parts {
if val == "on" {
err := v.StartAirConditioning()
if err != nil {
tracker := uuid.NewString()
k.SendMessageByConvID(m.ConvID, "There was an error starting your Climate. Contact @rudi9719 for more information with code %+v", tracker)
log.LogError("%+v: %+v", tracker, err)
return
}
}
if val == "off" {
err := v.StopAirConditioning()
if err != nil {
tracker := uuid.NewString()
k.SendMessageByConvID(m.ConvID, "There was an error turning off your Climate. Contact @rudi9719 for more information with code %+v", tracker)
log.LogError("%+v: %+v", tracker, err)
return
}
}
if temp, err := strconv.Atoi(val); err == nil {
if guiSettings.GuiTemperatureUnits == "F" {
temp = (temp - 32) * 5 / 9
}
err = v.SetTemperature(float64(temp), float64(temp))
if err != nil {
tracker := uuid.NewString()
k.SendMessageByConvID(m.ConvID, "There was an error setting your Climate. Contact @rudi9719 for more information with code %+v", tracker)
log.LogError("%+v: %+v", tracker, err)
return
}
err = v.StartAirConditioning()
if err != nil {
tracker := uuid.NewString()
k.SendMessageByConvID(m.ConvID, "There was an error starting your Climate. Contact @rudi9719 for more information with code %+v", tracker)
log.LogError("%+v: %+v", tracker, err)
return
}
}
}
climateState, err := v.ClimateState()
if err != nil {
tracker := uuid.NewString()
k.SendMessageByConvID(m.ConvID, "There was an error getting your Climate State. Contact @rudi9719 for more information with code %+v", tracker)
log.LogError("%+v: %+v", tracker, err)
return
}
tempSetting := climateState.DriverTempSetting
insideTemp := climateState.InsideTemp
if guiSettings.GuiTemperatureUnits == "F" {
tempSetting = (climateState.DriverTempSetting * 1.8) + 32
insideTemp = (climateState.InsideTemp * 1.8) + 32
}
if climateState.IsClimateOn {
k.SendMessageByConvID(m.ConvID, "Your climate on and set to %+v, current temp is: %+v", tempSetting, insideTemp)
} else {
k.SendMessageByConvID(m.ConvID, "Your climate off but set to %+v", tempSetting)
}
}
func lockVehicle(m chat1.MsgSummary) {
v := getVehicle(m)
if v == nil {
return
}
err := v.LockDoors()
if err != nil {
tracker := uuid.NewString()
k.SendMessageByConvID(m.ConvID, "There was an error locking your doors. Contact @rudi9719 for more information with code %+v", tracker)
log.LogError("%+v: %+v", tracker, err)
return
}
}
func unlockVehicle(m chat1.MsgSummary) {
v := getVehicle(m)
if v == nil {
return
}
err := v.UnlockDoors()
if err != nil {
tracker := uuid.NewString()
k.SendMessageByConvID(m.ConvID, "There was an error unlocking your doors. Contact @rudi9719 for more information with code %+v", tracker)
log.LogError("%+v: %+v", tracker, err)
return
}
}
func enableStart(m chat1.MsgSummary) {
parts := strings.Split(m.Content.Text.Body, " ")
if len(parts) != 3 {
k.SendMessageByConvID(m.ConvID, "You must 'accept' this command and supply your password. This command is not as safe, as it stores your password in KVStore.")
return
}
if !strings.Contains(parts[1], "accept") {
k.SendMessageByConvID(m.ConvID, "You must 'accept' this command and supply your password. This command is not as safe, as it stores your password in KVStore.")
return
}
_, err := k.KVPut(&m.Channel.Name, "teslabot", "startPass", parts[2])
if err != nil {
tracker := uuid.NewString()
k.SendMessageByConvID(m.ConvID, "There was an error storing your password. Contact @rudi9719 for more information with code %+v", tracker)
log.LogError("%+v: %+v", tracker, err)
return
}
}
func disableStart(m chat1.MsgSummary) {
_, err := k.KVDelete(&m.Channel.Name, "teslabot", "startPass")
if err != nil {
tracker := uuid.NewString()
k.SendMessageByConvID(m.ConvID, "There was an error deleting your password. Contact @rudi9719 for more information with code %+v", tracker)
log.LogError("%+v: %+v", tracker, err)
return
}
}
func startVehicle(m chat1.MsgSummary) {
v := getVehicle(m)
if v == nil {
return
}
test, _ := k.KVGet(&m.Channel.Name, "teslabot", "startPass")
if test.EntryValue == "" {
k.SendMessageByConvID(m.ConvID, "You must first !enablestart to use this command.")
return
}
err := v.Start(test.EntryValue)
if err != nil {
tracker := uuid.NewString()
k.SendMessageByConvID(m.ConvID, "There was an error starting your vehicle. Contact @rudi9719 for more information with code %+v", tracker)
log.LogError("%+v: %+v", tracker, err)
return
}
k.SendMessageByConvID(m.ConvID, "Your vehicle has been started!")
}
func openTrunk(m chat1.MsgSummary) {
v := getVehicle(m)
parts := strings.Split(m.Content.Text.Body, " ")
if len(parts) != 2 {
k.SendMessageByConvID(m.ConvID, "You must supply front or rear.")
return
}
trunk := parts[1]
switch trunk {
case "rear":
case "front":
err := v.OpenTrunk(trunk)
if err != nil {
tracker := uuid.NewString()
k.SendMessageByConvID(m.ConvID, "There was an error opening your trunk. Contact @rudi9719 for more information with code %+v", tracker)
log.LogError("%+v: %+v", tracker, err)
return
}
default:
k.SendMessageByConvID(m.ConvID, "You must supply front or rear.")
return
}
}

13
go.mod

@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
module git.nightmare.haus/rudi/helabot
go 1.16
require (
github.com/bogosj/tesla v1.0.0
github.com/google/uuid v1.2.0 // indirect
github.com/manifoldco/promptui v0.8.0
github.com/rudi9719/loggy v0.0.0-20201031035735-9438c484de9a // indirect
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93 // indirect
samhofi.us/x/keybase v0.0.0-20200129212102-e05e93be9f3f // indirect
samhofi.us/x/keybase/v2 v2.1.1
)

393
go.sum

@ -0,0 +1,393 @@ @@ -0,0 +1,393 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/PuerkitoBio/goquery v1.6.1 h1:FgjbQZKl5HTmcn4sKBgvx8vv63nhyhIpv7lJpFGCWpk=
github.com/PuerkitoBio/goquery v1.6.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
github.com/andybalholm/cascadia v1.1.0 h1:BuuO6sSfQNFRu1LppgbD25Hr2vLYW25JvxHs5zzsLTo=
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
github.com/bogosj/tesla v1.0.0 h1:qV+0AMV6DJC/b/w8SXPNvUDHqGqugycl+Sv0EiQoypA=
github.com/bogosj/tesla v1.0.0/go.mod h1:xmG/yUw+GhxVB2m5GQLV4Vo/byvOf0wwhYGQ6IWPl+k=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs=
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a h1:FaWFmfWdAUKbSCtOU2QjDaorUexogfaMgbipgYATUMU=
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a h1:weJVJJRzAJBFRlAiJQROKQs8oC9vOxvm4rZmBBk0ONw=
github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
github.com/manifoldco/promptui v0.8.0 h1:R95mMF+McvXZQ7j1g8ucVZE1gLP3Sv6j9vlF9kyRqQo=
github.com/manifoldco/promptui v0.8.0/go.mod h1:n4zTdgP0vr0S3w7/O/g98U+e0gwLScEXGwov2nIKuGQ=
github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rudi9719/loggy v0.0.0-20201031035735-9438c484de9a h1:4rkaWoLCWOmra5Mw/dLAWjtDLT/+i5uTX1qhlMVL8WA=
github.com/rudi9719/loggy v0.0.0-20201031035735-9438c484de9a/go.mod h1:s1ANCN8bF6HwwTpJLR458MFVGua9oqKKDbph/2jptL4=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93 h1:alLDrZkL34Y2bnGHfvC1CYBRBXCXgx8AC2vY4MRtYX4=
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642 h1:B6caxRw+hozq68X2MY7jEpZh/cr4/aHLv9xU8Kkadrw=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
samhofi.us/x/keybase v0.0.0-20200129212102-e05e93be9f3f h1:MHSEiuiRFrFi7BTw46lC22PMk3Fit8IvVRM4xANTt20=
samhofi.us/x/keybase v0.0.0-20200129212102-e05e93be9f3f/go.mod h1:fcva80IUFyWcHtV4bBSzgKg07K6Rvuvi3GtGCLNGkyE=
samhofi.us/x/keybase/v2 v2.1.1 h1:XPWrmdbJCrNcsW3sRuR6WuALYOZt7O+av0My6YoehqE=
samhofi.us/x/keybase/v2 v2.1.1/go.mod h1:lJivwhzMSV+WUg+XUbatszStjjFVcuLGl+xcQpqQ5GQ=

BIN
helabot

Binary file not shown.

35
login.go

@ -0,0 +1,35 @@ @@ -0,0 +1,35 @@
package main
import (
"context"
"encoding/json"
"github.com/bogosj/tesla"
)
func noDevice(ctx context.Context, devices []tesla.Device) (d tesla.Device, passcode string, err error) {
return tesla.Device{}, "", nil
}
func login(ctx context.Context, username string, password string) (string, error) {
client, err := tesla.NewClient(
ctx,
tesla.WithMFAHandler(noDevice),
tesla.WithCredentials(username, password),
)
if err != nil {
log.LogErrorType(err)
return "", err
}
t, err := client.Token()
if err != nil {
log.LogErrorType(err)
return "", err
}
ret, err := json.Marshal(t)
if err != nil {
log.LogErrorType(err)
return "", err
}
return string(ret), nil
}

113
main.go

@ -0,0 +1,113 @@ @@ -0,0 +1,113 @@
package main
import (
"context"
"encoding/json"
"strings"
"github.com/bogosj/tesla"
"github.com/google/uuid"
"github.com/rudi9719/loggy"
"golang.org/x/oauth2"
"samhofi.us/x/keybase/v2"
"samhofi.us/x/keybase/v2/types/chat1"
)
var (
k = keybase.NewKeybase()
log = loggy.NewLogger(loggy.LogOpts{
OutFile: "teslabot.log",
KBTeam: "nightmarehaus.logs",
KBChann: "teslabot",
Level: 5,
ProgName: "TeslaBot",
UseStdout: true,
})
commands []BotCommand
)
func main() {
chat := handleChat
handlers := keybase.Handlers{
ChatHandler: &chat,
}
setupCommands()
cmds := keybase.AdvertiseCommandsOptions{
Alias: "Tesla Bot",
}
for _, v := range commands {
cmds.Advertisements = append(cmds.Advertisements, v.Advert)
}
k.AdvertiseCommands(cmds)
k.Run(handlers, &keybase.RunOptions{})
}
func handleChat(m chat1.MsgSummary) {
defer log.PanicSafe()
parts := strings.Split(m.Content.Text.Body, " ")
command := strings.Replace(parts[0], "!", "", -1)
for _, v := range commands {
for _, test := range v.Triggers {
if command == test {
v.Exec(m)
return
}
}
}
}
func isAuthenticated(m chat1.MsgSummary) bool {
test, _ := k.KVGet(&m.Channel.Name, "teslabot", "authtok")
return test.EntryValue != ""
}
func getTeslaClient(m chat1.MsgSummary) *tesla.Client {
var t *oauth2.Token
if !isAuthenticated(m) {
k.SendMessageByConvID(m.ConvID, "You are not authenticated.")
return nil
}
test, _ := k.KVGet(&m.Channel.Name, "teslabot", "authtok")
err := json.Unmarshal([]byte(test.EntryValue), &t)
if err != nil {
tracker := uuid.NewString()
k.SendMessageByConvID(m.ConvID, "There was an retrieving token from KVStore. Contact @rudi9719 for more information with code %+v", tracker)
log.LogError("%+v: %+v", tracker, err)
return nil
}
c, err := tesla.NewClient(context.Background(), tesla.WithToken(t))
if err != nil {
tracker := uuid.NewString()
k.SendMessageByConvID(m.ConvID, "There was an error logging in. Contact @rudi9719 for more information with code %+v", tracker)
log.LogError("%+v: %+v", tracker, err)
return nil
}
return c
}
func getVehicle(m chat1.MsgSummary) *tesla.Vehicle {
c := getTeslaClient(m)
if c == nil {
return nil
}
parts := strings.Split(m.Content.Text.Body, " ")
vehicles, err := c.Vehicles()
if err != nil {
tracker := uuid.NewString()
k.SendMessageByConvID(m.ConvID, "There was an error listing vehicles. Contact @rudi9719 for more information with code %+v", tracker)
log.LogError("%+v: %+v", tracker, err)
return nil
}
v := vehicles[0]
if len(parts) == 2 {
for _, test := range vehicles {
if parts[1] == test.Vin {
v = test
}
if parts[1] == test.DisplayName {
v = test
}
}
}
return v
}

204
teslabot.log

@ -0,0 +1,204 @@ @@ -0,0 +1,204 @@
[22May21 08:04:04.903] Error: 5b28f252-5ee4-4b02-a5a9-606dbab7f3df: unexpected status code 401
[22May21 08:04:05.2948] Error: 15e567c9-42fc-4e83-82ec-11af225d3b77: unexpected status code 401
[22May21 08:04:06.3511] Error: 0429dff6-80da-454d-a302-fd6459c5ca78: unexpected status code 401
[22May21 08:04:06.4625] Error: e1373512-44b8-4b5a-a857-5345cf2dfe78: unexpected status code 401
[22May21 08:04:06.7508] Error: a7ba3013-fba5-4ec5-9786-5fb69679873f: unexpected status code 401
[22May21 08:04:06.8095] Error: 523db61b-4a19-43e9-bee7-03c278c035bd: `entryValue` field required
[22May21 08:04:07.152] Error: ec937316-5486-4dd5-afce-00f1a93047a9: unexpected status code 401
[22May21 08:04:07.1635] Error: 68f09c45-43ed-48b3-ae79-38eceaba5d04: `entryValue` field required
[22May21 08:04:07.8906] Error: 66f653e4-b082-45b7-afaf-a2c1a1be73d0: `entryValue` field required
[22May21 08:04:07.9731] Error: 7b3a9838-2d3e-457a-8df2-25ccca0e961d: unexpected status code 401
[22May21 08:04:08.1978] Error: 6a724106-a0a8-401a-b568-b2e13e222741: `entryValue` field required
[22May21 08:04:08.2162] Error: d3361831-6b20-4482-839b-deaceab26d84: `entryValue` field required
[22May21 08:04:08.3898] Error: 9be2e672-f46d-4c83-b978-217f4346d23d: unexpected status code 401
[22May21 08:04:08.4751] Error: 45c578a2-e411-4fa0-87c4-301714b303b2: `entryValue` field required
[22May21 08:04:08.7995] Error: 5afa3d71-114e-4a3c-827e-586a2681a965: unexpected status code 401
[22May21 08:04:08.9817] Error: 2a1de83b-b985-46fe-8e36-d16358791541: `entryValue` field required
[22May21 08:04:09.3179] Error: ff452ad9-2569-4fa6-904f-21eaac882938: unexpected status code 401
[22May21 08:04:09.3201] Error: 738cb5eb-c92c-4154-b67b-1bd21693d8ea: unexpected status code 401
[22May21 08:04:09.3227] Error: 0f752c32-302b-4fbc-979d-217453e71a9a: `entryValue` field required
[22May21 08:04:09.4634] Error: a640255a-4791-493f-91c6-ae1d6d3cf03f: unexpected status code 401
[22May21 08:04:09.5994] Error: 7bfca02c-dc15-4396-a428-b42c9004f72e: unexpected status code 401
[22May21 08:04:10.0394] Error: 830871d5-dedb-4ea5-b0dc-2b045fc1b7e5: unexpected status code 401
[22May21 08:04:10.1867] Error: 4e530735-627d-42dc-8a3e-6976aa4b2d3b: `entryValue` field required
[22May21 08:04:10.4266] Error: 4f45325c-f478-4622-bd7c-7f026defc768: unexpected status code 401
[22May21 08:04:10.4863] Error: f10e7c69-7ea5-4945-8f7c-a726f7a030ac: unexpected status code 401
[22May21 08:04:10.6332] Error: c947ff6a-04b3-4538-89aa-e99ab6bc182e: `entryValue` field required
[22May21 08:04:10.714] Error: d83a4f5f-d5f3-4664-aa05-bcf6b14744c6: `entryValue` field required
[22May21 08:04:10.8452] Error: 7c31495c-c7be-4108-9c20-60889cf5e6ba: unexpected status code 401
[22May21 08:04:11.047] Error: eb085d7e-fa68-40f2-86cc-fb0e3e6a4ec0: unexpected status code 401
[22May21 08:04:11.0508] Error: 142f650e-1799-4339-982a-fca4b3736eab: unexpected status code 401
[22May21 08:04:11.1732] Error: c3e495ac-514f-402e-8265-446947fc07f3: `entryValue` field required
[22May21 08:04:11.2856] Error: 6995514b-5f1f-49db-83f9-acbf3d9aa134: `entryValue` field required
[22May21 08:04:11.3434] Error: 301d97f2-2e5d-43e2-9207-201c0de3793f: `entryValue` field required
[22May21 08:04:11.3438] Error: 00a87d59-1e4c-4dda-af8e-4527e45dd491: unexpected status code 401
[22May21 08:04:11.4097] Error: 957a3f3d-ef7b-4f5d-a7cb-1a90f09fcf7b: unexpected status code 401
[22May21 08:04:11.6699] Error: ea27d189-55ec-4a30-a11b-47f707c5ef49: unexpected status code 401
[22May21 08:04:11.9539] Error: 4c051699-a189-40c5-93f9-8967bac24128: `entryValue` field required
[22May21 08:04:12.1511] Error: 3e3fa20d-177e-476b-9e3e-18fad3f6b654: `entryValue` field required
[22May21 08:04:12.1683] Error: 0450929c-c801-40b6-b6b6-c3fccd8e5141: `entryValue` field required
[22May21 08:04:12.652] Error: 36e5bca7-9e99-4a60-b22c-b45db92c7a69: unexpected status code 401
[22May21 08:04:13.0513] Error: 4059034f-6a92-4f90-91c6-18ae9577ab1b: unexpected status code 401
[22May21 08:04:13.0512] Error: 842c1a2a-b88e-42f5-b82e-6dd621854c60: `entryValue` field required
[22May21 08:04:13.1868] Error: e0f213d9-33b1-46cb-b71c-385c8493681a: `entryValue` field required
[22May21 08:04:13.3091] Error: 8268e1b4-13e8-4757-aa6b-e631fb0dcce2: `entryValue` field required
[22May21 08:04:13.5326] Error: f36f8584-b6a0-483d-b121-577f73214768: `entryValue` field required
[22May21 08:04:13.8462] Error: ed4f2d3e-9136-4fe7-8b62-9d3028b574ab: `entryValue` field required
[22May21 08:04:14.0541] Error: 8d42cf43-f3f2-45ad-9b6d-4361ff0889e5: unexpected status code 401
[22May21 08:04:14.1291] Error: 806f8a2b-515b-48f1-b2aa-ad82af0edd8d: unexpected status code 401
[22May21 08:04:14.1997] Error: 48567674-9004-4721-a111-e086198ebcd7: `entryValue` field required
[22May21 08:04:14.2287] Error: b8339d11-4ce5-4ff1-8ba1-8a851c6c9a6c: unexpected status code 401
[22May21 08:04:14.3373] Error: fdd7046a-913e-4fa7-bca8-e6b4746014ef: unexpected status code 401
[22May21 08:04:14.7321] Error: ead1705b-5ed7-4462-a26b-b70a2610a113: `entryValue` field required
[22May21 08:04:15.2247] Error: 59d42772-1de2-4f8a-9d0a-a4e5de4b3679: unexpected status code 401
[22May21 08:04:15.4134] Error: 9a658435-d7a6-420a-b70a-bb9d929ff682: unexpected status code 401
[22May21 08:04:15.6586] Error: 3f121735-8d5c-4df4-bb83-2087ea4676cc: unexpected status code 401
[22May21 08:04:15.7697] Error: 4caf7648-3bfb-4f95-8513-48a48060d131: `entryValue` field required
[22May21 08:04:15.7767] Error: 93f006a8-e262-4346-a46d-4a7e11f9231f: `entryValue` field required
[22May21 08:04:15.8586] Error: 4947ac81-20df-4769-8a3f-81a85b87d5b3: `entryValue` field required
[22May21 08:04:16.0417] Error: aecb08c7-f08c-486c-8002-50303e18c168: unexpected status code 401
[22May21 08:04:16.0513] Error: 34838ff5-4f2a-45c2-8058-05bf4137ae59: unexpected status code 401
[22May21 08:04:16.1437] Error: f07ce54d-1703-4333-ada9-149c60d35cd9: `entryValue` field required
[22May21 08:04:16.4105] Error: 7061885e-bfdd-4f5b-9f6e-91d006e02cdc: unexpected status code 401
[22May21 08:04:16.4756] Error: f53e003e-164d-4aa1-b9d9-54105d707222: unexpected status code 401
[22May21 08:04:16.7838] Error: 92706ff6-cfa4-42e2-b601-ffac17b0e345: `entryValue` field required
[22May21 08:04:16.8494] Error: 63141702-102a-49ae-930e-3a79f6708fe8: `entryValue` field required
[22May21 08:04:16.9124] Error: 1b35f37c-2481-41f2-8baf-df29323e84ca: `entryValue` field required
[22May21 08:04:17.2024] Error: e548ecb9-9679-4a56-b3fa-b4d581bac087: unexpected status code 401
[22May21 08:04:17.2276] Error: b57d1e38-bb79-41d5-b0c7-3c6db6568139: `entryValue` field required
[22May21 08:04:17.2296] Error: 00973952-dd84-4b21-92b9-6051f3d7754e: `entryValue` field required
[22May21 08:04:17.733] Error: e0fea769-89cc-47cb-b5ac-43015afc82fb: `entryValue` field required
[22May21 08:04:18.1309] Error: bb1b9b38-e176-4806-a10a-7de52d78aa33: unexpected status code 401
[22May21 08:04:18.1397] Error: 0ca28a8d-9824-4ca1-9b97-be558945777f: `entryValue` field required
[22May21 08:04:18.2521] Error: 21300b64-5ba3-4758-b47a-d2d0be4000ba: unexpected status code 401
[22May21 08:04:18.2996] Error: bd5ca158-b042-4e06-9168-b714009d37b1: unexpected status code 401
[22May21 08:04:18.5609] Error: 03ef7fd0-4b1c-49f3-8584-04b842e89627: unexpected status code 401
[22May21 08:04:18.8334] Error: a81ca7e9-4cc8-4d57-8f3c-739483584729: unexpected status code 401
[22May21 08:04:18.9205] Error: 6ddeae3d-ca5b-49f2-bcfd-d7a3dc782c4e: `entryValue` field required
[22May21 08:04:19.1938] Error: c2800e7e-132b-4a60-8ce0-575417fd4338: unexpected status code 401
[22May21 08:04:19.2947] Error: 796e5b27-5a55-4673-862e-ce61ba3a8494: `entryValue` field required
[22May21 08:04:19.4857] Error: e77e49e1-d81d-45d4-9052-bca1f17433a7: unexpected status code 401
[22May21 08:04:19.6373] Error: a35514d2-c4a6-46c5-82c1-01201e386cc4: `entryValue` field required
[22May21 08:04:19.6858] Error: cc6545ab-0240-41f5-96f6-0a63b06b4050: `entryValue` field required
[22May21 08:04:19.8855] Error: 2bb5c45c-3a42-4c6a-a4e6-834782bbb92b: `entryValue` field required
[22May21 08:04:19.8875] Error: f4d134e5-e592-4f5b-8e3e-cb7823f99623: `entryValue` field required
[22May21 08:04:19.8878] Error: b81e4c02-96e1-44b1-be37-c07381fb4432: unexpected status code 401
[22May21 08:04:20.3426] Error: dbd34ea2-04cf-4b6b-86bc-165366cf0ed2: unexpected status code 401
[22May21 08:04:20.4187] Error: fc0cf746-b870-4ef8-b528-99b0d89b82cf: `entryValue` field required
[22May21 08:04:20.5129] Error: 89337a6a-a463-46c1-9b83-2425146b1bc1: `entryValue` field required
[22May21 08:04:20.5554] Error: 176bc5ed-db07-4faf-a28e-f847e2e61ede: unexpected status code 401
[22May21 08:04:20.6278] Error: 644252a1-7f71-47a2-a5f1-ac88d8243ed8: unexpected status code 401
[22May21 08:04:20.8296] Error: 52bdcfb5-c78c-41e3-8750-7c2527690087: unexpected status code 401
[22May21 08:04:20.9083] Error: 1c2ea14f-a53e-4536-a15e-a707f866a286: unexpected status code 401
[22May21 08:04:20.9927] Error: d332ce99-bac2-45dc-8062-40300930934e: unexpected status code 401
[22May21 08:04:21.3501] Error: bce5132f-9054-4a8f-ae20-5dcfff26e81b: unexpected status code 401
[22May21 08:04:21.8172] Error: ada267fe-8ada-4209-ba2a-6d700ba12f20: `entryValue` field required
[22May21 08:04:21.8214] Error: 1b1feab6-c1c6-4177-9807-78a46ad2e507: `entryValue` field required
[22May21 08:04:21.85] Error: 28aacd7d-1d4f-43b2-a005-53013449cbeb: `entryValue` field required
[22May21 08:04:21.8953] Error: e39e5fa6-e880-4d03-8eb9-7edf794c956c: unexpected status code 401
[22May21 08:04:22.2287] Error: da6b1842-5a0e-4195-b10e-769b61cd447f: unexpected status code 401
[22May21 08:04:22.3213] Error: b7e61cc1-f341-4e98-9baa-d9c394c4f6bc: `entryValue` field required
[22May21 08:04:22.3481] Error: f0c939f7-1002-48ba-8ad0-7785199fe681: `entryValue` field required
[22May21 08:04:22.3812] Error: 5fca1990-39ad-4b2b-b85f-fe4c0b86ea4d: unexpected status code 401
[22May21 08:04:22.5924] Error: f58143e8-0915-4d5b-a32c-4a3cc84eae93: `entryValue` field required
[22May21 08:04:22.6126] Error: 9a4bd03c-0d1f-482b-b4d1-1bc2a5f7c053: `entryValue` field required
[22May21 08:04:22.7092] Error: f0a649ff-d180-4634-8c93-734a95e6fd78: `entryValue` field required
[22May21 08:04:22.9431] Error: f77ef3b6-aa23-43fa-84de-3fb91bb3a647: `entryValue` field required
[22May21 08:04:23.0308] Error: c81de30e-228b-45f5-a15b-4672142becfe: unexpected status code 401
[22May21 08:04:23.2222] Error: 3016b92b-c9a7-44ff-abc0-04e88ce4fdb2: `entryValue` field required
[22May21 08:04:23.291] Error: 403f7030-d98a-4092-990c-05c172aab406: `entryValue` field required
[22May21 08:04:23.4231] Error: 1fa9659f-028d-4db2-9b92-c857b71d9080: unexpected status code 401
[22May21 08:04:23.6583] Error: d0ecba27-f7f4-49e5-825a-77f5498c244d: unexpected status code 401
[22May21 08:04:23.7263] Error: 10e62aa1-6ac9-4826-a09d-3e1208dbe136: `entryValue` field required
[22May21 08:04:23.9075] Error: 420bf2eb-2a0d-4f09-ae8b-189686e663d7: unexpected status code 401
[22May21 08:04:23.9906] Error: 92de72a9-14de-44ae-9148-7fa0a5933293: unexpected status code 401
[22May21 08:04:24.6139] Error: a7fcff19-b0fc-4168-ba12-b089cd0077b0: `entryValue` field required
[22May21 08:04:24.6199] Error: 038a8217-5217-4fb0-8b2c-e1e1a913ba0b: `entryValue` field required
[22May21 08:04:24.7643] Error: 14fce671-cb22-4d6a-8b78-e1ffb740a8d5: unexpected status code 401
[22May21 08:04:24.9627] Error: 1c565eb9-8207-4145-befa-6bd88d28cfc0: unexpected status code 401
[22May21 08:04:25.2114] Error: 92ce95fa-7c6d-466f-9cd1-25e445ff999a: unexpected status code 401
[22May21 08:04:25.2432] Error: c310fa79-d6d6-4ea4-9c67-8e3aa7def9e3: `entryValue` field required
[22May21 08:04:25.2533] Error: cb754152-c6be-4b7a-bc6f-db3a6b036d36: unexpected status code 401
[22May21 08:04:25.2854] Error: 2df5d746-3454-4966-b4c0-64d0e11ed0a4: unexpected status code 401
[22May21 08:04:25.3891] Error: a102347d-114e-4697-aa73-be23b3920bf7: unexpected status code 401
[22May21 08:04:25.8104] Error: 220dddd1-7bae-4b25-ac99-2096d0f0c5f0: unexpected status code 401
[22May21 08:04:25.9043] Error: 89774326-b076-4c17-9033-7319a1023dad: `entryValue` field required
[22May21 08:04:26.0876] Error: ff991a2f-8d2c-4ef6-a0b5-9b9a387f7337: unexpected status code 401
[22May21 08:04:26.2764] Error: 3d42065e-f2c8-4337-a8d4-936407c94d84: `entryValue` field required
[22May21 08:04:26.28] Error: 455b222c-8c9c-48f0-80ab-0fbc437a88ed: `entryValue` field required
[22May21 08:04:26.3721] Error: 5b9a6e4b-0aa1-46df-b88a-6da624b57175: `entryValue` field required
[22May21 08:04:26.4735] Error: cb3d51e2-dbba-44ae-9228-4b2052631851: `entryValue` field required
[22May21 08:04:26.5527] Error: c20d1ecf-5a9a-4887-a204-1dbf14a8c87e: `entryValue` field required
[22May21 08:04:26.6255] Error: 7cc3c66b-af6d-45af-8878-04d44693d0ff: `entryValue` field required
[22May21 08:04:26.8414] Error: f66ebe4a-3ed7-4657-aeed-f3e3944d61b8: `entryValue` field required
[22May21 08:04:26.863] Error: 0f18df13-ea6c-46d0-93a9-e335535209e2: `entryValue` field required
[22May21 08:04:27.0293] Error: cc9331ee-07c4-4ad2-b3ba-2efc160bd6bd: unexpected status code 401
[22May21 08:04:27.2135] Error: 1d6ba5da-9c87-40ef-8808-652342159877: unexpected status code 401
[22May21 08:04:27.4219] Error: e1824432-74cd-418c-9afe-f63056ef3170: unexpected status code 401
[22May21 08:04:27.4946] Error: 49e1b2d0-6c3f-4bf0-8436-b1f0e425b3c4: unexpected status code 401
[22May21 08:04:27.7729] Error: 3a0c1673-96cc-4471-b55a-10929cec4e6f: `entryValue` field required
[22May21 08:04:27.803] Error: cd941821-5433-47e5-a400-32d4b33c944d: unexpected status code 401
[22May21 08:04:27.8636] Error: 640423e8-7e92-46e6-819c-f02bd588c348: unexpected status code 401
[22May21 08:04:28.0967] Error: dc626911-24ad-4ee2-858c-df1096dca645: unexpected status code 401
[22May21 08:04:28.1913] Error: efdd610b-806a-4f4c-9984-2950f89e046e: unexpected status code 401
[22May21 08:04:28.1938] Error: c736f1f6-1c93-4733-abab-7963d10f7e37: unexpected status code 401
[22May21 08:04:28.1952] Error: 68879ed5-7e7b-409f-8722-881371f4732d: `entryValue` field required
[22May21 08:04:28.2928] Error: 4ddd1911-5ffb-4762-b190-38bb8c75cd22: `entryValue` field required
[22May21 08:04:28.6377] Error: 7b5b19c2-cb99-4e2f-a36e-520ede1bd7bc: `entryValue` field required
[22May21 08:04:28.6593] Error: c816fbaf-431a-4501-a997-c110927fe43e: `entryValue` field required
[22May21 08:04:28.779] Error: 8e74db37-b3e7-406d-8216-1c42fd31ed23: `entryValue` field required
[22May21 08:04:28.9678] Error: ede51021-625e-4a99-9685-4a606139dc72: `entryValue` field required
[22May21 08:04:28.9921] Error: 139af1af-3102-48bc-a68f-7d64992c498b: `entryValue` field required
[22May21 08:04:29.1062] Error: f0198c96-2224-431c-8905-229f858c6efd: unexpected status code 401
[22May21 08:04:29.2476] Error: eb72cd8b-737c-4b60-ab30-4a760fcda166: unexpected status code 401
[22May21 08:14:54.5887] Critical: Panic detected: runtime error: invalid memory address or nil pointer dereference
[22May21 08:14:54.5889] Critical: Optional panic data: %!v(MISSING)
[22May21 08:14:55.4534] Critical: Optional panic data: %!v(MISSING)
[22May21 08:14:55.4535] Critical: Panic detected: runtime error: invalid memory address or nil pointer dereference
[22May21 08:14:59.0527] Critical: Panic detected: runtime error: index out of range [2] with length 2
[22May21 08:14:59.0527] Critical: Optional panic data: %!v(MISSING)
[22May21 08:14:59.2922] Critical: Panic detected: runtime error: index out of range [2] with length 2
[22May21 08:14:59.2922] Critical: Optional panic data: %!v(MISSING)
[22May21 08:14:59.7308] Critical: Panic detected: runtime error: index out of range [2] with length 2
[22May21 08:14:59.7308] Critical: Optional panic data: %!v(MISSING)
[22May21 08:15:00.1232] Critical: Optional panic data: %!v(MISSING)
[22May21 08:15:00.1232] Critical: Panic detected: runtime error: index out of range [2] with length 2
[22May21 08:15:01.1209] Error: 8e9baa9e-a4c6-4585-b915-acc0231e5af8: unexpected status code 401
[22May21 08:15:01.1721] Critical: Panic detected: runtime error: index out of range [2] with length 2
[22May21 08:15:01.1723] Critical: Optional panic data: %!v(MISSING)
[22May21 08:15:01.1977] Error: 456dfcd7-2d1d-450a-8263-160382e4ad6e: unexpected status code 401
[22May21 08:15:01.2404] Error: ba996127-05db-458f-bbe5-fe72372b9b72: unexpected status code 401
[22May21 08:15:01.6307] Error: 4d841e6c-b788-4d81-993c-6f18d3cb8d13: unexpected status code 401
[22May21 08:15:02.5707] Critical: Panic detected: runtime error: index out of range [2] with length 2
[22May21 08:15:02.5708] Critical: Optional panic data: %!v(MISSING)
[22May21 08:15:03.5002] Error: 7949cc34-b1cf-4adc-b830-2616a021a11a: `entryValue` field required
[22May21 08:15:03.5584] Error: 239f1640-3122-403e-909f-87df971ee31a: `entryValue` field required
[22May21 08:15:03.5828] Error: e417c1a4-4897-40f6-94af-c1c22fbe9070: `entryValue` field required
[22May21 08:15:03.9081] Critical: Panic detected: runtime error: index out of range [2] with length 2
[22May21 08:15:03.9081] Critical: Optional panic data: %!v(MISSING)
[22May21 08:15:03.961] Error: f0a576bc-5e6b-4f6b-8b15-b206ea7146df: `entryValue` field required
[22May21 08:15:04.4733] Error: b4010ca8-bc29-4c4d-aff8-9ed71553b0b0: unexpected status code 401
[22May21 08:16:08.3098] Error: 05f66d9e-ed7b-4a0e-9e66-0b8167970822: unexpected status code 401
[22May21 08:16:08.5805] Error: 315d3067-7b2f-45ff-8cee-d7da9cfa3f3b: `entryValue` field required
[22May21 08:17:50.7406] Critical: Optional panic data: %!v(MISSING)
[22May21 08:17:50.7407] Critical: Panic detected: runtime error: invalid memory address or nil pointer dereference
[22May21 08:21:22.4875] Debug: Token created for rudi9719
[22May21 08:21:23.1959] Critical: Panic detected: runtime error: invalid memory address or nil pointer dereference
[22May21 08:21:23.1958] Critical: Optional panic data: %!v(MISSING)
[22May21 08:24:34.1008] Critical: Optional panic data: %!v(MISSING)
[22May21 08:24:34.1008] Critical: Panic detected: runtime error: invalid memory address or nil pointer dereference
[22May21 08:24:40.75] Debug: Token created for rudi9719
[22May21 08:24:41.3495] Critical: Optional panic data: %!v(MISSING)
[22May21 08:24:41.3496] Critical: Panic detected: runtime error: invalid memory address or nil pointer dereference
[22May21 08:24:41.6306] Critical: Optional panic data: %!v(MISSING)
[22May21 08:24:41.6307] Critical: Panic detected: runtime error: invalid memory address or nil pointer dereference
[22May21 08:24:51.7027] Critical: Optional panic data: %!v(MISSING)
[22May21 08:24:51.7026] Critical: Panic detected: runtime error: invalid memory address or nil pointer dereference
[22May21 09:53:43.3098] Debug: Token created for rudi9719
[22May21 09:53:43.9497] Critical: Panic detected: runtime error: invalid memory address or nil pointer dereference
[22May21 09:53:43.9497] Critical: Optional panic data: %!v(MISSING)
[22May21 09:53:44.0814] Critical: Optional panic data: %!v(MISSING)
[22May21 09:53:44.0816] Critical: Panic detected: runtime error: invalid memory address or nil pointer dereference
[22May21 09:53:47.2925] Critical: Panic detected: runtime error: invalid memory address or nil pointer dereference
[22May21 09:53:47.2924] Critical: Optional panic data: %!v(MISSING)
[22May21 10:37:39.104] Debug: F

9
types.go

@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
package main
import "samhofi.us/x/keybase/v2/types/chat1"
type BotCommand struct {
Advert chat1.AdvertiseCommandAPIParam
Triggers []string
Exec func(chat1.MsgSummary)
}
Loading…
Cancel
Save