1
0
mirror of https://github.com/makew0rld/amfora.git synced 2024-12-04 14:46:29 -05:00

Update dependencies, browse using TabbedPanels (#104)

Co-authored-by: makeworld <25111343+makeworld-the-better-one@users.noreply.github.com>
This commit is contained in:
Trevor Slocum 2020-10-29 11:56:14 -07:00 committed by GitHub
parent f5024068d0
commit 3ef059ad5e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 300 additions and 357 deletions

View File

@ -21,37 +21,38 @@ var bkmkCh = make(chan int) // 1, 0, -1 for add/update, cancel, and remove
var bkmkModalText string // The current text of the input field in the modal var bkmkModalText string // The current text of the input field in the modal
func bkmkInit() { func bkmkInit() {
m := bkmkModal
if viper.GetBool("a-general.color") { if viper.GetBool("a-general.color") {
bkmkModal.SetBackgroundColor(config.GetColor("bkmk_modal_bg")). m.SetBackgroundColor(config.GetColor("bkmk_modal_bg"))
SetButtonBackgroundColor(config.GetColor("btn_bg")). m.SetButtonBackgroundColor(config.GetColor("btn_bg"))
SetButtonTextColor(config.GetColor("btn_text")). m.SetButtonTextColor(config.GetColor("btn_text"))
SetTextColor(config.GetColor("bkmk_modal_text")) m.SetTextColor(config.GetColor("bkmk_modal_text"))
bkmkModal.GetForm(). form := m.GetForm()
SetLabelColor(config.GetColor("bkmk_modal_label")). form.SetLabelColor(config.GetColor("bkmk_modal_label"))
SetFieldBackgroundColor(config.GetColor("bkmk_modal_field_bg")). form.SetFieldBackgroundColor(config.GetColor("bkmk_modal_field_bg"))
SetFieldTextColor(config.GetColor("bkmk_modal_field_text")) form.SetFieldTextColor(config.GetColor("bkmk_modal_field_text"))
bkmkModal.GetFrame(). frame := m.GetFrame()
SetBorderColor(config.GetColor("bkmk_modal_text")). frame.SetBorderColor(config.GetColor("bkmk_modal_text"))
SetTitleColor(config.GetColor("bkmk_modal_text")) frame.SetTitleColor(config.GetColor("bkmk_modal_text"))
} else { } else {
bkmkModal.SetBackgroundColor(tcell.ColorBlack). m.SetBackgroundColor(tcell.ColorBlack)
SetButtonBackgroundColor(tcell.ColorWhite). m.SetButtonBackgroundColor(tcell.ColorWhite)
SetButtonTextColor(tcell.ColorBlack). m.SetButtonTextColor(tcell.ColorBlack)
SetTextColor(tcell.ColorWhite) m.SetTextColor(tcell.ColorWhite)
bkmkModal.GetForm(). form := m.GetForm()
SetLabelColor(tcell.ColorWhite). form.SetLabelColor(tcell.ColorWhite)
SetFieldBackgroundColor(tcell.ColorWhite). form.SetFieldBackgroundColor(tcell.ColorWhite)
SetFieldTextColor(tcell.ColorBlack) form.SetFieldTextColor(tcell.ColorBlack)
bkmkModal.GetFrame(). frame := m.GetFrame()
SetBorderColor(tcell.ColorWhite). frame.SetBorderColor(tcell.ColorWhite)
SetTitleColor(tcell.ColorWhite) frame.SetTitleColor(tcell.ColorWhite)
} }
bkmkModal.SetBorder(true) m.SetBorder(true)
bkmkModal.GetFrame(). frame := m.GetFrame()
SetTitleAlign(cview.AlignCenter). frame.SetTitleAlign(cview.AlignCenter)
SetTitle(" Add Bookmark ") frame.SetTitle(" Add Bookmark ")
bkmkModal.SetDoneFunc(func(buttonIndex int, buttonLabel string) { m.SetDoneFunc(func(buttonIndex int, buttonLabel string) {
switch buttonLabel { switch buttonLabel {
case "Add": case "Add":
bkmkCh <- 1 bkmkCh <- 1
@ -95,13 +96,12 @@ func openBkmkModal(name string, exists bool, favicon string) (string, int) {
bkmkModalText = text bkmkModalText = text
}) })
tabPages.ShowPage("bkmk") panels.ShowPanel("bkmk")
tabPages.SendToFront("bkmk")
App.SetFocus(bkmkModal) App.SetFocus(bkmkModal)
App.Draw() App.Draw()
action := <-bkmkCh action := <-bkmkCh
tabPages.SwitchToPage(strconv.Itoa(curTab)) browser.SetCurrentTab(strconv.Itoa(curTab))
App.SetFocus(tabs[curTab].view) App.SetFocus(tabs[curTab].view)
App.Draw() App.Draw()

View File

@ -26,37 +26,27 @@ var termH int
// The user input and URL display bar at the bottom // The user input and URL display bar at the bottom
var bottomBar = cview.NewInputField() var bottomBar = cview.NewInputField()
// Viewer for the tab primitives // Viewer for primitives
// Pages are named as strings of tab numbers - so the textview for the first tab // This contains the browser and any modals modals drawn on top of it.
// is held in the page named "0".
// The only pages that don't confine to this scheme are those named after modals,
// which are used to draw modals on top the current tab.
// Ex: "info", "error", "input", "yesno" // Ex: "info", "error", "input", "yesno"
var tabPages = cview.NewPages() var panels = cview.NewPanels()
// The tabs at the top with titles // Tabbed viewer for primitives
var tabRow = cview.NewTextView(). // Panels are named as strings of tab numbers - so the textview for the first tab
SetDynamicColors(true). // is held in the page named "0".
SetRegions(true). var browser = cview.NewTabbedPanels()
SetScrollable(true).
SetWrap(false).
SetHighlightedFunc(func(added, removed, remaining []string) {
// There will always only be one string in added - never multiple highlights
// Remaining should always be empty
i, _ := strconv.Atoi(added[0])
tabPages.SwitchToPage(strconv.Itoa(i)) // Tab names are just numbers, zero-indexed
})
// Root layout // Root layout
var layout = cview.NewFlex(). var layout = cview.NewFlex()
SetDirection(cview.FlexRow)
var newTabPage structs.Page var newTabPage structs.Page
var App = cview.NewApplication(). var App = cview.NewApplication()
EnableMouse(false).
SetRoot(layout, true). func Init() {
SetAfterResizeFunc(func(width int, height int) { App.EnableMouse(false)
App.SetRoot(layout, true)
App.SetAfterResizeFunc(func(width int, height int) {
// Store for calculations // Store for calculations
termW = width termW = width
termH = height termH = height
@ -70,35 +60,26 @@ var App = cview.NewApplication().
}(tabs[curTab]) }(tabs[curTab])
}) })
func Init() { panels.AddPanel("browser", browser, true, true)
tabRow.SetChangedFunc(func() {
App.Draw()
})
helpInit() helpInit()
layout. layout.SetDirection(cview.FlexRow)
AddItem(tabRow, 1, 1, false). layout.AddItem(panels, 0, 1, true)
AddItem(nil, 1, 1, false). // One line of empty space above the page layout.AddItem(bottomBar, 1, 1, false)
AddItem(tabPages, 0, 1, true).
AddItem(nil, 1, 1, false). // One line of empty space before bottomBar
AddItem(bottomBar, 1, 1, false)
if viper.GetBool("a-general.color") { if viper.GetBool("a-general.color") {
layout.SetBackgroundColor(config.GetColor("bg")) layout.SetBackgroundColor(config.GetColor("bg"))
tabRow.SetBackgroundColor(config.GetColor("bg"))
bottomBar.SetBackgroundColor(config.GetColor("bottombar_bg")) bottomBar.SetBackgroundColor(config.GetColor("bottombar_bg"))
bottomBar. bottomBar.SetLabelColor(config.GetColor("bottombar_label"))
SetLabelColor(config.GetColor("bottombar_label")). bottomBar.SetFieldBackgroundColor(config.GetColor("bottombar_bg"))
SetFieldBackgroundColor(config.GetColor("bottombar_bg")). bottomBar.SetFieldTextColor(config.GetColor("bottombar_text"))
SetFieldTextColor(config.GetColor("bottombar_text"))
} else { } else {
bottomBar.SetBackgroundColor(tcell.ColorWhite) bottomBar.SetBackgroundColor(tcell.ColorWhite)
bottomBar. bottomBar.SetLabelColor(tcell.ColorBlack)
SetLabelColor(tcell.ColorBlack). bottomBar.SetFieldBackgroundColor(tcell.ColorWhite)
SetFieldBackgroundColor(tcell.ColorWhite). bottomBar.SetFieldTextColor(tcell.ColorBlack)
SetFieldTextColor(tcell.ColorBlack)
} }
bottomBar.SetDoneFunc(func(key tcell.Key) { bottomBar.SetDoneFunc(func(key tcell.Key) {
tab := curTab tab := curTab
@ -429,23 +410,10 @@ func NewTab() {
// The first page will be the next one the user goes to. // The first page will be the next one the user goes to.
tabs[curTab].history.pos = -1 tabs[curTab].history.pos = -1
tabPages.AddAndSwitchToPage(strconv.Itoa(curTab), tabs[curTab].view, true) browser.AddTab(strconv.Itoa(curTab), strconv.Itoa(curTab+1), tabs[curTab].view)
browser.SetCurrentTab(strconv.Itoa(curTab))
App.SetFocus(tabs[curTab].view) App.SetFocus(tabs[curTab].view)
// Add tab number to the actual place where tabs are show on the screen
// Tab regions are 0-indexed but text displayed on the screen starts at 1
if viper.GetBool("a-general.color") {
fmt.Fprintf(tabRow, `["%d"][%s] %d [%s][""]|`,
curTab,
config.GetColorString("tab_num"),
curTab+1,
config.GetColorString("tab_divider"),
)
} else {
fmt.Fprintf(tabRow, `["%d"] %d [""]|`, curTab, curTab+1)
}
tabRow.Highlight(strconv.Itoa(curTab)).ScrollToHighlight()
bottomBar.SetLabel("") bottomBar.SetLabel("")
bottomBar.SetText("") bottomBar.SetText("")
tabs[curTab].saveBottomBar() tabs[curTab].saveBottomBar()
@ -472,7 +440,7 @@ func CloseTab() {
} }
tabs = tabs[:len(tabs)-1] tabs = tabs[:len(tabs)-1]
tabPages.RemovePage(strconv.Itoa(curTab)) browser.RemoveTab(strconv.Itoa(curTab))
if curTab <= 0 { if curTab <= 0 {
curTab = NumTabs() - 1 curTab = NumTabs() - 1
@ -480,8 +448,7 @@ func CloseTab() {
curTab-- curTab--
} }
tabPages.SwitchToPage(strconv.Itoa(curTab)) // Go to previous page browser.SetCurrentTab(strconv.Itoa(curTab)) // Go to previous page
rewriteTabRow()
// Restore previous tab's state // Restore previous tab's state
tabs[curTab].applyAll() tabs[curTab].applyAll()
@ -513,8 +480,7 @@ func SwitchTab(tab int) {
// Display tab // Display tab
reformatPageAndSetView(tabs[curTab], tabs[curTab].page) reformatPageAndSetView(tabs[curTab], tabs[curTab].page)
tabPages.SwitchToPage(strconv.Itoa(curTab)) browser.SetCurrentTab(strconv.Itoa(curTab))
tabRow.Highlight(strconv.Itoa(curTab)).ScrollToHighlight()
tabs[curTab].applyAll() tabs[curTab].applyAll()
App.SetFocus(tabs[curTab].view) App.SetFocus(tabs[curTab].view)

View File

@ -22,8 +22,7 @@ import (
) )
// For choosing between download and the portal - copy of YesNo basically // For choosing between download and the portal - copy of YesNo basically
var dlChoiceModal = cview.NewModal(). var dlChoiceModal = cview.NewModal()
AddButtons([]string{"Download", "Open in portal", "Cancel"})
// Channel to indicate what choice they made using the button text // Channel to indicate what choice they made using the button text
var dlChoiceCh = make(chan string) var dlChoiceCh = make(chan string)
@ -31,52 +30,55 @@ var dlChoiceCh = make(chan string)
var dlModal = cview.NewModal() var dlModal = cview.NewModal()
func dlInit() { func dlInit() {
dlm := dlModal
chm := dlChoiceModal
if viper.GetBool("a-general.color") { if viper.GetBool("a-general.color") {
dlChoiceModal.SetButtonBackgroundColor(config.GetColor("btn_bg")). chm.SetButtonBackgroundColor(config.GetColor("btn_bg"))
SetButtonTextColor(config.GetColor("btn_text")). chm.SetButtonTextColor(config.GetColor("btn_text"))
SetBackgroundColor(config.GetColor("dl_choice_modal_bg")). chm.SetBackgroundColor(config.GetColor("dl_choice_modal_bg"))
SetTextColor(config.GetColor("dl_choice_modal_text")) chm.SetTextColor(config.GetColor("dl_choice_modal_text"))
dlChoiceModal.GetFrame(). frame := chm.GetFrame()
SetBorderColor(config.GetColor("dl_choice_modal_text")). frame.SetBorderColor(config.GetColor("dl_choice_modal_text"))
SetTitleColor(config.GetColor("dl_choice_modal_text")) frame.SetTitleColor(config.GetColor("dl_choice_modal_text"))
dlModal.SetButtonBackgroundColor(config.GetColor("btn_bg")). dlm.SetButtonBackgroundColor(config.GetColor("btn_bg"))
SetButtonTextColor(config.GetColor("btn_text")). dlm.SetButtonTextColor(config.GetColor("btn_text"))
SetBackgroundColor(config.GetColor("dl_modal_bg")). dlm.SetBackgroundColor(config.GetColor("dl_modal_bg"))
SetTextColor(config.GetColor("dl_modal_text")) dlm.SetTextColor(config.GetColor("dl_modal_text"))
dlModal.GetFrame(). frame = dlm.GetFrame()
SetBorderColor(config.GetColor("dl_modal_text")). frame.SetBorderColor(config.GetColor("dl_modal_text"))
SetTitleColor(config.GetColor("dl_modal_text")) frame.SetTitleColor(config.GetColor("dl_modal_text"))
} else { } else {
dlChoiceModal.SetButtonBackgroundColor(tcell.ColorWhite). chm.SetButtonBackgroundColor(tcell.ColorWhite)
SetButtonTextColor(tcell.ColorBlack). chm.SetButtonTextColor(tcell.ColorBlack)
SetBackgroundColor(tcell.ColorBlack). chm.SetBackgroundColor(tcell.ColorBlack)
SetTextColor(tcell.ColorWhite) chm.SetTextColor(tcell.ColorWhite)
dlChoiceModal.SetBorderColor(tcell.ColorWhite) dlChoiceModal.SetBorderColor(tcell.ColorWhite)
dlChoiceModal.GetFrame().SetTitleColor(tcell.ColorWhite) dlChoiceModal.GetFrame().SetTitleColor(tcell.ColorWhite)
dlModal.SetButtonBackgroundColor(tcell.ColorWhite). dlm.SetButtonBackgroundColor(tcell.ColorWhite)
SetButtonTextColor(tcell.ColorBlack). dlm.SetButtonTextColor(tcell.ColorBlack)
SetBackgroundColor(tcell.ColorBlack). dlm.SetBackgroundColor(tcell.ColorBlack)
SetTextColor(tcell.ColorWhite) dlm.SetTextColor(tcell.ColorWhite)
dlModal.GetFrame(). frame := dlm.GetFrame()
SetBorderColor(tcell.ColorWhite). frame.SetBorderColor(tcell.ColorWhite)
SetTitleColor(tcell.ColorWhite) frame.SetTitleColor(tcell.ColorWhite)
} }
dlChoiceModal.SetBorder(true) chm.AddButtons([]string{"Download", "Open in portal", "Cancel"})
dlChoiceModal.GetFrame().SetTitleAlign(cview.AlignCenter) chm.SetBorder(true)
dlChoiceModal.SetDoneFunc(func(buttonIndex int, buttonLabel string) { chm.GetFrame().SetTitleAlign(cview.AlignCenter)
chm.SetDoneFunc(func(buttonIndex int, buttonLabel string) {
dlChoiceCh <- buttonLabel dlChoiceCh <- buttonLabel
}) })
dlModal.SetBorder(true) dlm.SetBorder(true)
dlModal.GetFrame(). frame := dlm.GetFrame()
SetTitleAlign(cview.AlignCenter). frame.SetTitleAlign(cview.AlignCenter)
SetTitle(" Download ") frame.SetTitle(" Download ")
dlModal.SetDoneFunc(func(buttonIndex int, buttonLabel string) { dlm.SetDoneFunc(func(buttonIndex int, buttonLabel string) {
if buttonLabel == "Ok" { if buttonLabel == "Ok" {
tabPages.SwitchToPage(strconv.Itoa(curTab)) browser.SetCurrentTab(strconv.Itoa(curTab))
App.SetFocus(tabs[curTab].view) App.SetFocus(tabs[curTab].view)
App.Draw() App.Draw()
} }
@ -95,14 +97,13 @@ func dlChoice(text, u string, resp *gemini.Response) {
} }
dlChoiceModal.SetText(text) dlChoiceModal.SetText(text)
tabPages.ShowPage("dlChoice") panels.ShowPanel("dlChoice")
tabPages.SendToFront("dlChoice")
App.SetFocus(dlChoiceModal) App.SetFocus(dlChoiceModal)
App.Draw() App.Draw()
choice := <-dlChoiceCh choice := <-dlChoiceCh
if choice == "Download" { if choice == "Download" {
tabPages.HidePage("dlChoice") panels.HidePanel("dlChoice")
App.Draw() App.Draw()
downloadURL(u, resp) downloadURL(u, resp)
return return
@ -118,12 +119,12 @@ func dlChoice(text, u string, resp *gemini.Response) {
} }
portalURL = strings.TrimPrefix(portalURL, "gemini://") + "?raw=1" portalURL = strings.TrimPrefix(portalURL, "gemini://") + "?raw=1"
handleHTTP("https://portal.mozz.us/gemini/"+portalURL, false) handleHTTP("https://portal.mozz.us/gemini/"+portalURL, false)
tabPages.SwitchToPage(strconv.Itoa(curTab)) browser.SetCurrentTab(strconv.Itoa(curTab))
App.SetFocus(tabs[curTab].view) App.SetFocus(tabs[curTab].view)
App.Draw() App.Draw()
return return
} }
tabPages.SwitchToPage(strconv.Itoa(curTab)) browser.SetCurrentTab(strconv.Itoa(curTab))
App.SetFocus(tabs[curTab].view) App.SetFocus(tabs[curTab].view)
App.Draw() App.Draw()
} }
@ -170,15 +171,14 @@ func downloadURL(u string, resp *gemini.Response) {
// Display // Display
dlModal.ClearButtons() dlModal.ClearButtons()
dlModal.AddButtons([]string{"Downloading..."}) dlModal.AddButtons([]string{"Downloading..."})
tabPages.ShowPage("dl") panels.ShowPanel("dl")
tabPages.SendToFront("dl")
App.SetFocus(dlModal) App.SetFocus(dlModal)
App.Draw() App.Draw()
_, err = io.Copy(io.MultiWriter(f, bar), resp.Body) _, err = io.Copy(io.MultiWriter(f, bar), resp.Body)
done = true done = true
if err != nil { if err != nil {
tabPages.HidePage("dl") panels.HidePanel("dl")
Error("Download Error", err.Error()) Error("Download Error", err.Error())
f.Close() f.Close()
os.Remove(savePath) // Remove partial file os.Remove(savePath) // Remove partial file

View File

@ -1,10 +1,13 @@
package display package display
import ( import (
"fmt"
"strconv" "strconv"
"strings" "strings"
"text/tabwriter"
"github.com/gdamore/tcell/v2" "github.com/gdamore/tcell/v2"
"github.com/makeworld-the-better-one/amfora/config"
"gitlab.com/tslocum/cview" "gitlab.com/tslocum/cview"
) )
@ -47,56 +50,39 @@ Ctrl-C|Hard quit. This can be used when in the middle of downloading,
|for example. |for example.
`) `)
var helpTable = cview.NewTable(). var helpTable = cview.NewTextView()
SetSelectable(false, false).
SetBorders(false).
SetScrollBarVisibility(cview.ScrollBarNever)
// Help displays the help and keybindings. // Help displays the help and keybindings.
func Help() { func Help() {
helpTable.ScrollToBeginning() helpTable.ScrollToBeginning()
tabPages.SwitchToPage("help") if !browser.HasTab("help") {
browser.AddTab("help", "Help", helpTable)
}
browser.SetCurrentTab("help")
App.SetFocus(helpTable) App.SetFocus(helpTable)
App.Draw() App.Draw()
} }
func helpInit() { func helpInit() {
// Populate help table // Populate help table
helpTable.SetBackgroundColor(config.GetColor("bg"))
helpTable.SetPadding(0, 0, 1, 1)
helpTable.SetDoneFunc(func(key tcell.Key) { helpTable.SetDoneFunc(func(key tcell.Key) {
if key == tcell.KeyEsc || key == tcell.KeyEnter { if key == tcell.KeyEsc || key == tcell.KeyEnter {
tabPages.SwitchToPage(strconv.Itoa(curTab)) browser.SetCurrentTab(strconv.Itoa(curTab))
App.SetFocus(tabs[curTab].view) App.SetFocus(tabs[curTab].view)
App.Draw() App.Draw()
} }
}) })
rows := strings.Count(helpCells, "\n") + 1 lines := strings.Split(helpCells, "\n")
cells := strings.Split( w := tabwriter.NewWriter(helpTable, 0, 8, 2, ' ', 0)
strings.ReplaceAll(helpCells, "\n", "|"), for i, line := range lines {
"|") cells := strings.Split(line, "|")
cell := 0 if i > 0 && len(cells[0]) > 0 {
extraRows := 0 // Rows continued from the previous, without spacing fmt.Fprintln(w, "\t")
for r := 0; r < rows; r++ {
for c := 0; c < 2; c++ {
var tableCell *cview.TableCell
if c == 0 {
// First column, the keybinding
tableCell = cview.NewTableCell(" " + cells[cell]).
SetAttributes(tcell.AttrBold).
SetAlign(cview.AlignLeft)
} else {
tableCell = cview.NewTableCell(" " + cells[cell])
}
if c == 0 && cells[cell] == "" || (cell > 0 && cells[cell-1] == "" && c == 1) {
// The keybinding column for this row was blank, meaning the explanation
// column is continued from the previous row.
// The row should be added without any spacing rows
helpTable.SetCell(((2*r)-extraRows/2)-1, c, tableCell)
extraRows++
} else {
helpTable.SetCell((2*r)-extraRows/2, c, tableCell) // Every other row, for readability
}
cell++
} }
fmt.Fprintf(w, "%s\t%s\n", cells[0], cells[1])
} }
tabPages.AddPage("help", helpTable, true, false) w.Flush()
browser.AddTab("help", "Help", helpTable)
} }

View File

@ -16,103 +16,114 @@ import (
// This file contains code for the popups / modals used in the display. // This file contains code for the popups / modals used in the display.
// The bookmark modal is in bookmarks.go // The bookmark modal is in bookmarks.go
var infoModal = cview.NewModal(). var infoModal = cview.NewModal()
AddButtons([]string{"Ok"})
var errorModal = cview.NewModal(). var errorModal = cview.NewModal()
AddButtons([]string{"Ok"})
var inputModal = cview.NewModal() var inputModal = cview.NewModal()
var inputCh = make(chan string) var inputCh = make(chan string)
var inputModalText string // The current text of the input field in the modal var inputModalText string // The current text of the input field in the modal
var yesNoModal = cview.NewModal(). var yesNoModal = cview.NewModal()
AddButtons([]string{"Yes", "No"})
// Channel to receive yesNo answer on // Channel to receive yesNo answer on
var yesNoCh = make(chan bool) var yesNoCh = make(chan bool)
func modalInit() { func modalInit() {
tabPages.AddPage("info", infoModal, false, false). infoModal.AddButtons([]string{"Ok"})
AddPage("error", errorModal, false, false).
AddPage("input", inputModal, false, false). errorModal.AddButtons([]string{"Ok"})
AddPage("yesno", yesNoModal, false, false).
AddPage("bkmk", bkmkModal, false, false). yesNoModal.AddButtons([]string{"Yes", "No"})
AddPage("dlChoice", dlChoiceModal, false, false).
AddPage("dl", dlModal, false, false) panels.AddPanel("info", infoModal, false, false)
panels.AddPanel("error", errorModal, false, false)
panels.AddPanel("input", inputModal, false, false)
panels.AddPanel("yesno", yesNoModal, false, false)
panels.AddPanel("bkmk", bkmkModal, false, false)
panels.AddPanel("dlChoice", dlChoiceModal, false, false)
panels.AddPanel("dl", dlModal, false, false)
// Color setup // Color setup
if viper.GetBool("a-general.color") { if viper.GetBool("a-general.color") {
infoModal.SetBackgroundColor(config.GetColor("info_modal_bg")). m := infoModal
SetButtonBackgroundColor(config.GetColor("btn_bg")). m.SetBackgroundColor(config.GetColor("info_modal_bg"))
SetButtonTextColor(config.GetColor("btn_text")). m.SetButtonBackgroundColor(config.GetColor("btn_bg"))
SetTextColor(config.GetColor("info_modal_text")) m.SetButtonTextColor(config.GetColor("btn_text"))
infoModal.GetFrame(). m.SetTextColor(config.GetColor("info_modal_text"))
SetBorderColor(config.GetColor("info_modal_text")). frame := m.GetFrame()
SetTitleColor(config.GetColor("info_modal_text")) frame.SetBorderColor(config.GetColor("info_modal_text"))
frame.SetTitleColor(config.GetColor("info_modal_text"))
errorModal.SetBackgroundColor(config.GetColor("error_modal_bg")). m = errorModal
SetButtonBackgroundColor(config.GetColor("btn_bg")). m.SetBackgroundColor(config.GetColor("error_modal_bg"))
SetButtonTextColor(config.GetColor("btn_text")). m.SetButtonBackgroundColor(config.GetColor("btn_bg"))
SetTextColor(config.GetColor("error_modal_text")) m.SetButtonTextColor(config.GetColor("btn_text"))
errorModal.GetFrame(). m.SetTextColor(config.GetColor("error_modal_text"))
SetBorderColor(config.GetColor("error_modal_text")). frame = errorModal.GetFrame()
SetTitleColor(config.GetColor("error_modal_text")) frame.SetBorderColor(config.GetColor("error_modal_text"))
frame.SetTitleColor(config.GetColor("error_modal_text"))
inputModal.SetBackgroundColor(config.GetColor("input_modal_bg")). m = inputModal
SetButtonBackgroundColor(config.GetColor("btn_bg")). m.SetBackgroundColor(config.GetColor("input_modal_bg"))
SetButtonTextColor(config.GetColor("btn_text")). m.SetButtonBackgroundColor(config.GetColor("btn_bg"))
SetTextColor(config.GetColor("input_modal_text")) m.SetButtonTextColor(config.GetColor("btn_text"))
inputModal.GetFrame(). m.SetTextColor(config.GetColor("input_modal_text"))
SetBorderColor(config.GetColor("input_modal_text")). frame = inputModal.GetFrame()
SetTitleColor(config.GetColor("input_modal_text")) frame.SetBorderColor(config.GetColor("input_modal_text"))
inputModal.GetForm(). frame.SetTitleColor(config.GetColor("input_modal_text"))
SetFieldBackgroundColor(config.GetColor("input_modal_field_bg")). form := inputModal.GetForm()
SetFieldTextColor(config.GetColor("input_modal_field_text")) form.SetFieldBackgroundColor(config.GetColor("input_modal_field_bg"))
form.SetFieldTextColor(config.GetColor("input_modal_field_text"))
yesNoModal.SetButtonBackgroundColor(config.GetColor("btn_bg")). m = yesNoModal
SetButtonTextColor(config.GetColor("btn_text")) m.SetButtonBackgroundColor(config.GetColor("btn_bg"))
m.SetButtonTextColor(config.GetColor("btn_text"))
} else { } else {
infoModal.SetBackgroundColor(tcell.ColorBlack). m := infoModal
SetButtonBackgroundColor(tcell.ColorWhite). m.SetBackgroundColor(tcell.ColorBlack)
SetButtonTextColor(tcell.ColorBlack). m.SetButtonBackgroundColor(tcell.ColorWhite)
SetTextColor(tcell.ColorWhite) m.SetButtonTextColor(tcell.ColorBlack)
infoModal.GetFrame(). m.SetTextColor(tcell.ColorWhite)
SetBorderColor(tcell.ColorWhite). frame := infoModal.GetFrame()
SetTitleColor(tcell.ColorWhite) frame.SetBorderColor(tcell.ColorWhite)
frame.SetTitleColor(tcell.ColorWhite)
errorModal.SetBackgroundColor(tcell.ColorBlack). m = errorModal
SetButtonBackgroundColor(tcell.ColorWhite). m.SetBackgroundColor(tcell.ColorBlack)
SetButtonTextColor(tcell.ColorBlack). m.SetButtonBackgroundColor(tcell.ColorWhite)
SetTextColor(tcell.ColorWhite) m.SetButtonTextColor(tcell.ColorBlack)
errorModal.GetFrame(). m.SetTextColor(tcell.ColorWhite)
SetBorderColor(tcell.ColorWhite). frame = errorModal.GetFrame()
SetTitleColor(tcell.ColorWhite) frame.SetBorderColor(tcell.ColorWhite)
frame.SetTitleColor(tcell.ColorWhite)
inputModal.SetBackgroundColor(tcell.ColorBlack). m = inputModal
SetButtonBackgroundColor(tcell.ColorWhite). m.SetBackgroundColor(tcell.ColorBlack)
SetButtonTextColor(tcell.ColorBlack). m.SetButtonBackgroundColor(tcell.ColorWhite)
SetTextColor(tcell.ColorWhite) m.SetButtonTextColor(tcell.ColorBlack)
inputModal.GetFrame(). m.SetTextColor(tcell.ColorWhite)
SetBorderColor(tcell.ColorWhite). frame = inputModal.GetFrame()
SetTitleColor(tcell.ColorWhite) frame.SetBorderColor(tcell.ColorWhite)
inputModal.GetForm(). frame.SetTitleColor(tcell.ColorWhite)
SetFieldBackgroundColor(tcell.ColorWhite). form := inputModal.GetForm()
SetFieldTextColor(tcell.ColorBlack) form.SetFieldBackgroundColor(tcell.ColorWhite)
form.SetFieldTextColor(tcell.ColorBlack)
// YesNo background color is changed in funcs // YesNo background color is changed in funcs
yesNoModal.SetButtonBackgroundColor(tcell.ColorWhite). m = yesNoModal
SetButtonTextColor(tcell.ColorBlack) m.SetButtonBackgroundColor(tcell.ColorWhite)
m.SetButtonTextColor(tcell.ColorBlack)
} }
// Modal functions that can't be added up above, because they return the wrong type // Modal functions that can't be added up above, because they return the wrong type
infoModal.SetBorder(true) infoModal.SetBorder(true)
infoModal.GetFrame(). frame := infoModal.GetFrame()
SetTitleAlign(cview.AlignCenter). frame.SetTitleAlign(cview.AlignCenter)
SetTitle(" Info ") frame.SetTitle(" Info ")
infoModal.SetDoneFunc(func(buttonIndex int, buttonLabel string) { infoModal.SetDoneFunc(func(buttonIndex int, buttonLabel string) {
tabPages.SwitchToPage(strconv.Itoa(curTab)) browser.SetCurrentTab(strconv.Itoa(curTab))
App.SetFocus(tabs[curTab].view) App.SetFocus(tabs[curTab].view)
App.Draw() App.Draw()
}) })
@ -120,15 +131,15 @@ func modalInit() {
errorModal.SetBorder(true) errorModal.SetBorder(true)
errorModal.GetFrame().SetTitleAlign(cview.AlignCenter) errorModal.GetFrame().SetTitleAlign(cview.AlignCenter)
errorModal.SetDoneFunc(func(buttonIndex int, buttonLabel string) { errorModal.SetDoneFunc(func(buttonIndex int, buttonLabel string) {
tabPages.SwitchToPage(strconv.Itoa(curTab)) browser.SetCurrentTab(strconv.Itoa(curTab))
App.SetFocus(tabs[curTab].view) App.SetFocus(tabs[curTab].view)
App.Draw() App.Draw()
}) })
inputModal.SetBorder(true) inputModal.SetBorder(true)
inputModal.GetFrame(). frame = inputModal.GetFrame()
SetTitleAlign(cview.AlignCenter). frame.SetTitleAlign(cview.AlignCenter)
SetTitle(" Input ") frame.SetTitle(" Input ")
inputModal.SetDoneFunc(func(buttonIndex int, buttonLabel string) { inputModal.SetDoneFunc(func(buttonIndex int, buttonLabel string) {
if buttonLabel == "Send" { if buttonLabel == "Send" {
inputCh <- inputModalText inputCh <- inputModalText
@ -167,8 +178,8 @@ func Error(title, text string) {
errorModal.GetFrame().SetTitle(title) errorModal.GetFrame().SetTitle(title)
errorModal.SetText(text) errorModal.SetText(text)
tabPages.ShowPage("error") panels.ShowPanel("error")
tabPages.SendToFront("error") panels.SendToFront("error")
App.SetFocus(errorModal) App.SetFocus(errorModal)
App.Draw() App.Draw()
} }
@ -176,8 +187,8 @@ func Error(title, text string) {
// Info displays some info on the screen in a modal. // Info displays some info on the screen in a modal.
func Info(s string) { func Info(s string) {
infoModal.SetText(s) infoModal.SetText(s)
tabPages.ShowPage("info") panels.ShowPanel("info")
tabPages.SendToFront("info") panels.SendToFront("info")
App.SetFocus(infoModal) App.SetFocus(infoModal)
App.Draw() App.Draw()
} }
@ -198,14 +209,14 @@ func Input(prompt string) (string, bool) {
}) })
inputModal.SetText(prompt + " ") inputModal.SetText(prompt + " ")
tabPages.ShowPage("input") panels.ShowPanel("input")
tabPages.SendToFront("input") panels.SendToFront("input")
App.SetFocus(inputModal) App.SetFocus(inputModal)
App.Draw() App.Draw()
resp := <-inputCh resp := <-inputCh
tabPages.SwitchToPage(strconv.Itoa(curTab)) browser.SetCurrentTab(strconv.Itoa(curTab))
App.SetFocus(tabs[curTab].view) App.SetFocus(tabs[curTab].view)
App.Draw() App.Draw()
@ -218,29 +229,29 @@ func Input(prompt string) (string, bool) {
// YesNo displays a modal asking a yes-or-no question. // YesNo displays a modal asking a yes-or-no question.
func YesNo(prompt string) bool { func YesNo(prompt string) bool {
if viper.GetBool("a-general.color") { if viper.GetBool("a-general.color") {
yesNoModal. m := yesNoModal
SetBackgroundColor(config.GetColor("yesno_modal_bg")). m.SetBackgroundColor(config.GetColor("yesno_modal_bg"))
SetTextColor(config.GetColor("yesno_modal_text")) m.SetTextColor(config.GetColor("yesno_modal_text"))
yesNoModal.GetFrame(). frame := yesNoModal.GetFrame()
SetBorderColor(config.GetColor("yesno_modal_text")). frame.SetBorderColor(config.GetColor("yesno_modal_text"))
SetTitleColor(config.GetColor("yesno_modal_text")) frame.SetTitleColor(config.GetColor("yesno_modal_text"))
} else { } else {
yesNoModal. m := yesNoModal
SetBackgroundColor(tcell.ColorBlack). m.SetBackgroundColor(tcell.ColorBlack)
SetTextColor(tcell.ColorWhite) m.SetTextColor(tcell.ColorWhite)
yesNoModal.GetFrame(). frame := yesNoModal.GetFrame()
SetBorderColor(tcell.ColorWhite). frame.SetBorderColor(tcell.ColorWhite)
SetTitleColor(tcell.ColorWhite) frame.SetTitleColor(tcell.ColorWhite)
} }
yesNoModal.GetFrame().SetTitle("") yesNoModal.GetFrame().SetTitle("")
yesNoModal.SetText(prompt) yesNoModal.SetText(prompt)
tabPages.ShowPage("yesno") panels.ShowPanel("yesno")
tabPages.SendToFront("yesno") panels.SendToFront("yesno")
App.SetFocus(yesNoModal) App.SetFocus(yesNoModal)
App.Draw() App.Draw()
resp := <-yesNoCh resp := <-yesNoCh
tabPages.SwitchToPage(strconv.Itoa(curTab)) browser.SetCurrentTab(strconv.Itoa(curTab))
App.SetFocus(tabs[curTab].view) App.SetFocus(tabs[curTab].view)
App.Draw() App.Draw()
return resp return resp
@ -251,36 +262,34 @@ func YesNo(prompt string) bool {
func Tofu(host string, expiry time.Time) bool { func Tofu(host string, expiry time.Time) bool {
// Reuses yesNoModal, with error color // Reuses yesNoModal, with error color
m := yesNoModal
frame := yesNoModal.GetFrame()
if viper.GetBool("a-general.color") { if viper.GetBool("a-general.color") {
yesNoModal. m.SetBackgroundColor(config.GetColor("tofu_modal_bg"))
SetBackgroundColor(config.GetColor("tofu_modal_bg")). m.SetTextColor(config.GetColor("tofu_modal_text"))
SetTextColor(config.GetColor("tofu_modal_text")) frame.SetBorderColor(config.GetColor("tofu_modal_text"))
yesNoModal.GetFrame(). frame.SetTitleColor(config.GetColor("tofu_modal_text"))
SetBorderColor(config.GetColor("tofu_modal_text")).
SetTitleColor(config.GetColor("tofu_modal_text"))
} else { } else {
yesNoModal. m.SetBackgroundColor(tcell.ColorBlack)
SetBackgroundColor(tcell.ColorBlack). m.SetTextColor(tcell.ColorWhite)
SetTextColor(tcell.ColorWhite) m.SetBorderColor(tcell.ColorWhite)
yesNoModal. m.SetTitleColor(tcell.ColorWhite)
SetBorderColor(tcell.ColorWhite).
SetTitleColor(tcell.ColorWhite)
} }
yesNoModal.GetFrame().SetTitle(" TOFU ") frame.SetTitle(" TOFU ")
yesNoModal.SetText( m.SetText(
//nolint:lll //nolint:lll
fmt.Sprintf("%s's certificate has changed, possibly indicating an security issue. The certificate would have expired %s. Are you sure you want to continue? ", fmt.Sprintf("%s's certificate has changed, possibly indicating an security issue. The certificate would have expired %s. Are you sure you want to continue? ",
host, host,
humanize.Time(expiry), humanize.Time(expiry),
), ),
) )
tabPages.ShowPage("yesno") panels.ShowPanel("yesno")
tabPages.SendToFront("yesno") panels.SendToFront("yesno")
App.SetFocus(yesNoModal) App.SetFocus(yesNoModal)
App.Draw() App.Draw()
resp := <-yesNoCh resp := <-yesNoCh
tabPages.SwitchToPage(strconv.Itoa(curTab)) browser.SetCurrentTab(strconv.Itoa(curTab))
App.SetFocus(tabs[curTab].view) App.SetFocus(tabs[curTab].view)
App.Draw() App.Draw()
return resp return resp

View File

@ -3,17 +3,14 @@ package display
import ( import (
"bytes" "bytes"
"errors" "errors"
"fmt"
"io" "io"
"net" "net"
"net/url" "net/url"
"os/exec" "os/exec"
"strconv"
"strings" "strings"
"github.com/makeworld-the-better-one/amfora/cache" "github.com/makeworld-the-better-one/amfora/cache"
"github.com/makeworld-the-better-one/amfora/client" "github.com/makeworld-the-better-one/amfora/client"
"github.com/makeworld-the-better-one/amfora/config"
"github.com/makeworld-the-better-one/amfora/renderer" "github.com/makeworld-the-better-one/amfora/renderer"
"github.com/makeworld-the-better-one/amfora/structs" "github.com/makeworld-the-better-one/amfora/structs"
"github.com/makeworld-the-better-one/amfora/webbrowser" "github.com/makeworld-the-better-one/amfora/webbrowser"
@ -198,7 +195,7 @@ func handleFavicon(t *tab, host, old string) {
defer func() { defer func() {
// Update display if needed // Update display if needed
if t.page.Favicon != old && isValidTab(t) { if t.page.Favicon != old && isValidTab(t) {
rewriteTabRow() // TODO update browser tab label
} }
}() }()
@ -220,7 +217,7 @@ func handleFavicon(t *tab, host, old string) {
} }
if fav != "" { if fav != "" {
t.page.Favicon = fav t.page.Favicon = fav
rewriteTabRow() // TODO update browser tab label
return return
} }
@ -510,32 +507,3 @@ func handleURL(t *tab, u string, numRedirects int) (string, bool) {
go dlChoice("That file could not be displayed. What would you like to do?", u, res) go dlChoice("That file could not be displayed. What would you like to do?", u, res)
return ret("", false) return ret("", false)
} }
// rewriteTabRow clears the tabRow and writes all the tabs number/favicons into it.
func rewriteTabRow() {
tabRow.Clear()
if viper.GetBool("a-general.color") {
for i := 0; i < NumTabs(); i++ {
char := strconv.Itoa(i + 1)
if tabs[i].page.Favicon != "" {
char = tabs[i].page.Favicon
}
fmt.Fprintf(tabRow, `["%d"][%s] %s [%s][""]|`,
i,
config.GetColorString("tab_num"),
char,
config.GetColorString("tab_divider"),
)
}
} else {
for i := 0; i < NumTabs(); i++ {
char := strconv.Itoa(i + 1)
if tabs[i].page.Favicon != "" {
char = tabs[i].page.Favicon
}
fmt.Fprintf(tabRow, `["%d"] %s [""]|`, i, char)
}
}
tabRow.Highlight(strconv.Itoa(curTab)).ScrollToHighlight()
App.Draw()
}

View File

@ -36,19 +36,19 @@ type tab struct {
// makeNewTab initializes an tab struct with no content. // makeNewTab initializes an tab struct with no content.
func makeNewTab() *tab { func makeNewTab() *tab {
t := tab{ t := tab{
page: &structs.Page{Mode: structs.ModeOff}, page: &structs.Page{Mode: structs.ModeOff},
view: cview.NewTextView(). view: cview.NewTextView(),
SetDynamicColors(true).
SetRegions(true).
SetScrollable(true).
SetWrap(false).
SetChangedFunc(func() {
App.Draw()
}),
history: &tabHistory{}, history: &tabHistory{},
reformatMu: &sync.Mutex{}, reformatMu: &sync.Mutex{},
mode: tabModeDone, mode: tabModeDone,
} }
t.view.SetDynamicColors(true)
t.view.SetRegions(true)
t.view.SetScrollable(true)
t.view.SetWrap(false)
t.view.SetChangedFunc(func() {
App.Draw()
})
t.view.SetDoneFunc(func(key tcell.Key) { t.view.SetDoneFunc(func(key tcell.Key) {
// Altered from: https://gitlab.com/tslocum/cview/-/blob/master/demos/textview/main.go // Altered from: https://gitlab.com/tslocum/cview/-/blob/master/demos/textview/main.go
// Handles being able to select and "click" links with the enter and tab keys // Handles being able to select and "click" links with the enter and tab keys
@ -89,7 +89,8 @@ func makeNewTab() *tab {
// They've started link highlighting // They've started link highlighting
tabs[tab].page.Mode = structs.ModeLinkSelect tabs[tab].page.Mode = structs.ModeLinkSelect
tabs[tab].view.Highlight("0").ScrollToHighlight() tabs[tab].view.Highlight("0")
tabs[tab].view.ScrollToHighlight()
// Display link URL in bottomBar // Display link URL in bottomBar
bottomBar.SetLabel("[::b]Link: [::-]") bottomBar.SetLabel("[::b]Link: [::-]")
bottomBar.SetText(tabs[tab].page.Links[0]) bottomBar.SetText(tabs[tab].page.Links[0])
@ -109,7 +110,8 @@ func makeNewTab() *tab {
} else { } else {
return return
} }
tabs[tab].view.Highlight(strconv.Itoa(index)).ScrollToHighlight() tabs[tab].view.Highlight(strconv.Itoa(index))
tabs[tab].view.ScrollToHighlight()
// Display link URL in bottomBar // Display link URL in bottomBar
bottomBar.SetLabel("[::b]Link: [::-]") bottomBar.SetLabel("[::b]Link: [::-]")
bottomBar.SetText(tabs[tab].page.Links[index]) bottomBar.SetText(tabs[tab].page.Links[index])

19
go.mod
View File

@ -5,23 +5,26 @@ go 1.14
require ( require (
github.com/dustin/go-humanize v1.0.0 github.com/dustin/go-humanize v1.0.0
github.com/fsnotify/fsnotify v1.4.9 // indirect github.com/fsnotify/fsnotify v1.4.9 // indirect
github.com/gdamore/tcell/v2 v2.0.0-dev.0.20200926152101-0fb77ddaa5b4 github.com/gdamore/tcell/v2 v2.0.1-0.20201019142633-1057d5591ed1
github.com/google/go-cmp v0.5.0 // indirect github.com/google/go-cmp v0.5.0 // indirect
github.com/makeworld-the-better-one/go-gemini v0.8.4 github.com/magiconair/properties v1.8.4 // indirect
github.com/makeworld-the-better-one/go-gemini v0.9.0
github.com/makeworld-the-better-one/go-isemoji v1.1.0 github.com/makeworld-the-better-one/go-isemoji v1.1.0
github.com/makeworld-the-better-one/progressbar/v3 v3.3.5-0.20200710151429-125743e22b4f github.com/makeworld-the-better-one/progressbar/v3 v3.3.5-0.20200710151429-125743e22b4f
github.com/mitchellh/go-homedir v1.1.0 github.com/mitchellh/go-homedir v1.1.0
github.com/mitchellh/mapstructure v1.3.1 // indirect github.com/mitchellh/mapstructure v1.3.3 // indirect
github.com/pelletier/go-toml v1.8.0 // indirect github.com/pelletier/go-toml v1.8.1 // indirect
github.com/rkoesters/xdg v0.0.0-20181125232953-edd15b846f9b github.com/rkoesters/xdg v0.0.0-20181125232953-edd15b846f9b
github.com/spf13/afero v1.2.2 // indirect github.com/spf13/afero v1.4.1 // indirect
github.com/spf13/cast v1.3.1 // indirect github.com/spf13/cast v1.3.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.7.0 github.com/spf13/viper v1.7.1
github.com/stretchr/testify v1.6.1 github.com/stretchr/testify v1.6.1
gitlab.com/tslocum/cview v1.5.1-0.20201012001533-298510a6852b gitlab.com/tslocum/cview v1.5.1-0.20201026174147-36671ba7d31c
golang.org/x/sys v0.0.0-20201026173827-119d4633e4d1 // indirect
golang.org/x/text v0.3.3 golang.org/x/text v0.3.3
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
gopkg.in/ini.v1 v1.57.0 // indirect gopkg.in/ini.v1 v1.62.0 // indirect
gopkg.in/yaml.v2 v2.3.0 // indirect
) )

51
go.sum
View File

@ -45,8 +45,8 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4
github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko= github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg= github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
github.com/gdamore/tcell/v2 v2.0.0-dev/go.mod h1:vSVL/GV5mCSlPC6thFP5kfOFdM9MGZcalipmpTxTgQA= github.com/gdamore/tcell/v2 v2.0.0-dev/go.mod h1:vSVL/GV5mCSlPC6thFP5kfOFdM9MGZcalipmpTxTgQA=
github.com/gdamore/tcell/v2 v2.0.0-dev.0.20200926152101-0fb77ddaa5b4 h1:9WLVV5c2UI2qvgROlgzLgCuK5gi7igcU5LNsPXCSFB8= github.com/gdamore/tcell/v2 v2.0.1-0.20201019142633-1057d5591ed1 h1:gp9ujdOQmQf1gMvqOYYgxdMS5tRpRGE3HAgRH4Hgzd4=
github.com/gdamore/tcell/v2 v2.0.0-dev.0.20200926152101-0fb77ddaa5b4/go.mod h1:vSVL/GV5mCSlPC6thFP5kfOFdM9MGZcalipmpTxTgQA= github.com/gdamore/tcell/v2 v2.0.1-0.20201019142633-1057d5591ed1/go.mod h1:vSVL/GV5mCSlPC6thFP5kfOFdM9MGZcalipmpTxTgQA=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
@ -113,6 +113,7 @@ github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
@ -123,8 +124,10 @@ github.com/lucasb-eyer/go-colorful v1.0.3 h1:QIbQXiugsb+q10B+MI+7DI1oQLdmnep86tW
github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/makeworld-the-better-one/go-gemini v0.8.4 h1:ntsQ9HnlJCmC9PDqXp/f1SCALjBMwh69BbT4BhFRFaw= github.com/magiconair/properties v1.8.4 h1:8KGKTcQQGm0Kv7vEbKFErAoAOFyyacLStRtQSeYtvkY=
github.com/makeworld-the-better-one/go-gemini v0.8.4/go.mod h1:P7/FbZ+IEIbA/d+A0Y3w2GNgD8SA2AcNv7aDGJbaWG4= github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/makeworld-the-better-one/go-gemini v0.9.0 h1:Iz4ywRDrfsyoR8xZOkSKGXXftMR2spIV6ibVuhrKvSw=
github.com/makeworld-the-better-one/go-gemini v0.9.0/go.mod h1:P7/FbZ+IEIbA/d+A0Y3w2GNgD8SA2AcNv7aDGJbaWG4=
github.com/makeworld-the-better-one/go-isemoji v1.1.0 h1:wZBHOKB5zAIgaU2vaWnXFDDhatebB8TySrNVxjVV84g= github.com/makeworld-the-better-one/go-isemoji v1.1.0 h1:wZBHOKB5zAIgaU2vaWnXFDDhatebB8TySrNVxjVV84g=
github.com/makeworld-the-better-one/go-isemoji v1.1.0/go.mod h1:FBjkPl9rr0G4vlZCc+Mr+QcnOfGCTbGWYW8/1sp06I0= github.com/makeworld-the-better-one/go-isemoji v1.1.0/go.mod h1:FBjkPl9rr0G4vlZCc+Mr+QcnOfGCTbGWYW8/1sp06I0=
github.com/makeworld-the-better-one/progressbar/v3 v3.3.5-0.20200710151429-125743e22b4f h1:YEUlTs5gb35UlBLTgqrub9axWTYB3d7/8TxrkJDZpRI= github.com/makeworld-the-better-one/progressbar/v3 v3.3.5-0.20200710151429-125743e22b4f h1:YEUlTs5gb35UlBLTgqrub9axWTYB3d7/8TxrkJDZpRI=
@ -147,18 +150,19 @@ github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS4
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.3.1 h1:cCBH2gTD2K0OtLlv/Y5H01VQCqmlDxz30kS5Y5bqfLA= github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8=
github.com/mitchellh/mapstructure v1.3.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.8.0 h1:Keo9qb7iRJs2voHvunFtuuYFsbWeOBh8/P9v/kVMFtw= github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM=
github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs= github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
@ -187,8 +191,8 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.4.1 h1:asw9sl74539yqavKaglDM5hFpdJVK0Y5Dr/JOgQ89nQ=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.4.1/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
@ -198,23 +202,24 @@ github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.7.0 h1:xVKxvI7ouOI5I+U9s2eeiUfMaWBVoXA3AWskkrqK0VM= github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk=
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
gitlab.com/tslocum/cbind v0.1.2 h1:ptDjO7WeOl1HglprsK18L8I9JeRkmtuBoBBaYw/6/Ow= gitlab.com/tslocum/cbind v0.1.3 h1:FT/fTQ4Yj3eo5021lB3IbkIt8eVtYGhrw/xur+cjvUU=
gitlab.com/tslocum/cbind v0.1.2/go.mod h1:HfB7qAhHSZbn1rFK8M9SvSN5NG6ScAg/3h3iE6xdeeI= gitlab.com/tslocum/cbind v0.1.3/go.mod h1:RvwYE3auSjBNlCmWeGspzn+jdLUVQ8C2QGC+0nP9ChI=
gitlab.com/tslocum/cview v1.5.1-0.20201012001533-298510a6852b h1:wVXKnAE2gt165dbOupmxBIcjLW7ZTRGAtUUAhyNAEHs= gitlab.com/tslocum/cview v1.5.1-0.20201026174147-36671ba7d31c h1:yjyZ6CMJodKSylKTyIHbCsMNNuSE26hW7PMl6TWaM4M=
gitlab.com/tslocum/cview v1.5.1-0.20201012001533-298510a6852b/go.mod h1:i9NyxtwBtkiVFrwmsh3Bv3dunvipjZrKX0TTdPHbzcw= gitlab.com/tslocum/cview v1.5.1-0.20201026174147-36671ba7d31c/go.mod h1:IEfcfqcDG4Tm28XM+H8TEtbrqjpieAewfcJvQ9SgcRM=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= 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.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
@ -226,6 +231,7 @@ golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 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-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-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 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-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-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -281,9 +287,11 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201013132646-2da7054afaeb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= golang.org/x/sys v0.0.0-20201020230747-6e5568b54d1a h1:e3IU37lwO4aq3uoRKINC7JikojFmE5gO7xhfxs8VC34=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201020230747-6e5568b54d1a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201026173827-119d4633e4d1 h1:/DtoiOYKoQCcIFXQjz07RnWNPRCbqmSXSpgEzhC9ZHM=
golang.org/x/sys v0.0.0-20201026173827-119d4633e4d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/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.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.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
@ -339,11 +347,12 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogR
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.57.0 h1:9unxIsFcTt4I55uWluz+UmL95q4kdJ0buvQ1ZIqVQww= gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=