From cfb2cc057c32330be0ca0a68cfbd245cb2b8e31b Mon Sep 17 00:00:00 2001
From: Tulir Asokan <tulir@maunium.net>
Date: Wed, 5 Sep 2018 10:55:48 +0300
Subject: Update to latest gomatrix. Things are broken

---
 vendor/github.com/davecgh/go-spew/LICENSE          |   2 +-
 vendor/github.com/davecgh/go-spew/spew/bypass.go   | 187 ++++-----
 .../github.com/davecgh/go-spew/spew/bypasssafe.go  |   2 +-
 vendor/github.com/davecgh/go-spew/spew/common.go   |   2 +-
 vendor/github.com/davecgh/go-spew/spew/dump.go     |  10 +-
 vendor/github.com/davecgh/go-spew/spew/format.go   |   4 +-
 .../github.com/disintegration/imaging/effects.go   |  36 +-
 .../github.com/disintegration/imaging/helpers.go   | 272 ------------
 vendor/github.com/disintegration/imaging/io.go     | 463 +++++++++++++++++++++
 vendor/github.com/disintegration/imaging/tools.go  |  34 ++
 .../github.com/lucasb-eyer/go-colorful/README.md   |  33 +-
 .../github.com/lucasb-eyer/go-colorful/colors.go   |   7 +-
 vendor/github.com/mattn/go-runewidth/runewidth.go  |  14 +-
 vendor/github.com/renstrom/fuzzysearch/LICENSE     |   2 +-
 .../github.com/renstrom/fuzzysearch/fuzzy/fuzzy.go |   5 +-
 .../stretchr/testify/assert/assertion_format.go    | 139 ++++++-
 .../testify/assert/assertion_format.go.tmpl        |   1 +
 .../stretchr/testify/assert/assertion_forward.go   | 278 ++++++++++++-
 .../testify/assert/assertion_forward.go.tmpl       |   1 +
 .../stretchr/testify/assert/assertions.go          | 214 ++++++++--
 .../stretchr/testify/assert/http_assertions.go     |  22 +-
 vendor/github.com/zyedidia/clipboard/LICENSE       |   4 +
 vendor/github.com/zyedidia/clipboard/README.md     |   4 +
 vendor/golang.org/x/image/bmp/writer.go            | 122 +++++-
 vendor/golang.org/x/net/html/parse.go              | 103 ++---
 vendor/gopkg.in/toast.v1/toast.go                  |   5 +-
 vendor/maunium.net/go/gomatrix/client.go           | 145 +++++--
 vendor/maunium.net/go/gomatrix/events.go           | 455 ++++++++++++++++----
 vendor/maunium.net/go/gomatrix/reply.go            |  96 +++++
 vendor/maunium.net/go/gomatrix/requests.go         |   8 +-
 vendor/maunium.net/go/gomatrix/responses.go        |   2 +-
 vendor/maunium.net/go/gomatrix/room.go             |  20 +-
 vendor/maunium.net/go/gomatrix/sync.go             |  15 +-
 vendor/maunium.net/go/maulogger/LICENSE            |  21 +
 vendor/maunium.net/go/maulogger/README.md          |   6 +
 vendor/maunium.net/go/maulogger/logger.go          | 219 ++++++++++
 36 files changed, 2293 insertions(+), 660 deletions(-)
 delete mode 100644 vendor/github.com/disintegration/imaging/helpers.go
 create mode 100644 vendor/github.com/disintegration/imaging/io.go
 create mode 100644 vendor/maunium.net/go/gomatrix/reply.go
 create mode 100644 vendor/maunium.net/go/maulogger/LICENSE
 create mode 100644 vendor/maunium.net/go/maulogger/README.md
 create mode 100644 vendor/maunium.net/go/maulogger/logger.go

(limited to 'vendor')

diff --git a/vendor/github.com/davecgh/go-spew/LICENSE b/vendor/github.com/davecgh/go-spew/LICENSE
index c836416..bc52e96 100644
--- a/vendor/github.com/davecgh/go-spew/LICENSE
+++ b/vendor/github.com/davecgh/go-spew/LICENSE
@@ -2,7 +2,7 @@ ISC License
 
 Copyright (c) 2012-2016 Dave Collins <dave@davec.name>
 
-Permission to use, copy, modify, and distribute this software for any
+Permission to use, copy, modify, and/or distribute this software for any
 purpose with or without fee is hereby granted, provided that the above
 copyright notice and this permission notice appear in all copies.
 
diff --git a/vendor/github.com/davecgh/go-spew/spew/bypass.go b/vendor/github.com/davecgh/go-spew/spew/bypass.go
index 8a4a658..7929947 100644
--- a/vendor/github.com/davecgh/go-spew/spew/bypass.go
+++ b/vendor/github.com/davecgh/go-spew/spew/bypass.go
@@ -16,7 +16,9 @@
 // when the code is not running on Google App Engine, compiled by GopherJS, and
 // "-tags safe" is not added to the go build command line.  The "disableunsafe"
 // tag is deprecated and thus should not be used.
-// +build !js,!appengine,!safe,!disableunsafe
+// Go versions prior to 1.4 are disabled because they use a different layout
+// for interfaces which make the implementation of unsafeReflectValue more complex.
+// +build !js,!appengine,!safe,!disableunsafe,go1.4
 
 package spew
 
@@ -34,80 +36,49 @@ const (
 	ptrSize = unsafe.Sizeof((*byte)(nil))
 )
 
+type flag uintptr
+
 var (
-	// offsetPtr, offsetScalar, and offsetFlag are the offsets for the
-	// internal reflect.Value fields.  These values are valid before golang
-	// commit ecccf07e7f9d which changed the format.  The are also valid
-	// after commit 82f48826c6c7 which changed the format again to mirror
-	// the original format.  Code in the init function updates these offsets
-	// as necessary.
-	offsetPtr    = uintptr(ptrSize)
-	offsetScalar = uintptr(0)
-	offsetFlag   = uintptr(ptrSize * 2)
-
-	// flagKindWidth and flagKindShift indicate various bits that the
-	// reflect package uses internally to track kind information.
-	//
-	// flagRO indicates whether or not the value field of a reflect.Value is
-	// read-only.
-	//
-	// flagIndir indicates whether the value field of a reflect.Value is
-	// the actual data or a pointer to the data.
-	//
-	// These values are valid before golang commit 90a7c3c86944 which
-	// changed their positions.  Code in the init function updates these
-	// flags as necessary.
-	flagKindWidth = uintptr(5)
-	flagKindShift = uintptr(flagKindWidth - 1)
-	flagRO        = uintptr(1 << 0)
-	flagIndir     = uintptr(1 << 1)
+	// flagRO indicates whether the value field of a reflect.Value
+	// is read-only.
+	flagRO flag
+
+	// flagAddr indicates whether the address of the reflect.Value's
+	// value may be taken.
+	flagAddr flag
 )
 
-func init() {
-	// Older versions of reflect.Value stored small integers directly in the
-	// ptr field (which is named val in the older versions).  Versions
-	// between commits ecccf07e7f9d and 82f48826c6c7 added a new field named
-	// scalar for this purpose which unfortunately came before the flag
-	// field, so the offset of the flag field is different for those
-	// versions.
-	//
-	// This code constructs a new reflect.Value from a known small integer
-	// and checks if the size of the reflect.Value struct indicates it has
-	// the scalar field. When it does, the offsets are updated accordingly.
-	vv := reflect.ValueOf(0xf00)
-	if unsafe.Sizeof(vv) == (ptrSize * 4) {
-		offsetScalar = ptrSize * 2
-		offsetFlag = ptrSize * 3
-	}
+// flagKindMask holds the bits that make up the kind
+// part of the flags field. In all the supported versions,
+// it is in the lower 5 bits.
+const flagKindMask = flag(0x1f)
 
-	// Commit 90a7c3c86944 changed the flag positions such that the low
-	// order bits are the kind.  This code extracts the kind from the flags
-	// field and ensures it's the correct type.  When it's not, the flag
-	// order has been changed to the newer format, so the flags are updated
-	// accordingly.
-	upf := unsafe.Pointer(uintptr(unsafe.Pointer(&vv)) + offsetFlag)
-	upfv := *(*uintptr)(upf)
-	flagKindMask := uintptr((1<<flagKindWidth - 1) << flagKindShift)
-	if (upfv&flagKindMask)>>flagKindShift != uintptr(reflect.Int) {
-		flagKindShift = 0
-		flagRO = 1 << 5
-		flagIndir = 1 << 6
-
-		// Commit adf9b30e5594 modified the flags to separate the
-		// flagRO flag into two bits which specifies whether or not the
-		// field is embedded.  This causes flagIndir to move over a bit
-		// and means that flagRO is the combination of either of the
-		// original flagRO bit and the new bit.
-		//
-		// This code detects the change by extracting what used to be
-		// the indirect bit to ensure it's set.  When it's not, the flag
-		// order has been changed to the newer format, so the flags are
-		// updated accordingly.
-		if upfv&flagIndir == 0 {
-			flagRO = 3 << 5
-			flagIndir = 1 << 7
-		}
+// Different versions of Go have used different
+// bit layouts for the flags type. This table
+// records the known combinations.
+var okFlags = []struct {
+	ro, addr flag
+}{{
+	// From Go 1.4 to 1.5
+	ro:   1 << 5,
+	addr: 1 << 7,
+}, {
+	// Up to Go tip.
+	ro:   1<<5 | 1<<6,
+	addr: 1 << 8,
+}}
+
+var flagValOffset = func() uintptr {
+	field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag")
+	if !ok {
+		panic("reflect.Value has no flag field")
 	}
+	return field.Offset
+}()
+
+// flagField returns a pointer to the flag field of a reflect.Value.
+func flagField(v *reflect.Value) *flag {
+	return (*flag)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + flagValOffset))
 }
 
 // unsafeReflectValue converts the passed reflect.Value into a one that bypasses
@@ -119,34 +90,56 @@ func init() {
 // This allows us to check for implementations of the Stringer and error
 // interfaces to be used for pretty printing ordinarily unaddressable and
 // inaccessible values such as unexported struct fields.
-func unsafeReflectValue(v reflect.Value) (rv reflect.Value) {
-	indirects := 1
-	vt := v.Type()
-	upv := unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetPtr)
-	rvf := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetFlag))
-	if rvf&flagIndir != 0 {
-		vt = reflect.PtrTo(v.Type())
-		indirects++
-	} else if offsetScalar != 0 {
-		// The value is in the scalar field when it's not one of the
-		// reference types.
-		switch vt.Kind() {
-		case reflect.Uintptr:
-		case reflect.Chan:
-		case reflect.Func:
-		case reflect.Map:
-		case reflect.Ptr:
-		case reflect.UnsafePointer:
-		default:
-			upv = unsafe.Pointer(uintptr(unsafe.Pointer(&v)) +
-				offsetScalar)
-		}
+func unsafeReflectValue(v reflect.Value) reflect.Value {
+	if !v.IsValid() || (v.CanInterface() && v.CanAddr()) {
+		return v
 	}
+	flagFieldPtr := flagField(&v)
+	*flagFieldPtr &^= flagRO
+	*flagFieldPtr |= flagAddr
+	return v
+}
 
-	pv := reflect.NewAt(vt, upv)
-	rv = pv
-	for i := 0; i < indirects; i++ {
-		rv = rv.Elem()
+// Sanity checks against future reflect package changes
+// to the type or semantics of the Value.flag field.
+func init() {
+	field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag")
+	if !ok {
+		panic("reflect.Value has no flag field")
+	}
+	if field.Type.Kind() != reflect.TypeOf(flag(0)).Kind() {
+		panic("reflect.Value flag field has changed kind")
+	}
+	type t0 int
+	var t struct {
+		A t0
+		// t0 will have flagEmbedRO set.
+		t0
+		// a will have flagStickyRO set
+		a t0
+	}
+	vA := reflect.ValueOf(t).FieldByName("A")
+	va := reflect.ValueOf(t).FieldByName("a")
+	vt0 := reflect.ValueOf(t).FieldByName("t0")
+
+	// Infer flagRO from the difference between the flags
+	// for the (otherwise identical) fields in t.
+	flagPublic := *flagField(&vA)
+	flagWithRO := *flagField(&va) | *flagField(&vt0)
+	flagRO = flagPublic ^ flagWithRO
+
+	// Infer flagAddr from the difference between a value
+	// taken from a pointer and not.
+	vPtrA := reflect.ValueOf(&t).Elem().FieldByName("A")
+	flagNoPtr := *flagField(&vA)
+	flagPtr := *flagField(&vPtrA)
+	flagAddr = flagNoPtr ^ flagPtr
+
+	// Check that the inferred flags tally with one of the known versions.
+	for _, f := range okFlags {
+		if flagRO == f.ro && flagAddr == f.addr {
+			return
+		}
 	}
-	return rv
+	panic("reflect.Value read-only flag has changed semantics")
 }
diff --git a/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go b/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
index 1fe3cf3..205c28d 100644
--- a/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
+++ b/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
@@ -16,7 +16,7 @@
 // when the code is running on Google App Engine, compiled by GopherJS, or
 // "-tags safe" is added to the go build command line.  The "disableunsafe"
 // tag is deprecated and thus should not be used.
-// +build js appengine safe disableunsafe
+// +build js appengine safe disableunsafe !go1.4
 
 package spew
 
diff --git a/vendor/github.com/davecgh/go-spew/spew/common.go b/vendor/github.com/davecgh/go-spew/spew/common.go
index 7c519ff..1be8ce9 100644
--- a/vendor/github.com/davecgh/go-spew/spew/common.go
+++ b/vendor/github.com/davecgh/go-spew/spew/common.go
@@ -180,7 +180,7 @@ func printComplex(w io.Writer, c complex128, floatPrecision int) {
 	w.Write(closeParenBytes)
 }
 
-// printHexPtr outputs a uintptr formatted as hexidecimal with a leading '0x'
+// printHexPtr outputs a uintptr formatted as hexadecimal with a leading '0x'
 // prefix to Writer w.
 func printHexPtr(w io.Writer, p uintptr) {
 	// Null pointer.
diff --git a/vendor/github.com/davecgh/go-spew/spew/dump.go b/vendor/github.com/davecgh/go-spew/spew/dump.go
index df1d582..f78d89f 100644
--- a/vendor/github.com/davecgh/go-spew/spew/dump.go
+++ b/vendor/github.com/davecgh/go-spew/spew/dump.go
@@ -35,16 +35,16 @@ var (
 
 	// cCharRE is a regular expression that matches a cgo char.
 	// It is used to detect character arrays to hexdump them.
-	cCharRE = regexp.MustCompile("^.*\\._Ctype_char$")
+	cCharRE = regexp.MustCompile(`^.*\._Ctype_char$`)
 
 	// cUnsignedCharRE is a regular expression that matches a cgo unsigned
 	// char.  It is used to detect unsigned character arrays to hexdump
 	// them.
-	cUnsignedCharRE = regexp.MustCompile("^.*\\._Ctype_unsignedchar$")
+	cUnsignedCharRE = regexp.MustCompile(`^.*\._Ctype_unsignedchar$`)
 
 	// cUint8tCharRE is a regular expression that matches a cgo uint8_t.
 	// It is used to detect uint8_t arrays to hexdump them.
-	cUint8tCharRE = regexp.MustCompile("^.*\\._Ctype_uint8_t$")
+	cUint8tCharRE = regexp.MustCompile(`^.*\._Ctype_uint8_t$`)
 )
 
 // dumpState contains information about the state of a dump operation.
@@ -143,10 +143,10 @@ func (d *dumpState) dumpPtr(v reflect.Value) {
 	// Display dereferenced value.
 	d.w.Write(openParenBytes)
 	switch {
-	case nilFound == true:
+	case nilFound:
 		d.w.Write(nilAngleBytes)
 
-	case cycleFound == true:
+	case cycleFound:
 		d.w.Write(circularBytes)
 
 	default:
diff --git a/vendor/github.com/davecgh/go-spew/spew/format.go b/vendor/github.com/davecgh/go-spew/spew/format.go
index c49875b..b04edb7 100644
--- a/vendor/github.com/davecgh/go-spew/spew/format.go
+++ b/vendor/github.com/davecgh/go-spew/spew/format.go
@@ -182,10 +182,10 @@ func (f *formatState) formatPtr(v reflect.Value) {
 
 	// Display dereferenced value.
 	switch {
-	case nilFound == true:
+	case nilFound:
 		f.fs.Write(nilAngleBytes)
 
-	case cycleFound == true:
+	case cycleFound:
 		f.fs.Write(circularShortBytes)
 
 	default:
diff --git a/vendor/github.com/disintegration/imaging/effects.go b/vendor/github.com/disintegration/imaging/effects.go
index b16781f..149cfeb 100644
--- a/vendor/github.com/disintegration/imaging/effects.go
+++ b/vendor/github.com/disintegration/imaging/effects.go
@@ -38,9 +38,13 @@ func blurHorizontal(img image.Image, kernel []float64) *image.NRGBA {
 
 	parallel(0, src.h, func(ys <-chan int) {
 		scanLine := make([]uint8, src.w*4)
+		scanLineF := make([]float64, len(scanLine))
 		for y := range ys {
 			src.scan(0, y, src.w, y+1, scanLine)
-			for x := 0; x < src.w; x++ {
+			for i, v := range scanLine {
+				scanLineF[i] = float64(v)
+			}
+			for x, idx := 0, 0; x < src.w; x, idx = x+1, idx+4 {
 				min := x - radius
 				if min < 0 {
 					min = 0
@@ -55,10 +59,10 @@ func blurHorizontal(img image.Image, kernel []float64) *image.NRGBA {
 					i := ix * 4
 					weight := kernel[absint(x-ix)]
 					wsum += weight
-					wa := float64(scanLine[i+3]) * weight
-					r += float64(scanLine[i+0]) * wa
-					g += float64(scanLine[i+1]) * wa
-					b += float64(scanLine[i+2]) * wa
+					wa := scanLineF[i+3] * weight
+					r += scanLineF[i+0] * wa
+					g += scanLineF[i+1] * wa
+					b += scanLineF[i+2] * wa
 					a += wa
 				}
 				if a != 0 {
@@ -67,12 +71,12 @@ func blurHorizontal(img image.Image, kernel []float64) *image.NRGBA {
 					b /= a
 				}
 
-				j := y*dst.Stride + x*4
-				dst.Pix[j+0] = clamp(r)
-				dst.Pix[j+1] = clamp(g)
-				dst.Pix[j+2] = clamp(b)
-				dst.Pix[j+3] = clamp(a / wsum)
+				scanLine[idx+0] = clamp(r)
+				scanLine[idx+1] = clamp(g)
+				scanLine[idx+2] = clamp(b)
+				scanLine[idx+3] = clamp(a / wsum)
 			}
+			copy(dst.Pix[y*dst.Stride:], scanLine)
 		}
 	})
 
@@ -86,8 +90,12 @@ func blurVertical(img image.Image, kernel []float64) *image.NRGBA {
 
 	parallel(0, src.w, func(xs <-chan int) {
 		scanLine := make([]uint8, src.h*4)
+		scanLineF := make([]float64, len(scanLine))
 		for x := range xs {
 			src.scan(x, 0, x+1, src.h, scanLine)
+			for i, v := range scanLine {
+				scanLineF[i] = float64(v)
+			}
 			for y := 0; y < src.h; y++ {
 				min := y - radius
 				if min < 0 {
@@ -103,10 +111,10 @@ func blurVertical(img image.Image, kernel []float64) *image.NRGBA {
 					i := iy * 4
 					weight := kernel[absint(y-iy)]
 					wsum += weight
-					wa := float64(scanLine[i+3]) * weight
-					r += float64(scanLine[i+0]) * wa
-					g += float64(scanLine[i+1]) * wa
-					b += float64(scanLine[i+2]) * wa
+					wa := scanLineF[i+3] * weight
+					r += scanLineF[i+0] * wa
+					g += scanLineF[i+1] * wa
+					b += scanLineF[i+2] * wa
 					a += wa
 				}
 				if a != 0 {
diff --git a/vendor/github.com/disintegration/imaging/helpers.go b/vendor/github.com/disintegration/imaging/helpers.go
deleted file mode 100644
index dcb4d7e..0000000
--- a/vendor/github.com/disintegration/imaging/helpers.go
+++ /dev/null
@@ -1,272 +0,0 @@
-package imaging
-
-import (
-	"bytes"
-	"errors"
-	"image"
-	"image/color"
-	"image/draw"
-	"image/gif"
-	"image/jpeg"
-	"image/png"
-	"io"
-	"os"
-	"path/filepath"
-	"strings"
-
-	"golang.org/x/image/bmp"
-	"golang.org/x/image/tiff"
-)
-
-// Format is an image file format.
-type Format int
-
-// Image file formats.
-const (
-	JPEG Format = iota
-	PNG
-	GIF
-	TIFF
-	BMP
-)
-
-func (f Format) String() string {
-	switch f {
-	case JPEG:
-		return "JPEG"
-	case PNG:
-		return "PNG"
-	case GIF:
-		return "GIF"
-	case TIFF:
-		return "TIFF"
-	case BMP:
-		return "BMP"
-	default:
-		return "Unsupported"
-	}
-}
-
-var formatFromExt = map[string]Format{
-	".jpg":  JPEG,
-	".jpeg": JPEG,
-	".png":  PNG,
-	".tif":  TIFF,
-	".tiff": TIFF,
-	".bmp":  BMP,
-	".gif":  GIF,
-}
-
-// FormatFromFilename parses image format from filename extension:
-// "jpg" (or "jpeg"), "png", "gif", "tif" (or "tiff") and "bmp" are supported.
-func FormatFromFilename(filename string) (Format, error) {
-	ext := strings.ToLower(filepath.Ext(filename))
-	if f, ok := formatFromExt[ext]; ok {
-		return f, nil
-	}
-	return -1, ErrUnsupportedFormat
-}
-
-var (
-	// ErrUnsupportedFormat means the given image format (or file extension) is unsupported.
-	ErrUnsupportedFormat = errors.New("imaging: unsupported image format")
-)
-
-type fileSystem interface {
-	Create(string) (io.WriteCloser, error)
-	Open(string) (io.ReadCloser, error)
-}
-
-type localFS struct{}
-
-func (localFS) Create(name string) (io.WriteCloser, error) { return os.Create(name) }
-func (localFS) Open(name string) (io.ReadCloser, error)    { return os.Open(name) }
-
-var fs fileSystem = localFS{}
-
-// Decode reads an image from r.
-func Decode(r io.Reader) (image.Image, error) {
-	img, _, err := image.Decode(r)
-	return img, err
-}
-
-// Open loads an image from file
-func Open(filename string) (image.Image, error) {
-	file, err := fs.Open(filename)
-	if err != nil {
-		return nil, err
-	}
-	defer file.Close()
-	return Decode(file)
-}
-
-type encodeConfig struct {
-	jpegQuality         int
-	gifNumColors        int
-	gifQuantizer        draw.Quantizer
-	gifDrawer           draw.Drawer
-	pngCompressionLevel png.CompressionLevel
-}
-
-var defaultEncodeConfig = encodeConfig{
-	jpegQuality:         95,
-	gifNumColors:        256,
-	gifQuantizer:        nil,
-	gifDrawer:           nil,
-	pngCompressionLevel: png.DefaultCompression,
-}
-
-// EncodeOption sets an optional parameter for the Encode and Save functions.
-type EncodeOption func(*encodeConfig)
-
-// JPEGQuality returns an EncodeOption that sets the output JPEG quality.
-// Quality ranges from 1 to 100 inclusive, higher is better. Default is 95.
-func JPEGQuality(quality int) EncodeOption {
-	return func(c *encodeConfig) {
-		c.jpegQuality = quality
-	}
-}
-
-// GIFNumColors returns an EncodeOption that sets the maximum number of colors
-// used in the GIF-encoded image. It ranges from 1 to 256.  Default is 256.
-func GIFNumColors(numColors int) EncodeOption {
-	return func(c *encodeConfig) {
-		c.gifNumColors = numColors
-	}
-}
-
-// GIFQuantizer returns an EncodeOption that sets the quantizer that is used to produce
-// a palette of the GIF-encoded image.
-func GIFQuantizer(quantizer draw.Quantizer) EncodeOption {
-	return func(c *encodeConfig) {
-		c.gifQuantizer = quantizer
-	}
-}
-
-// GIFDrawer returns an EncodeOption that sets the drawer that is used to convert
-// the source image to the desired palette of the GIF-encoded image.
-func GIFDrawer(drawer draw.Drawer) EncodeOption {
-	return func(c *encodeConfig) {
-		c.gifDrawer = drawer
-	}
-}
-
-// PNGCompressionLevel returns an EncodeOption that sets the compression level
-// of the PNG-encoded image. Default is png.DefaultCompression.
-func PNGCompressionLevel(level png.CompressionLevel) EncodeOption {
-	return func(c *encodeConfig) {
-		c.pngCompressionLevel = level
-	}
-}
-
-// Encode writes the image img to w in the specified format (JPEG, PNG, GIF, TIFF or BMP).
-func Encode(w io.Writer, img image.Image, format Format, opts ...EncodeOption) error {
-	cfg := defaultEncodeConfig
-	for _, option := range opts {
-		option(&cfg)
-	}
-
-	var err error
-	switch format {
-	case JPEG:
-		var rgba *image.RGBA
-		if nrgba, ok := img.(*image.NRGBA); ok {
-			if nrgba.Opaque() {
-				rgba = &image.RGBA{
-					Pix:    nrgba.Pix,
-					Stride: nrgba.Stride,
-					Rect:   nrgba.Rect,
-				}
-			}
-		}
-		if rgba != nil {
-			err = jpeg.Encode(w, rgba, &jpeg.Options{Quality: cfg.jpegQuality})
-		} else {
-			err = jpeg.Encode(w, img, &jpeg.Options{Quality: cfg.jpegQuality})
-		}
-
-	case PNG:
-		enc := png.Encoder{CompressionLevel: cfg.pngCompressionLevel}
-		err = enc.Encode(w, img)
-
-	case GIF:
-		err = gif.Encode(w, img, &gif.Options{
-			NumColors: cfg.gifNumColors,
-			Quantizer: cfg.gifQuantizer,
-			Drawer:    cfg.gifDrawer,
-		})
-
-	case TIFF:
-		err = tiff.Encode(w, img, &tiff.Options{Compression: tiff.Deflate, Predictor: true})
-
-	case BMP:
-		err = bmp.Encode(w, img)
-
-	default:
-		err = ErrUnsupportedFormat
-	}
-	return err
-}
-
-// Save saves the image to file with the specified filename.
-// The format is determined from the filename extension: "jpg" (or "jpeg"), "png", "gif", "tif" (or "tiff") and "bmp" are supported.
-//
-// Examples:
-//
-//	// Save the image as PNG.
-//	err := imaging.Save(img, "out.png")
-//
-//	// Save the image as JPEG with optional quality parameter set to 80.
-//	err := imaging.Save(img, "out.jpg", imaging.JPEGQuality(80))
-//
-func Save(img image.Image, filename string, opts ...EncodeOption) (err error) {
-	f, err := FormatFromFilename(filename)
-	if err != nil {
-		return err
-	}
-	file, err := fs.Create(filename)
-	if err != nil {
-		return err
-	}
-
-	defer func() {
-		cerr := file.Close()
-		if err == nil {
-			err = cerr
-		}
-	}()
-
-	return Encode(file, img, f, opts...)
-}
-
-// New creates a new image with the specified width and height, and fills it with the specified color.
-func New(width, height int, fillColor color.Color) *image.NRGBA {
-	if width <= 0 || height <= 0 {
-		return &image.NRGBA{}
-	}
-
-	c := color.NRGBAModel.Convert(fillColor).(color.NRGBA)
-	if (c == color.NRGBA{0, 0, 0, 0}) {
-		return image.NewNRGBA(image.Rect(0, 0, width, height))
-	}
-
-	return &image.NRGBA{
-		Pix:    bytes.Repeat([]byte{c.R, c.G, c.B, c.A}, width*height),
-		Stride: 4 * width,
-		Rect:   image.Rect(0, 0, width, height),
-	}
-}
-
-// Clone returns a copy of the given image.
-func Clone(img image.Image) *image.NRGBA {
-	src := newScanner(img)
-	dst := image.NewNRGBA(image.Rect(0, 0, src.w, src.h))
-	size := src.w * 4
-	parallel(0, src.h, func(ys <-chan int) {
-		for y := range ys {
-			i := y * dst.Stride
-			src.scan(0, y, src.w, y+1, dst.Pix[i:i+size])
-		}
-	})
-	return dst
-}
diff --git a/vendor/github.com/disintegration/imaging/io.go b/vendor/github.com/disintegration/imaging/io.go
new file mode 100644
index 0000000..557bf2f
--- /dev/null
+++ b/vendor/github.com/disintegration/imaging/io.go
@@ -0,0 +1,463 @@
+package imaging
+
+import (
+	"encoding/binary"
+	"errors"
+	"image"
+	"image/draw"
+	"image/gif"
+	"image/jpeg"
+	"image/png"
+	"io"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"strings"
+
+	"golang.org/x/image/bmp"
+	"golang.org/x/image/tiff"
+)
+
+// Format is an image file format.
+type Format int
+
+// Image file formats.
+const (
+	JPEG Format = iota
+	PNG
+	GIF
+	TIFF
+	BMP
+)
+
+func (f Format) String() string {
+	switch f {
+	case JPEG:
+		return "JPEG"
+	case PNG:
+		return "PNG"
+	case GIF:
+		return "GIF"
+	case TIFF:
+		return "TIFF"
+	case BMP:
+		return "BMP"
+	default:
+		return "Unsupported"
+	}
+}
+
+var formatFromExt = map[string]Format{
+	"jpg":  JPEG,
+	"jpeg": JPEG,
+	"png":  PNG,
+	"tif":  TIFF,
+	"tiff": TIFF,
+	"bmp":  BMP,
+	"gif":  GIF,
+}
+
+// FormatFromExtension parses image format from extension:
+// "jpg" (or "jpeg"), "png", "gif", "tif" (or "tiff") and "bmp" are supported.
+func FormatFromExtension(ext string) (Format, error) {
+	if f, ok := formatFromExt[strings.ToLower(strings.TrimPrefix(ext, "."))]; ok {
+		return f, nil
+	}
+	return -1, ErrUnsupportedFormat
+}
+
+// FormatFromFilename parses image format from filename extension:
+// "jpg" (or "jpeg"), "png", "gif", "tif" (or "tiff") and "bmp" are supported.
+func FormatFromFilename(filename string) (Format, error) {
+	ext := filepath.Ext(filename)
+	return FormatFromExtension(ext)
+}
+
+var (
+	// ErrUnsupportedFormat means the given image format (or file extension) is unsupported.
+	ErrUnsupportedFormat = errors.New("imaging: unsupported image format")
+)
+
+type fileSystem interface {
+	Create(string) (io.WriteCloser, error)
+	Open(string) (io.ReadCloser, error)
+}
+
+type localFS struct{}
+
+func (localFS) Create(name string) (io.WriteCloser, error) { return os.Create(name) }
+func (localFS) Open(name string) (io.ReadCloser, error)    { return os.Open(name) }
+
+var fs fileSystem = localFS{}
+
+type decodeConfig struct {
+	autoOrientation bool
+}
+
+var defaultDecodeConfig = decodeConfig{
+	autoOrientation: false,
+}
+
+// DecodeOption sets an optional parameter for the Decode and Open functions.
+type DecodeOption func(*decodeConfig)
+
+// AutoOrientation returns a DecodeOption that sets the auto-orientation mode.
+// If auto-orientation is enabled, the image will be transformed after decoding
+// according to the EXIF orientation tag (if present). By default it's disabled.
+func AutoOrientation(enabled bool) DecodeOption {
+	return func(c *decodeConfig) {
+		c.autoOrientation = enabled
+	}
+}
+
+// Decode reads an image from r.
+func Decode(r io.Reader, opts ...DecodeOption) (image.Image, error) {
+	cfg := defaultDecodeConfig
+	for _, option := range opts {
+		option(&cfg)
+	}
+
+	if !cfg.autoOrientation {
+		img, _, err := image.Decode(r)
+		return img, err
+	}
+
+	var orient orientation
+	pr, pw := io.Pipe()
+	r = io.TeeReader(r, pw)
+	done := make(chan struct{})
+	go func() {
+		defer close(done)
+		orient = readOrientation(pr)
+		io.Copy(ioutil.Discard, pr)
+	}()
+
+	img, _, err := image.Decode(r)
+	pw.Close()
+	<-done
+	if err != nil {
+		return nil, err
+	}
+
+	return fixOrientation(img, orient), nil
+}
+
+// Open loads an image from file.
+//
+// Examples:
+//
+//	// Load an image from file.
+//	img, err := imaging.Open("test.jpg")
+//
+//	// Load an image and transform it depending on the EXIF orientation tag (if present).
+//	img, err := imaging.Open("test.jpg", imaging.AutoOrientation(true))
+//
+func Open(filename string, opts ...DecodeOption) (image.Image, error) {
+	file, err := fs.Open(filename)
+	if err != nil {
+		return nil, err
+	}
+	defer file.Close()
+	return Decode(file, opts...)
+}
+
+type encodeConfig struct {
+	jpegQuality         int
+	gifNumColors        int
+	gifQuantizer        draw.Quantizer
+	gifDrawer           draw.Drawer
+	pngCompressionLevel png.CompressionLevel
+}
+
+var defaultEncodeConfig = encodeConfig{
+	jpegQuality:         95,
+	gifNumColors:        256,
+	gifQuantizer:        nil,
+	gifDrawer:           nil,
+	pngCompressionLevel: png.DefaultCompression,
+}
+
+// EncodeOption sets an optional parameter for the Encode and Save functions.
+type EncodeOption func(*encodeConfig)
+
+// JPEGQuality returns an EncodeOption that sets the output JPEG quality.
+// Quality ranges from 1 to 100 inclusive, higher is better. Default is 95.
+func JPEGQuality(quality int) EncodeOption {
+	return func(c *encodeConfig) {
+		c.jpegQuality = quality
+	}
+}
+
+// GIFNumColors returns an EncodeOption that sets the maximum number of colors
+// used in the GIF-encoded image. It ranges from 1 to 256.  Default is 256.
+func GIFNumColors(numColors int) EncodeOption {
+	return func(c *encodeConfig) {
+		c.gifNumColors = numColors
+	}
+}
+
+// GIFQuantizer returns an EncodeOption that sets the quantizer that is used to produce
+// a palette of the GIF-encoded image.
+func GIFQuantizer(quantizer draw.Quantizer) EncodeOption {
+	return func(c *encodeConfig) {
+		c.gifQuantizer = quantizer
+	}
+}
+
+// GIFDrawer returns an EncodeOption that sets the drawer that is used to convert
+// the source image to the desired palette of the GIF-encoded image.
+func GIFDrawer(drawer draw.Drawer) EncodeOption {
+	return func(c *encodeConfig) {
+		c.gifDrawer = drawer
+	}
+}
+
+// PNGCompressionLevel returns an EncodeOption that sets the compression level
+// of the PNG-encoded image. Default is png.DefaultCompression.
+func PNGCompressionLevel(level png.CompressionLevel) EncodeOption {
+	return func(c *encodeConfig) {
+		c.pngCompressionLevel = level
+	}
+}
+
+// Encode writes the image img to w in the specified format (JPEG, PNG, GIF, TIFF or BMP).
+func Encode(w io.Writer, img image.Image, format Format, opts ...EncodeOption) error {
+	cfg := defaultEncodeConfig
+	for _, option := range opts {
+		option(&cfg)
+	}
+
+	var err error
+	switch format {
+	case JPEG:
+		var rgba *image.RGBA
+		if nrgba, ok := img.(*image.NRGBA); ok {
+			if nrgba.Opaque() {
+				rgba = &image.RGBA{
+					Pix:    nrgba.Pix,
+					Stride: nrgba.Stride,
+					Rect:   nrgba.Rect,
+				}
+			}
+		}
+		if rgba != nil {
+			err = jpeg.Encode(w, rgba, &jpeg.Options{Quality: cfg.jpegQuality})
+		} else {
+			err = jpeg.Encode(w, img, &jpeg.Options{Quality: cfg.jpegQuality})
+		}
+
+	case PNG:
+		enc := png.Encoder{CompressionLevel: cfg.pngCompressionLevel}
+		err = enc.Encode(w, img)
+
+	case GIF:
+		err = gif.Encode(w, img, &gif.Options{
+			NumColors: cfg.gifNumColors,
+			Quantizer: cfg.gifQuantizer,
+			Drawer:    cfg.gifDrawer,
+		})
+
+	case TIFF:
+		err = tiff.Encode(w, img, &tiff.Options{Compression: tiff.Deflate, Predictor: true})
+
+	case BMP:
+		err = bmp.Encode(w, img)
+
+	default:
+		err = ErrUnsupportedFormat
+	}
+	return err
+}
+
+// Save saves the image to file with the specified filename.
+// The format is determined from the filename extension:
+// "jpg" (or "jpeg"), "png", "gif", "tif" (or "tiff") and "bmp" are supported.
+//
+// Examples:
+//
+//	// Save the image as PNG.
+//	err := imaging.Save(img, "out.png")
+//
+//	// Save the image as JPEG with optional quality parameter set to 80.
+//	err := imaging.Save(img, "out.jpg", imaging.JPEGQuality(80))
+//
+func Save(img image.Image, filename string, opts ...EncodeOption) (err error) {
+	f, err := FormatFromFilename(filename)
+	if err != nil {
+		return err
+	}
+	file, err := fs.Create(filename)
+	if err != nil {
+		return err
+	}
+
+	defer func() {
+		cerr := file.Close()
+		if err == nil {
+			err = cerr
+		}
+	}()
+
+	return Encode(file, img, f, opts...)
+}
+
+// orientation is an EXIF flag that specifies the transformation
+// that should be applied to image to display it correctly.
+type orientation int
+
+const (
+	orientationUnspecified = 0
+	orientationNormal      = 1
+	orientationFlipH       = 2
+	orientationRotate180   = 3
+	orientationFlipV       = 4
+	orientationTranspose   = 5
+	orientationRotate270   = 6
+	orientationTransverse  = 7
+	orientationRotate90    = 8
+)
+
+// readOrientation tries to read the orientation EXIF flag from image data in r.
+// If the EXIF data block is not found or the orientation flag is not found
+// or any other error occures while reading the data, it returns the
+// orientationUnspecified (0) value.
+func readOrientation(r io.Reader) orientation {
+	const (
+		markerSOI      = 0xffd8
+		markerAPP1     = 0xffe1
+		exifHeader     = 0x45786966
+		byteOrderBE    = 0x4d4d
+		byteOrderLE    = 0x4949
+		orientationTag = 0x0112
+	)
+
+	// Check if JPEG SOI marker is present.
+	var soi uint16
+	if err := binary.Read(r, binary.BigEndian, &soi); err != nil {
+		return orientationUnspecified
+	}
+	if soi != markerSOI {
+		return orientationUnspecified // Missing JPEG SOI marker.
+	}
+
+	// Find JPEG APP1 marker.
+	for {
+		var marker, size uint16
+		if err := binary.Read(r, binary.BigEndian, &marker); err != nil {
+			return orientationUnspecified
+		}
+		if err := binary.Read(r, binary.BigEndian, &size); err != nil {
+			return orientationUnspecified
+		}
+		if marker>>8 != 0xff {
+			return orientationUnspecified // Invalid JPEG marker.
+		}
+		if marker == markerAPP1 {
+			break
+		}
+		if size < 2 {
+			return orientationUnspecified // Invalid block size.
+		}
+		if _, err := io.CopyN(ioutil.Discard, r, int64(size-2)); err != nil {
+			return orientationUnspecified
+		}
+	}
+
+	// Check if EXIF header is present.
+	var header uint32
+	if err := binary.Read(r, binary.BigEndian, &header); err != nil {
+		return orientationUnspecified
+	}
+	if header != exifHeader {
+		return orientationUnspecified
+	}
+	if _, err := io.CopyN(ioutil.Discard, r, 2); err != nil {
+		return orientationUnspecified
+	}
+
+	// Read byte order information.
+	var (
+		byteOrderTag uint16
+		byteOrder    binary.ByteOrder
+	)
+	if err := binary.Read(r, binary.BigEndian, &byteOrderTag); err != nil {
+		return orientationUnspecified
+	}
+	switch byteOrderTag {
+	case byteOrderBE:
+		byteOrder = binary.BigEndian
+	case byteOrderLE:
+		byteOrder = binary.LittleEndian
+	default:
+		return orientationUnspecified // Invalid byte order flag.
+	}
+	if _, err := io.CopyN(ioutil.Discard, r, 2); err != nil {
+		return orientationUnspecified
+	}
+
+	// Skip the EXIF offset.
+	var offset uint32
+	if err := binary.Read(r, byteOrder, &offset); err != nil {
+		return orientationUnspecified
+	}
+	if offset < 8 {
+		return orientationUnspecified // Invalid offset value.
+	}
+	if _, err := io.CopyN(ioutil.Discard, r, int64(offset-8)); err != nil {
+		return orientationUnspecified
+	}
+
+	// Read the number of tags.
+	var numTags uint16
+	if err := binary.Read(r, byteOrder, &numTags); err != nil {
+		return orientationUnspecified
+	}
+
+	// Find the orientation tag.
+	for i := 0; i < int(numTags); i++ {
+		var tag uint16
+		if err := binary.Read(r, byteOrder, &tag); err != nil {
+			return orientationUnspecified
+		}
+		if tag != orientationTag {
+			if _, err := io.CopyN(ioutil.Discard, r, 10); err != nil {
+				return orientationUnspecified
+			}
+			continue
+		}
+		if _, err := io.CopyN(ioutil.Discard, r, 6); err != nil {
+			return orientationUnspecified
+		}
+		var val uint16
+		if err := binary.Read(r, byteOrder, &val); err != nil {
+			return orientationUnspecified
+		}
+		if val < 1 || val > 8 {
+			return orientationUnspecified // Invalid tag value.
+		}
+		return orientation(val)
+	}
+	return orientationUnspecified // Missing orientation tag.
+}
+
+// fixOrientation applies a transform to img corresponding to the given orientation flag.
+func fixOrientation(img image.Image, o orientation) image.Image {
+	switch o {
+	case orientationNormal:
+	case orientationFlipH:
+		img = FlipH(img)
+	case orientationFlipV:
+		img = FlipV(img)
+	case orientationRotate90:
+		img = Rotate90(img)
+	case orientationRotate180:
+		img = Rotate180(img)
+	case orientationRotate270:
+		img = Rotate270(img)
+	case orientationTranspose:
+		img = Transpose(img)
+	case orientationTransverse:
+		img = Transverse(img)
+	}
+	return img
+}
diff --git a/vendor/github.com/disintegration/imaging/tools.go b/vendor/github.com/disintegration/imaging/tools.go
index fae1fa1..7887946 100644
--- a/vendor/github.com/disintegration/imaging/tools.go
+++ b/vendor/github.com/disintegration/imaging/tools.go
@@ -1,10 +1,44 @@
 package imaging
 
 import (
+	"bytes"
 	"image"
+	"image/color"
 	"math"
 )
 
+// New creates a new image with the specified width and height, and fills it with the specified color.
+func New(width, height int, fillColor color.Color) *image.NRGBA {
+	if width <= 0 || height <= 0 {
+		return &image.NRGBA{}
+	}
+
+	c := color.NRGBAModel.Convert(fillColor).(color.NRGBA)
+	if (c == color.NRGBA{0, 0, 0, 0}) {
+		return image.NewNRGBA(image.Rect(0, 0, width, height))
+	}
+
+	return &image.NRGBA{
+		Pix:    bytes.Repeat([]byte{c.R, c.G, c.B, c.A}, width*height),
+		Stride: 4 * width,
+		Rect:   image.Rect(0, 0, width, height),
+	}
+}
+
+// Clone returns a copy of the given image.
+func Clone(img image.Image) *image.NRGBA {
+	src := newScanner(img)
+	dst := image.NewNRGBA(image.Rect(0, 0, src.w, src.h))
+	size := src.w * 4
+	parallel(0, src.h, func(ys <-chan int) {
+		for y := range ys {
+			i := y * dst.Stride
+			src.scan(0, y, src.w, y+1, dst.Pix[i:i+size])
+		}
+	})
+	return dst
+}
+
 // Anchor is the anchor point for image alignment.
 type Anchor int
 
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/README.md b/vendor/github.com/lucasb-eyer/go-colorful/README.md
index c170435..8c89c38 100644
--- a/vendor/github.com/lucasb-eyer/go-colorful/README.md
+++ b/vendor/github.com/lucasb-eyer/go-colorful/README.md
@@ -124,17 +124,16 @@ Because a `colorful.Color` implements Go's `color.Color` interface (found in the
 `image/color` package), it can be used anywhere that expects a `color.Color`.
 
 Furthermore, you can convert anything that implements the `color.Color` interface
-into a `colorful.Color` using the `MakeColorful` function:
+into a `colorful.Color` using the `MakeColor` function:
 
 ```go
-c := colorful.MakeColor(color.Gray16{12345})
+c, ok := colorful.MakeColor(color.Gray16{12345})
 ```
 
-**Caveat:** Be aware that for this latter conversion  (using `MakeColor`) hits a corner-case
-when alpha is exactly zero. Because `color.Color` uses pre-multiplied alpha colors,
-this means the RGB values are lost and it's impossible to recover them. The current
-implementation `panic()`s in that case, see [issue 21](https://github.com/lucasb-eyer/go-colorful/issues/21)
-for discussion and suggesting alternatives.
+**Caveat:** Be aware that this latter conversion (using `MakeColor`) hits a
+corner-case when alpha is exactly zero. Because `color.Color` uses pre-multiplied
+alpha colors, this means the RGB values are lost (set to 0) and it's impossible
+to recover them. In such a case `MakeColor` will return `false` as its second value.
 
 ### Comparing colors
 In the RGB color space, the Euclidian distance between colors *doesn't* correspond
@@ -456,16 +455,26 @@ but that is outside the scope of this library.
 Thanks to [@ZirconiumX](https://github.com/ZirconiumX) for starting this investigation,
 see [issue #18](https://github.com/lucasb-eyer/go-colorful/issues/18) for details.
 
-### Q: `MakeColor` panics when alpha is zero!
-A: Because in that case, the conversion is undefined. See
-[issue 21](https://github.com/lucasb-eyer/go-colorful/issues/21)
-as well as the short caveat discussion in the ["The `color.Color` interface"](README.md#the-colorcolor-interface) section above.
+### Q: Why would `MakeColor` ever fail!?
+A: `MakeColor` fails when the alpha channel is zero. In that case, the
+conversion is undefined. See [issue 21](https://github.com/lucasb-eyer/go-colorful/issues/21)
+as well as the short caveat note in the ["The `color.Color` interface"](README.md#the-colorcolor-interface)
+section above.
 
 Who?
 ====
 
 This library has been developed by Lucas Beyer with contributions from
-Bastien Dejean (@baskerville) and Phil Kulak (@pkulak).
+Bastien Dejean (@baskerville), Phil Kulak (@pkulak) and Christian Muehlhaeuser (@muesli).
+
+Release Notes
+=============
+
+### Version 1.0
+- API Breaking change in `MakeColor`: instead of `panic`ing when alpha is zero, it now returns a secondary, boolean return value indicating success. See [the color.Color interface](https://github.com/lucasb-eyer/go-colorful#the-colorcolor-interface) section and [this FAQ entry](https://github.com/lucasb-eyer/go-colorful#q-why-would-makecolor-ever-fail) for details.
+
+### Version 0.9
+- Initial version number after having ignored versioning for a long time :)
 
 License: MIT
 ============
diff --git a/vendor/github.com/lucasb-eyer/go-colorful/colors.go b/vendor/github.com/lucasb-eyer/go-colorful/colors.go
index 7469cf7..febf94c 100644
--- a/vendor/github.com/lucasb-eyer/go-colorful/colors.go
+++ b/vendor/github.com/lucasb-eyer/go-colorful/colors.go
@@ -22,8 +22,11 @@ func (col Color) RGBA() (r, g, b, a uint32) {
 }
 
 // Constructs a colorful.Color from something implementing color.Color
-func MakeColor(col color.Color) Color {
+func MakeColor(col color.Color) (Color, bool) {
 	r, g, b, a := col.RGBA()
+	if a == 0 {
+		return Color{0, 0, 0}, false
+	}
 
 	// Since color.Color is alpha pre-multiplied, we need to divide the
 	// RGB values by alpha again in order to get back the original RGB.
@@ -34,7 +37,7 @@ func MakeColor(col color.Color) Color {
 	b *= 0xffff
 	b /= a
 
-	return Color{float64(r) / 65535.0, float64(g) / 65535.0, float64(b) / 65535.0}
+	return Color{float64(r) / 65535.0, float64(g) / 65535.0, float64(b) / 65535.0}, true
 }
 
 // Might come in handy sometimes to reduce boilerplate code.
diff --git a/vendor/github.com/mattn/go-runewidth/runewidth.go b/vendor/github.com/mattn/go-runewidth/runewidth.go
index 2164497..82568a1 100644
--- a/vendor/github.com/mattn/go-runewidth/runewidth.go
+++ b/vendor/github.com/mattn/go-runewidth/runewidth.go
@@ -1,13 +1,24 @@
 package runewidth
 
+import "os"
+
 var (
 	// EastAsianWidth will be set true if the current locale is CJK
-	EastAsianWidth = IsEastAsian()
+	EastAsianWidth bool
 
 	// DefaultCondition is a condition in current locale
 	DefaultCondition = &Condition{EastAsianWidth}
 )
 
+func init() {
+	env := os.Getenv("RUNEWIDTH_EASTASIAN")
+	if env == "" {
+		EastAsianWidth = IsEastAsian()
+	} else {
+		EastAsianWidth = env == "1"
+	}
+}
+
 type interval struct {
 	first rune
 	last  rune
@@ -55,6 +66,7 @@ var private = table{
 var nonprint = table{
 	{0x0000, 0x001F}, {0x007F, 0x009F}, {0x00AD, 0x00AD},
 	{0x070F, 0x070F}, {0x180B, 0x180E}, {0x200B, 0x200F},
+	{0x2028, 0x2029},
 	{0x202A, 0x202E}, {0x206A, 0x206F}, {0xD800, 0xDFFF},
 	{0xFEFF, 0xFEFF}, {0xFFF9, 0xFFFB}, {0xFFFE, 0xFFFF},
 }
diff --git a/vendor/github.com/renstrom/fuzzysearch/LICENSE b/vendor/github.com/renstrom/fuzzysearch/LICENSE
index 9cc7533..dee3d1d 100644
--- a/vendor/github.com/renstrom/fuzzysearch/LICENSE
+++ b/vendor/github.com/renstrom/fuzzysearch/LICENSE
@@ -1,6 +1,6 @@
 The MIT License (MIT)
 
-Copyright (c) 2015 Peter Renström
+Copyright (c) 2018 Peter Lithammer
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/vendor/github.com/renstrom/fuzzysearch/fuzzy/fuzzy.go b/vendor/github.com/renstrom/fuzzysearch/fuzzy/fuzzy.go
index 76b1c6e..33d4898 100644
--- a/vendor/github.com/renstrom/fuzzysearch/fuzzy/fuzzy.go
+++ b/vendor/github.com/renstrom/fuzzysearch/fuzzy/fuzzy.go
@@ -112,10 +112,7 @@ Outer:
 	}
 
 	// Count up remaining char
-	for len(target) > 0 {
-		target = target[utf8.RuneLen(rune(target[0])):]
-		runeDiff++
-	}
+	runeDiff += utf8.RuneCountInString(target)
 
 	return runeDiff
 }
diff --git a/vendor/github.com/stretchr/testify/assert/assertion_format.go b/vendor/github.com/stretchr/testify/assert/assertion_format.go
index ae06a54..aa1c2b9 100644
--- a/vendor/github.com/stretchr/testify/assert/assertion_format.go
+++ b/vendor/github.com/stretchr/testify/assert/assertion_format.go
@@ -13,6 +13,9 @@ import (
 
 // Conditionf uses a Comparison to assert a complex condition.
 func Conditionf(t TestingT, comp Comparison, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return Condition(t, comp, append([]interface{}{msg}, args...)...)
 }
 
@@ -23,11 +26,17 @@ func Conditionf(t TestingT, comp Comparison, msg string, args ...interface{}) bo
 //    assert.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted")
 //    assert.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted")
 func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return Contains(t, s, contains, append([]interface{}{msg}, args...)...)
 }
 
 // DirExistsf checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
 func DirExistsf(t TestingT, path string, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return DirExists(t, path, append([]interface{}{msg}, args...)...)
 }
 
@@ -37,6 +46,9 @@ func DirExistsf(t TestingT, path string, msg string, args ...interface{}) bool {
 //
 // assert.ElementsMatchf(t, [1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted")
 func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return ElementsMatch(t, listA, listB, append([]interface{}{msg}, args...)...)
 }
 
@@ -45,6 +57,9 @@ func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string
 //
 //  assert.Emptyf(t, obj, "error message %s", "formatted")
 func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return Empty(t, object, append([]interface{}{msg}, args...)...)
 }
 
@@ -56,6 +71,9 @@ func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) boo
 // referenced values (as opposed to the memory addresses). Function equality
 // cannot be determined and will always fail.
 func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return Equal(t, expected, actual, append([]interface{}{msg}, args...)...)
 }
 
@@ -65,6 +83,9 @@ func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, ar
 //   actualObj, err := SomeFunction()
 //   assert.EqualErrorf(t, err,  expectedErrorString, "error message %s", "formatted")
 func EqualErrorf(t TestingT, theError error, errString string, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return EqualError(t, theError, errString, append([]interface{}{msg}, args...)...)
 }
 
@@ -73,6 +94,9 @@ func EqualErrorf(t TestingT, theError error, errString string, msg string, args
 //
 //    assert.EqualValuesf(t, uint32(123, "error message %s", "formatted"), int32(123))
 func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return EqualValues(t, expected, actual, append([]interface{}{msg}, args...)...)
 }
 
@@ -83,6 +107,9 @@ func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg stri
 // 	   assert.Equal(t, expectedErrorf, err)
 //   }
 func Errorf(t TestingT, err error, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return Error(t, err, append([]interface{}{msg}, args...)...)
 }
 
@@ -90,16 +117,25 @@ func Errorf(t TestingT, err error, msg string, args ...interface{}) bool {
 //
 //    assert.Exactlyf(t, int32(123, "error message %s", "formatted"), int64(123))
 func Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return Exactly(t, expected, actual, append([]interface{}{msg}, args...)...)
 }
 
 // Failf reports a failure through
 func Failf(t TestingT, failureMessage string, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return Fail(t, failureMessage, append([]interface{}{msg}, args...)...)
 }
 
 // FailNowf fails test
 func FailNowf(t TestingT, failureMessage string, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return FailNow(t, failureMessage, append([]interface{}{msg}, args...)...)
 }
 
@@ -107,31 +143,43 @@ func FailNowf(t TestingT, failureMessage string, msg string, args ...interface{}
 //
 //    assert.Falsef(t, myBool, "error message %s", "formatted")
 func Falsef(t TestingT, value bool, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return False(t, value, append([]interface{}{msg}, args...)...)
 }
 
 // FileExistsf checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
 func FileExistsf(t TestingT, path string, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return FileExists(t, path, append([]interface{}{msg}, args...)...)
 }
 
 // HTTPBodyContainsf asserts that a specified handler returns a
 // body that contains a string.
 //
-//  assert.HTTPBodyContainsf(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
+//  assert.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
 //
 // Returns whether the assertion was successful (true) or not (false).
 func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return HTTPBodyContains(t, handler, method, url, values, str, append([]interface{}{msg}, args...)...)
 }
 
 // HTTPBodyNotContainsf asserts that a specified handler returns a
 // body that does not contain a string.
 //
-//  assert.HTTPBodyNotContainsf(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
+//  assert.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
 //
 // Returns whether the assertion was successful (true) or not (false).
 func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return HTTPBodyNotContains(t, handler, method, url, values, str, append([]interface{}{msg}, args...)...)
 }
 
@@ -141,6 +189,9 @@ func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, u
 //
 // Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
 func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return HTTPError(t, handler, method, url, values, append([]interface{}{msg}, args...)...)
 }
 
@@ -150,6 +201,9 @@ func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string,
 //
 // Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
 func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return HTTPRedirect(t, handler, method, url, values, append([]interface{}{msg}, args...)...)
 }
 
@@ -159,6 +213,9 @@ func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url stri
 //
 // Returns whether the assertion was successful (true) or not (false).
 func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return HTTPSuccess(t, handler, method, url, values, append([]interface{}{msg}, args...)...)
 }
 
@@ -166,6 +223,9 @@ func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url strin
 //
 //    assert.Implementsf(t, (*MyInterface, "error message %s", "formatted")(nil), new(MyObject))
 func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return Implements(t, interfaceObject, object, append([]interface{}{msg}, args...)...)
 }
 
@@ -173,31 +233,49 @@ func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, ms
 //
 // 	 assert.InDeltaf(t, math.Pi, (22 / 7.0, "error message %s", "formatted"), 0.01)
 func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return InDelta(t, expected, actual, delta, append([]interface{}{msg}, args...)...)
 }
 
 // InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
 func InDeltaMapValuesf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return InDeltaMapValues(t, expected, actual, delta, append([]interface{}{msg}, args...)...)
 }
 
 // InDeltaSlicef is the same as InDelta, except it compares two slices.
 func InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return InDeltaSlice(t, expected, actual, delta, append([]interface{}{msg}, args...)...)
 }
 
 // InEpsilonf asserts that expected and actual have a relative error less than epsilon
 func InEpsilonf(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return InEpsilon(t, expected, actual, epsilon, append([]interface{}{msg}, args...)...)
 }
 
 // InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices.
 func InEpsilonSlicef(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return InEpsilonSlice(t, expected, actual, epsilon, append([]interface{}{msg}, args...)...)
 }
 
 // IsTypef asserts that the specified objects are of the same type.
 func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return IsType(t, expectedType, object, append([]interface{}{msg}, args...)...)
 }
 
@@ -205,6 +283,9 @@ func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg strin
 //
 //  assert.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted")
 func JSONEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return JSONEq(t, expected, actual, append([]interface{}{msg}, args...)...)
 }
 
@@ -213,6 +294,9 @@ func JSONEqf(t TestingT, expected string, actual string, msg string, args ...int
 //
 //    assert.Lenf(t, mySlice, 3, "error message %s", "formatted")
 func Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return Len(t, object, length, append([]interface{}{msg}, args...)...)
 }
 
@@ -220,6 +304,9 @@ func Lenf(t TestingT, object interface{}, length int, msg string, args ...interf
 //
 //    assert.Nilf(t, err, "error message %s", "formatted")
 func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return Nil(t, object, append([]interface{}{msg}, args...)...)
 }
 
@@ -230,6 +317,9 @@ func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) bool
 // 	   assert.Equal(t, expectedObj, actualObj)
 //   }
 func NoErrorf(t TestingT, err error, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return NoError(t, err, append([]interface{}{msg}, args...)...)
 }
 
@@ -240,6 +330,9 @@ func NoErrorf(t TestingT, err error, msg string, args ...interface{}) bool {
 //    assert.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted")
 //    assert.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted")
 func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotContains(t, s, contains, append([]interface{}{msg}, args...)...)
 }
 
@@ -250,6 +343,9 @@ func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, a
 //    assert.Equal(t, "two", obj[1])
 //  }
 func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotEmpty(t, object, append([]interface{}{msg}, args...)...)
 }
 
@@ -260,6 +356,9 @@ func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{})
 // Pointer variable equality is determined based on the equality of the
 // referenced values (as opposed to the memory addresses).
 func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotEqual(t, expected, actual, append([]interface{}{msg}, args...)...)
 }
 
@@ -267,6 +366,9 @@ func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string,
 //
 //    assert.NotNilf(t, err, "error message %s", "formatted")
 func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotNil(t, object, append([]interface{}{msg}, args...)...)
 }
 
@@ -274,6 +376,9 @@ func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) bo
 //
 //   assert.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted")
 func NotPanicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotPanics(t, f, append([]interface{}{msg}, args...)...)
 }
 
@@ -282,6 +387,9 @@ func NotPanicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bo
 //  assert.NotRegexpf(t, regexp.MustCompile("starts", "error message %s", "formatted"), "it's starting")
 //  assert.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted")
 func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotRegexp(t, rx, str, append([]interface{}{msg}, args...)...)
 }
 
@@ -290,11 +398,17 @@ func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ..
 //
 //    assert.NotSubsetf(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted")
 func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotSubset(t, list, subset, append([]interface{}{msg}, args...)...)
 }
 
 // NotZerof asserts that i is not the zero value for its type.
 func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotZero(t, i, append([]interface{}{msg}, args...)...)
 }
 
@@ -302,6 +416,9 @@ func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) bool {
 //
 //   assert.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted")
 func Panicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return Panics(t, f, append([]interface{}{msg}, args...)...)
 }
 
@@ -310,6 +427,9 @@ func Panicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool
 //
 //   assert.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted")
 func PanicsWithValuef(t TestingT, expected interface{}, f PanicTestFunc, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return PanicsWithValue(t, expected, f, append([]interface{}{msg}, args...)...)
 }
 
@@ -318,6 +438,9 @@ func PanicsWithValuef(t TestingT, expected interface{}, f PanicTestFunc, msg str
 //  assert.Regexpf(t, regexp.MustCompile("start", "error message %s", "formatted"), "it's starting")
 //  assert.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted")
 func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return Regexp(t, rx, str, append([]interface{}{msg}, args...)...)
 }
 
@@ -326,6 +449,9 @@ func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...in
 //
 //    assert.Subsetf(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted")
 func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return Subset(t, list, subset, append([]interface{}{msg}, args...)...)
 }
 
@@ -333,6 +459,9 @@ func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args
 //
 //    assert.Truef(t, myBool, "error message %s", "formatted")
 func Truef(t TestingT, value bool, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return True(t, value, append([]interface{}{msg}, args...)...)
 }
 
@@ -340,10 +469,16 @@ func Truef(t TestingT, value bool, msg string, args ...interface{}) bool {
 //
 //   assert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted")
 func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return WithinDuration(t, expected, actual, delta, append([]interface{}{msg}, args...)...)
 }
 
 // Zerof asserts that i is the zero value for its type.
 func Zerof(t TestingT, i interface{}, msg string, args ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	return Zero(t, i, append([]interface{}{msg}, args...)...)
 }
diff --git a/vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl b/vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl
index c5cc66f..d2bb0b8 100644
--- a/vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl
+++ b/vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl
@@ -1,4 +1,5 @@
 {{.CommentFormat}}
 func {{.DocInfo.Name}}f(t TestingT, {{.ParamsFormat}}) bool {
+	if h, ok := t.(tHelper); ok { h.Helper() }
 	return {{.DocInfo.Name}}(t, {{.ForwardedParamsFormat}})
 }
diff --git a/vendor/github.com/stretchr/testify/assert/assertion_forward.go b/vendor/github.com/stretchr/testify/assert/assertion_forward.go
index ffa5428..de39f79 100644
--- a/vendor/github.com/stretchr/testify/assert/assertion_forward.go
+++ b/vendor/github.com/stretchr/testify/assert/assertion_forward.go
@@ -13,11 +13,17 @@ import (
 
 // Condition uses a Comparison to assert a complex condition.
 func (a *Assertions) Condition(comp Comparison, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Condition(a.t, comp, msgAndArgs...)
 }
 
 // Conditionf uses a Comparison to assert a complex condition.
 func (a *Assertions) Conditionf(comp Comparison, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Conditionf(a.t, comp, msg, args...)
 }
 
@@ -28,6 +34,9 @@ func (a *Assertions) Conditionf(comp Comparison, msg string, args ...interface{}
 //    a.Contains(["Hello", "World"], "World")
 //    a.Contains({"Hello": "World"}, "Hello")
 func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Contains(a.t, s, contains, msgAndArgs...)
 }
 
@@ -38,16 +47,25 @@ func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ..
 //    a.Containsf(["Hello", "World"], "World", "error message %s", "formatted")
 //    a.Containsf({"Hello": "World"}, "Hello", "error message %s", "formatted")
 func (a *Assertions) Containsf(s interface{}, contains interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Containsf(a.t, s, contains, msg, args...)
 }
 
 // DirExists checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
 func (a *Assertions) DirExists(path string, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return DirExists(a.t, path, msgAndArgs...)
 }
 
 // DirExistsf checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
 func (a *Assertions) DirExistsf(path string, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return DirExistsf(a.t, path, msg, args...)
 }
 
@@ -57,6 +75,9 @@ func (a *Assertions) DirExistsf(path string, msg string, args ...interface{}) bo
 //
 // a.ElementsMatch([1, 3, 2, 3], [1, 3, 3, 2])
 func (a *Assertions) ElementsMatch(listA interface{}, listB interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return ElementsMatch(a.t, listA, listB, msgAndArgs...)
 }
 
@@ -66,6 +87,9 @@ func (a *Assertions) ElementsMatch(listA interface{}, listB interface{}, msgAndA
 //
 // a.ElementsMatchf([1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted")
 func (a *Assertions) ElementsMatchf(listA interface{}, listB interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return ElementsMatchf(a.t, listA, listB, msg, args...)
 }
 
@@ -74,6 +98,9 @@ func (a *Assertions) ElementsMatchf(listA interface{}, listB interface{}, msg st
 //
 //  a.Empty(obj)
 func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Empty(a.t, object, msgAndArgs...)
 }
 
@@ -82,6 +109,9 @@ func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool {
 //
 //  a.Emptyf(obj, "error message %s", "formatted")
 func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Emptyf(a.t, object, msg, args...)
 }
 
@@ -93,6 +123,9 @@ func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{})
 // referenced values (as opposed to the memory addresses). Function equality
 // cannot be determined and will always fail.
 func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Equal(a.t, expected, actual, msgAndArgs...)
 }
 
@@ -102,6 +135,9 @@ func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs
 //   actualObj, err := SomeFunction()
 //   a.EqualError(err,  expectedErrorString)
 func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return EqualError(a.t, theError, errString, msgAndArgs...)
 }
 
@@ -111,6 +147,9 @@ func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...
 //   actualObj, err := SomeFunction()
 //   a.EqualErrorf(err,  expectedErrorString, "error message %s", "formatted")
 func (a *Assertions) EqualErrorf(theError error, errString string, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return EqualErrorf(a.t, theError, errString, msg, args...)
 }
 
@@ -119,6 +158,9 @@ func (a *Assertions) EqualErrorf(theError error, errString string, msg string, a
 //
 //    a.EqualValues(uint32(123), int32(123))
 func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return EqualValues(a.t, expected, actual, msgAndArgs...)
 }
 
@@ -127,6 +169,9 @@ func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAn
 //
 //    a.EqualValuesf(uint32(123, "error message %s", "formatted"), int32(123))
 func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return EqualValuesf(a.t, expected, actual, msg, args...)
 }
 
@@ -138,6 +183,9 @@ func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg
 // referenced values (as opposed to the memory addresses). Function equality
 // cannot be determined and will always fail.
 func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Equalf(a.t, expected, actual, msg, args...)
 }
 
@@ -148,6 +196,9 @@ func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string
 // 	   assert.Equal(t, expectedError, err)
 //   }
 func (a *Assertions) Error(err error, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Error(a.t, err, msgAndArgs...)
 }
 
@@ -158,6 +209,9 @@ func (a *Assertions) Error(err error, msgAndArgs ...interface{}) bool {
 // 	   assert.Equal(t, expectedErrorf, err)
 //   }
 func (a *Assertions) Errorf(err error, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Errorf(a.t, err, msg, args...)
 }
 
@@ -165,6 +219,9 @@ func (a *Assertions) Errorf(err error, msg string, args ...interface{}) bool {
 //
 //    a.Exactly(int32(123), int64(123))
 func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Exactly(a.t, expected, actual, msgAndArgs...)
 }
 
@@ -172,26 +229,41 @@ func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArg
 //
 //    a.Exactlyf(int32(123, "error message %s", "formatted"), int64(123))
 func (a *Assertions) Exactlyf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Exactlyf(a.t, expected, actual, msg, args...)
 }
 
 // Fail reports a failure through
 func (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Fail(a.t, failureMessage, msgAndArgs...)
 }
 
 // FailNow fails test
 func (a *Assertions) FailNow(failureMessage string, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return FailNow(a.t, failureMessage, msgAndArgs...)
 }
 
 // FailNowf fails test
 func (a *Assertions) FailNowf(failureMessage string, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return FailNowf(a.t, failureMessage, msg, args...)
 }
 
 // Failf reports a failure through
 func (a *Assertions) Failf(failureMessage string, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Failf(a.t, failureMessage, msg, args...)
 }
 
@@ -199,6 +271,9 @@ func (a *Assertions) Failf(failureMessage string, msg string, args ...interface{
 //
 //    a.False(myBool)
 func (a *Assertions) False(value bool, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return False(a.t, value, msgAndArgs...)
 }
 
@@ -206,56 +281,77 @@ func (a *Assertions) False(value bool, msgAndArgs ...interface{}) bool {
 //
 //    a.Falsef(myBool, "error message %s", "formatted")
 func (a *Assertions) Falsef(value bool, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Falsef(a.t, value, msg, args...)
 }
 
 // FileExists checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
 func (a *Assertions) FileExists(path string, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return FileExists(a.t, path, msgAndArgs...)
 }
 
 // FileExistsf checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
 func (a *Assertions) FileExistsf(path string, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return FileExistsf(a.t, path, msg, args...)
 }
 
 // HTTPBodyContains asserts that a specified handler returns a
 // body that contains a string.
 //
-//  a.HTTPBodyContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky")
+//  a.HTTPBodyContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky")
 //
 // Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return HTTPBodyContains(a.t, handler, method, url, values, str, msgAndArgs...)
 }
 
 // HTTPBodyContainsf asserts that a specified handler returns a
 // body that contains a string.
 //
-//  a.HTTPBodyContainsf(myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
+//  a.HTTPBodyContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
 //
 // Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return HTTPBodyContainsf(a.t, handler, method, url, values, str, msg, args...)
 }
 
 // HTTPBodyNotContains asserts that a specified handler returns a
 // body that does not contain a string.
 //
-//  a.HTTPBodyNotContains(myHandler, "www.google.com", nil, "I'm Feeling Lucky")
+//  a.HTTPBodyNotContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky")
 //
 // Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return HTTPBodyNotContains(a.t, handler, method, url, values, str, msgAndArgs...)
 }
 
 // HTTPBodyNotContainsf asserts that a specified handler returns a
 // body that does not contain a string.
 //
-//  a.HTTPBodyNotContainsf(myHandler, "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
+//  a.HTTPBodyNotContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted")
 //
 // Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return HTTPBodyNotContainsf(a.t, handler, method, url, values, str, msg, args...)
 }
 
@@ -265,6 +361,9 @@ func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method strin
 //
 // Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return HTTPError(a.t, handler, method, url, values, msgAndArgs...)
 }
 
@@ -274,6 +373,9 @@ func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url stri
 //
 // Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
 func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return HTTPErrorf(a.t, handler, method, url, values, msg, args...)
 }
 
@@ -283,6 +385,9 @@ func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url str
 //
 // Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return HTTPRedirect(a.t, handler, method, url, values, msgAndArgs...)
 }
 
@@ -292,6 +397,9 @@ func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url s
 //
 // Returns whether the assertion was successful (true, "error message %s", "formatted") or not (false).
 func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return HTTPRedirectf(a.t, handler, method, url, values, msg, args...)
 }
 
@@ -301,6 +409,9 @@ func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url
 //
 // Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return HTTPSuccess(a.t, handler, method, url, values, msgAndArgs...)
 }
 
@@ -310,6 +421,9 @@ func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url st
 //
 // Returns whether the assertion was successful (true) or not (false).
 func (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return HTTPSuccessf(a.t, handler, method, url, values, msg, args...)
 }
 
@@ -317,6 +431,9 @@ func (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url s
 //
 //    a.Implements((*MyInterface)(nil), new(MyObject))
 func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Implements(a.t, interfaceObject, object, msgAndArgs...)
 }
 
@@ -324,6 +441,9 @@ func (a *Assertions) Implements(interfaceObject interface{}, object interface{},
 //
 //    a.Implementsf((*MyInterface, "error message %s", "formatted")(nil), new(MyObject))
 func (a *Assertions) Implementsf(interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Implementsf(a.t, interfaceObject, object, msg, args...)
 }
 
@@ -331,26 +451,41 @@ func (a *Assertions) Implementsf(interfaceObject interface{}, object interface{}
 //
 // 	 a.InDelta(math.Pi, (22 / 7.0), 0.01)
 func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return InDelta(a.t, expected, actual, delta, msgAndArgs...)
 }
 
 // InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
 func (a *Assertions) InDeltaMapValues(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return InDeltaMapValues(a.t, expected, actual, delta, msgAndArgs...)
 }
 
 // InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
 func (a *Assertions) InDeltaMapValuesf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return InDeltaMapValuesf(a.t, expected, actual, delta, msg, args...)
 }
 
 // InDeltaSlice is the same as InDelta, except it compares two slices.
 func (a *Assertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return InDeltaSlice(a.t, expected, actual, delta, msgAndArgs...)
 }
 
 // InDeltaSlicef is the same as InDelta, except it compares two slices.
 func (a *Assertions) InDeltaSlicef(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return InDeltaSlicef(a.t, expected, actual, delta, msg, args...)
 }
 
@@ -358,36 +493,57 @@ func (a *Assertions) InDeltaSlicef(expected interface{}, actual interface{}, del
 //
 // 	 a.InDeltaf(math.Pi, (22 / 7.0, "error message %s", "formatted"), 0.01)
 func (a *Assertions) InDeltaf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return InDeltaf(a.t, expected, actual, delta, msg, args...)
 }
 
 // InEpsilon asserts that expected and actual have a relative error less than epsilon
 func (a *Assertions) InEpsilon(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return InEpsilon(a.t, expected, actual, epsilon, msgAndArgs...)
 }
 
 // InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices.
 func (a *Assertions) InEpsilonSlice(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return InEpsilonSlice(a.t, expected, actual, epsilon, msgAndArgs...)
 }
 
 // InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices.
 func (a *Assertions) InEpsilonSlicef(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return InEpsilonSlicef(a.t, expected, actual, epsilon, msg, args...)
 }
 
 // InEpsilonf asserts that expected and actual have a relative error less than epsilon
 func (a *Assertions) InEpsilonf(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return InEpsilonf(a.t, expected, actual, epsilon, msg, args...)
 }
 
 // IsType asserts that the specified objects are of the same type.
 func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return IsType(a.t, expectedType, object, msgAndArgs...)
 }
 
 // IsTypef asserts that the specified objects are of the same type.
 func (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return IsTypef(a.t, expectedType, object, msg, args...)
 }
 
@@ -395,6 +551,9 @@ func (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg s
 //
 //  a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
 func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return JSONEq(a.t, expected, actual, msgAndArgs...)
 }
 
@@ -402,6 +561,9 @@ func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interf
 //
 //  a.JSONEqf(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted")
 func (a *Assertions) JSONEqf(expected string, actual string, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return JSONEqf(a.t, expected, actual, msg, args...)
 }
 
@@ -410,6 +572,9 @@ func (a *Assertions) JSONEqf(expected string, actual string, msg string, args ..
 //
 //    a.Len(mySlice, 3)
 func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Len(a.t, object, length, msgAndArgs...)
 }
 
@@ -418,6 +583,9 @@ func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface
 //
 //    a.Lenf(mySlice, 3, "error message %s", "formatted")
 func (a *Assertions) Lenf(object interface{}, length int, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Lenf(a.t, object, length, msg, args...)
 }
 
@@ -425,6 +593,9 @@ func (a *Assertions) Lenf(object interface{}, length int, msg string, args ...in
 //
 //    a.Nil(err)
 func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Nil(a.t, object, msgAndArgs...)
 }
 
@@ -432,6 +603,9 @@ func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool {
 //
 //    a.Nilf(err, "error message %s", "formatted")
 func (a *Assertions) Nilf(object interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Nilf(a.t, object, msg, args...)
 }
 
@@ -442,6 +616,9 @@ func (a *Assertions) Nilf(object interface{}, msg string, args ...interface{}) b
 // 	   assert.Equal(t, expectedObj, actualObj)
 //   }
 func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NoError(a.t, err, msgAndArgs...)
 }
 
@@ -452,6 +629,9 @@ func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool {
 // 	   assert.Equal(t, expectedObj, actualObj)
 //   }
 func (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NoErrorf(a.t, err, msg, args...)
 }
 
@@ -462,6 +642,9 @@ func (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) bool {
 //    a.NotContains(["Hello", "World"], "Earth")
 //    a.NotContains({"Hello": "World"}, "Earth")
 func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotContains(a.t, s, contains, msgAndArgs...)
 }
 
@@ -472,6 +655,9 @@ func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs
 //    a.NotContainsf(["Hello", "World"], "Earth", "error message %s", "formatted")
 //    a.NotContainsf({"Hello": "World"}, "Earth", "error message %s", "formatted")
 func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotContainsf(a.t, s, contains, msg, args...)
 }
 
@@ -482,6 +668,9 @@ func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg strin
 //    assert.Equal(t, "two", obj[1])
 //  }
 func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotEmpty(a.t, object, msgAndArgs...)
 }
 
@@ -492,6 +681,9 @@ func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) boo
 //    assert.Equal(t, "two", obj[1])
 //  }
 func (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotEmptyf(a.t, object, msg, args...)
 }
 
@@ -502,6 +694,9 @@ func (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface
 // Pointer variable equality is determined based on the equality of the
 // referenced values (as opposed to the memory addresses).
 func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotEqual(a.t, expected, actual, msgAndArgs...)
 }
 
@@ -512,6 +707,9 @@ func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndAr
 // Pointer variable equality is determined based on the equality of the
 // referenced values (as opposed to the memory addresses).
 func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotEqualf(a.t, expected, actual, msg, args...)
 }
 
@@ -519,6 +717,9 @@ func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg str
 //
 //    a.NotNil(err)
 func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotNil(a.t, object, msgAndArgs...)
 }
 
@@ -526,6 +727,9 @@ func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool
 //
 //    a.NotNilf(err, "error message %s", "formatted")
 func (a *Assertions) NotNilf(object interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotNilf(a.t, object, msg, args...)
 }
 
@@ -533,6 +737,9 @@ func (a *Assertions) NotNilf(object interface{}, msg string, args ...interface{}
 //
 //   a.NotPanics(func(){ RemainCalm() })
 func (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotPanics(a.t, f, msgAndArgs...)
 }
 
@@ -540,6 +747,9 @@ func (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) bool
 //
 //   a.NotPanicsf(func(){ RemainCalm() }, "error message %s", "formatted")
 func (a *Assertions) NotPanicsf(f PanicTestFunc, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotPanicsf(a.t, f, msg, args...)
 }
 
@@ -548,6 +758,9 @@ func (a *Assertions) NotPanicsf(f PanicTestFunc, msg string, args ...interface{}
 //  a.NotRegexp(regexp.MustCompile("starts"), "it's starting")
 //  a.NotRegexp("^start", "it's not starting")
 func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotRegexp(a.t, rx, str, msgAndArgs...)
 }
 
@@ -556,6 +769,9 @@ func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...in
 //  a.NotRegexpf(regexp.MustCompile("starts", "error message %s", "formatted"), "it's starting")
 //  a.NotRegexpf("^start", "it's not starting", "error message %s", "formatted")
 func (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotRegexpf(a.t, rx, str, msg, args...)
 }
 
@@ -564,6 +780,9 @@ func (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, arg
 //
 //    a.NotSubset([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]")
 func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotSubset(a.t, list, subset, msgAndArgs...)
 }
 
@@ -572,16 +791,25 @@ func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs
 //
 //    a.NotSubsetf([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted")
 func (a *Assertions) NotSubsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotSubsetf(a.t, list, subset, msg, args...)
 }
 
 // NotZero asserts that i is not the zero value for its type.
 func (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotZero(a.t, i, msgAndArgs...)
 }
 
 // NotZerof asserts that i is not the zero value for its type.
 func (a *Assertions) NotZerof(i interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return NotZerof(a.t, i, msg, args...)
 }
 
@@ -589,6 +817,9 @@ func (a *Assertions) NotZerof(i interface{}, msg string, args ...interface{}) bo
 //
 //   a.Panics(func(){ GoCrazy() })
 func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Panics(a.t, f, msgAndArgs...)
 }
 
@@ -597,6 +828,9 @@ func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool {
 //
 //   a.PanicsWithValue("crazy error", func(){ GoCrazy() })
 func (a *Assertions) PanicsWithValue(expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return PanicsWithValue(a.t, expected, f, msgAndArgs...)
 }
 
@@ -605,6 +839,9 @@ func (a *Assertions) PanicsWithValue(expected interface{}, f PanicTestFunc, msgA
 //
 //   a.PanicsWithValuef("crazy error", func(){ GoCrazy() }, "error message %s", "formatted")
 func (a *Assertions) PanicsWithValuef(expected interface{}, f PanicTestFunc, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return PanicsWithValuef(a.t, expected, f, msg, args...)
 }
 
@@ -612,6 +849,9 @@ func (a *Assertions) PanicsWithValuef(expected interface{}, f PanicTestFunc, msg
 //
 //   a.Panicsf(func(){ GoCrazy() }, "error message %s", "formatted")
 func (a *Assertions) Panicsf(f PanicTestFunc, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Panicsf(a.t, f, msg, args...)
 }
 
@@ -620,6 +860,9 @@ func (a *Assertions) Panicsf(f PanicTestFunc, msg string, args ...interface{}) b
 //  a.Regexp(regexp.MustCompile("start"), "it's starting")
 //  a.Regexp("start...$", "it's not starting")
 func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Regexp(a.t, rx, str, msgAndArgs...)
 }
 
@@ -628,6 +871,9 @@ func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...inter
 //  a.Regexpf(regexp.MustCompile("start", "error message %s", "formatted"), "it's starting")
 //  a.Regexpf("start...$", "it's not starting", "error message %s", "formatted")
 func (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Regexpf(a.t, rx, str, msg, args...)
 }
 
@@ -636,6 +882,9 @@ func (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args .
 //
 //    a.Subset([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]")
 func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Subset(a.t, list, subset, msgAndArgs...)
 }
 
@@ -644,6 +893,9 @@ func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...
 //
 //    a.Subsetf([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted")
 func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Subsetf(a.t, list, subset, msg, args...)
 }
 
@@ -651,6 +903,9 @@ func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, a
 //
 //    a.True(myBool)
 func (a *Assertions) True(value bool, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return True(a.t, value, msgAndArgs...)
 }
 
@@ -658,6 +913,9 @@ func (a *Assertions) True(value bool, msgAndArgs ...interface{}) bool {
 //
 //    a.Truef(myBool, "error message %s", "formatted")
 func (a *Assertions) Truef(value bool, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Truef(a.t, value, msg, args...)
 }
 
@@ -665,6 +923,9 @@ func (a *Assertions) Truef(value bool, msg string, args ...interface{}) bool {
 //
 //   a.WithinDuration(time.Now(), time.Now(), 10*time.Second)
 func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return WithinDuration(a.t, expected, actual, delta, msgAndArgs...)
 }
 
@@ -672,15 +933,24 @@ func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta
 //
 //   a.WithinDurationf(time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted")
 func (a *Assertions) WithinDurationf(expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return WithinDurationf(a.t, expected, actual, delta, msg, args...)
 }
 
 // Zero asserts that i is the zero value for its type.
 func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Zero(a.t, i, msgAndArgs...)
 }
 
 // Zerof asserts that i is the zero value for its type.
 func (a *Assertions) Zerof(i interface{}, msg string, args ...interface{}) bool {
+	if h, ok := a.t.(tHelper); ok {
+		h.Helper()
+	}
 	return Zerof(a.t, i, msg, args...)
 }
diff --git a/vendor/github.com/stretchr/testify/assert/assertion_forward.go.tmpl b/vendor/github.com/stretchr/testify/assert/assertion_forward.go.tmpl
index 99f9acf..188bb9e 100644
--- a/vendor/github.com/stretchr/testify/assert/assertion_forward.go.tmpl
+++ b/vendor/github.com/stretchr/testify/assert/assertion_forward.go.tmpl
@@ -1,4 +1,5 @@
 {{.CommentWithoutT "a"}}
 func (a *Assertions) {{.DocInfo.Name}}({{.Params}}) bool {
+	if h, ok := a.t.(tHelper); ok { h.Helper() }
 	return {{.DocInfo.Name}}(a.t, {{.ForwardedParams}})
 }
diff --git a/vendor/github.com/stretchr/testify/assert/assertions.go b/vendor/github.com/stretchr/testify/assert/assertions.go
index 47bda77..5bdec56 100644
--- a/vendor/github.com/stretchr/testify/assert/assertions.go
+++ b/vendor/github.com/stretchr/testify/assert/assertions.go
@@ -27,6 +27,22 @@ type TestingT interface {
 	Errorf(format string, args ...interface{})
 }
 
+// ComparisonAssertionFunc is a common function prototype when comparing two values.  Can be useful
+// for table driven tests.
+type ComparisonAssertionFunc func(TestingT, interface{}, interface{}, ...interface{}) bool
+
+// ValueAssertionFunc is a common function prototype when validating a single value.  Can be useful
+// for table driven tests.
+type ValueAssertionFunc func(TestingT, interface{}, ...interface{}) bool
+
+// BoolAssertionFunc is a common function prototype when validating a bool value.  Can be useful
+// for table driven tests.
+type BoolAssertionFunc func(TestingT, bool, ...interface{}) bool
+
+// ValuesAssertionFunc is a common function prototype when validating an error value.  Can be useful
+// for table driven tests.
+type ErrorAssertionFunc func(TestingT, error, ...interface{}) bool
+
 // Comparison a custom function that returns true on success and false on failure
 type Comparison func() (success bool)
 
@@ -38,21 +54,23 @@ type Comparison func() (success bool)
 //
 // This function does no assertion of any kind.
 func ObjectsAreEqual(expected, actual interface{}) bool {
-
 	if expected == nil || actual == nil {
 		return expected == actual
 	}
-	if exp, ok := expected.([]byte); ok {
-		act, ok := actual.([]byte)
-		if !ok {
-			return false
-		} else if exp == nil || act == nil {
-			return exp == nil && act == nil
-		}
-		return bytes.Equal(exp, act)
+
+	exp, ok := expected.([]byte)
+	if !ok {
+		return reflect.DeepEqual(expected, actual)
 	}
-	return reflect.DeepEqual(expected, actual)
 
+	act, ok := actual.([]byte)
+	if !ok {
+		return false
+	}
+	if exp == nil || act == nil {
+		return exp == nil && act == nil
+	}
+	return bytes.Equal(exp, act)
 }
 
 // ObjectsAreEqualValues gets whether two objects are equal, or if their
@@ -156,21 +174,6 @@ func isTest(name, prefix string) bool {
 	return !unicode.IsLower(rune)
 }
 
-// getWhitespaceString returns a string that is long enough to overwrite the default
-// output from the go testing framework.
-func getWhitespaceString() string {
-
-	_, file, line, ok := runtime.Caller(1)
-	if !ok {
-		return ""
-	}
-	parts := strings.Split(file, "/")
-	file = parts[len(parts)-1]
-
-	return strings.Repeat(" ", len(fmt.Sprintf("%s:%d:        ", file, line)))
-
-}
-
 func messageFromMsgAndArgs(msgAndArgs ...interface{}) string {
 	if len(msgAndArgs) == 0 || msgAndArgs == nil {
 		return ""
@@ -195,7 +198,7 @@ func indentMessageLines(message string, longestLabelLen int) string {
 		// no need to align first line because it starts at the correct location (after the label)
 		if i != 0 {
 			// append alignLen+1 spaces to align with "{{longestLabel}}:" before adding tab
-			outBuf.WriteString("\n\r\t" + strings.Repeat(" ", longestLabelLen+1) + "\t")
+			outBuf.WriteString("\n\t" + strings.Repeat(" ", longestLabelLen+1) + "\t")
 		}
 		outBuf.WriteString(scanner.Text())
 	}
@@ -209,6 +212,9 @@ type failNower interface {
 
 // FailNow fails test
 func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	Fail(t, failureMessage, msgAndArgs...)
 
 	// We cannot extend TestingT with FailNow() and
@@ -227,8 +233,11 @@ func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool
 
 // Fail reports a failure through
 func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	content := []labeledContent{
-		{"Error Trace", strings.Join(CallerInfo(), "\n\r\t\t\t")},
+		{"Error Trace", strings.Join(CallerInfo(), "\n\t\t\t")},
 		{"Error", failureMessage},
 	}
 
@@ -244,7 +253,7 @@ func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool {
 		content = append(content, labeledContent{"Messages", message})
 	}
 
-	t.Errorf("%s", "\r"+getWhitespaceString()+labeledOutput(content...))
+	t.Errorf("\n%s", ""+labeledOutput(content...))
 
 	return false
 }
@@ -256,7 +265,7 @@ type labeledContent struct {
 
 // labeledOutput returns a string consisting of the provided labeledContent. Each labeled output is appended in the following manner:
 //
-//   \r\t{{label}}:{{align_spaces}}\t{{content}}\n
+//   \t{{label}}:{{align_spaces}}\t{{content}}\n
 //
 // The initial carriage return is required to undo/erase any padding added by testing.T.Errorf. The "\t{{label}}:" is for the label.
 // If a label is shorter than the longest label provided, padding spaces are added to make all the labels match in length. Once this
@@ -272,7 +281,7 @@ func labeledOutput(content ...labeledContent) string {
 	}
 	var output string
 	for _, v := range content {
-		output += "\r\t" + v.label + ":" + strings.Repeat(" ", longestLabel-len(v.label)) + "\t" + indentMessageLines(v.content, longestLabel) + "\n"
+		output += "\t" + v.label + ":" + strings.Repeat(" ", longestLabel-len(v.label)) + "\t" + indentMessageLines(v.content, longestLabel) + "\n"
 	}
 	return output
 }
@@ -281,6 +290,9 @@ func labeledOutput(content ...labeledContent) string {
 //
 //    assert.Implements(t, (*MyInterface)(nil), new(MyObject))
 func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	interfaceType := reflect.TypeOf(interfaceObject).Elem()
 
 	if object == nil {
@@ -295,6 +307,9 @@ func Implements(t TestingT, interfaceObject interface{}, object interface{}, msg
 
 // IsType asserts that the specified objects are of the same type.
 func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 
 	if !ObjectsAreEqual(reflect.TypeOf(object), reflect.TypeOf(expectedType)) {
 		return Fail(t, fmt.Sprintf("Object expected to be of type %v, but was %v", reflect.TypeOf(expectedType), reflect.TypeOf(object)), msgAndArgs...)
@@ -311,6 +326,9 @@ func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs
 // referenced values (as opposed to the memory addresses). Function equality
 // cannot be determined and will always fail.
 func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	if err := validateEqualArgs(expected, actual); err != nil {
 		return Fail(t, fmt.Sprintf("Invalid operation: %#v == %#v (%s)",
 			expected, actual, err), msgAndArgs...)
@@ -349,6 +367,9 @@ func formatUnequalValues(expected, actual interface{}) (e string, a string) {
 //
 //    assert.EqualValues(t, uint32(123), int32(123))
 func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 
 	if !ObjectsAreEqualValues(expected, actual) {
 		diff := diff(expected, actual)
@@ -366,12 +387,15 @@ func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interfa
 //
 //    assert.Exactly(t, int32(123), int64(123))
 func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 
 	aType := reflect.TypeOf(expected)
 	bType := reflect.TypeOf(actual)
 
 	if aType != bType {
-		return Fail(t, fmt.Sprintf("Types expected to match exactly\n\r\t%v != %v", aType, bType), msgAndArgs...)
+		return Fail(t, fmt.Sprintf("Types expected to match exactly\n\t%v != %v", aType, bType), msgAndArgs...)
 	}
 
 	return Equal(t, expected, actual, msgAndArgs...)
@@ -382,6 +406,9 @@ func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}
 //
 //    assert.NotNil(t, err)
 func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	if !isNil(object) {
 		return true
 	}
@@ -407,6 +434,9 @@ func isNil(object interface{}) bool {
 //
 //    assert.Nil(t, err)
 func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	if isNil(object) {
 		return true
 	}
@@ -446,6 +476,9 @@ func isEmpty(object interface{}) bool {
 //
 //  assert.Empty(t, obj)
 func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 
 	pass := isEmpty(object)
 	if !pass {
@@ -463,6 +496,9 @@ func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
 //    assert.Equal(t, "two", obj[1])
 //  }
 func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 
 	pass := !isEmpty(object)
 	if !pass {
@@ -490,6 +526,9 @@ func getLen(x interface{}) (ok bool, length int) {
 //
 //    assert.Len(t, mySlice, 3)
 func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	ok, l := getLen(object)
 	if !ok {
 		return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", object), msgAndArgs...)
@@ -505,6 +544,14 @@ func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{})
 //
 //    assert.True(t, myBool)
 func True(t TestingT, value bool, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
+	if h, ok := t.(interface {
+		Helper()
+	}); ok {
+		h.Helper()
+	}
 
 	if value != true {
 		return Fail(t, "Should be true", msgAndArgs...)
@@ -518,6 +565,9 @@ func True(t TestingT, value bool, msgAndArgs ...interface{}) bool {
 //
 //    assert.False(t, myBool)
 func False(t TestingT, value bool, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 
 	if value != false {
 		return Fail(t, "Should be false", msgAndArgs...)
@@ -534,6 +584,9 @@ func False(t TestingT, value bool, msgAndArgs ...interface{}) bool {
 // Pointer variable equality is determined based on the equality of the
 // referenced values (as opposed to the memory addresses).
 func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	if err := validateEqualArgs(expected, actual); err != nil {
 		return Fail(t, fmt.Sprintf("Invalid operation: %#v != %#v (%s)",
 			expected, actual, err), msgAndArgs...)
@@ -592,6 +645,9 @@ func includeElement(list interface{}, element interface{}) (ok, found bool) {
 //    assert.Contains(t, ["Hello", "World"], "World")
 //    assert.Contains(t, {"Hello": "World"}, "Hello")
 func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 
 	ok, found := includeElement(s, contains)
 	if !ok {
@@ -612,6 +668,9 @@ func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bo
 //    assert.NotContains(t, ["Hello", "World"], "Earth")
 //    assert.NotContains(t, {"Hello": "World"}, "Earth")
 func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 
 	ok, found := includeElement(s, contains)
 	if !ok {
@@ -630,6 +689,9 @@ func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{})
 //
 //    assert.Subset(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]")
 func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	if subset == nil {
 		return true // we consider nil to be equal to the nil set
 	}
@@ -671,6 +733,9 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok
 //
 //    assert.NotSubset(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]")
 func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	if subset == nil {
 		return Fail(t, fmt.Sprintf("nil is the empty set which is a subset of every set"), msgAndArgs...)
 	}
@@ -713,6 +778,9 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{})
 //
 // assert.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2])
 func ElementsMatch(t TestingT, listA, listB interface{}, msgAndArgs ...interface{}) (ok bool) {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	if isEmpty(listA) && isEmpty(listB) {
 		return true
 	}
@@ -763,6 +831,9 @@ func ElementsMatch(t TestingT, listA, listB interface{}, msgAndArgs ...interface
 
 // Condition uses a Comparison to assert a complex condition.
 func Condition(t TestingT, comp Comparison, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	result := comp()
 	if !result {
 		Fail(t, "Condition failed!", msgAndArgs...)
@@ -800,9 +871,12 @@ func didPanic(f PanicTestFunc) (bool, interface{}) {
 //
 //   assert.Panics(t, func(){ GoCrazy() })
 func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 
 	if funcDidPanic, panicValue := didPanic(f); !funcDidPanic {
-		return Fail(t, fmt.Sprintf("func %#v should panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...)
+		return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...)
 	}
 
 	return true
@@ -813,13 +887,16 @@ func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
 //
 //   assert.PanicsWithValue(t, "crazy error", func(){ GoCrazy() })
 func PanicsWithValue(t TestingT, expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 
 	funcDidPanic, panicValue := didPanic(f)
 	if !funcDidPanic {
-		return Fail(t, fmt.Sprintf("func %#v should panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...)
+		return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...)
 	}
 	if panicValue != expected {
-		return Fail(t, fmt.Sprintf("func %#v should panic with value:\t%v\n\r\tPanic value:\t%v", f, expected, panicValue), msgAndArgs...)
+		return Fail(t, fmt.Sprintf("func %#v should panic with value:\t%#v\n\tPanic value:\t%#v", f, expected, panicValue), msgAndArgs...)
 	}
 
 	return true
@@ -829,9 +906,12 @@ func PanicsWithValue(t TestingT, expected interface{}, f PanicTestFunc, msgAndAr
 //
 //   assert.NotPanics(t, func(){ RemainCalm() })
 func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 
 	if funcDidPanic, panicValue := didPanic(f); funcDidPanic {
-		return Fail(t, fmt.Sprintf("func %#v should not panic\n\r\tPanic value:\t%v", f, panicValue), msgAndArgs...)
+		return Fail(t, fmt.Sprintf("func %#v should not panic\n\tPanic value:\t%v", f, panicValue), msgAndArgs...)
 	}
 
 	return true
@@ -841,6 +921,9 @@ func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool {
 //
 //   assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second)
 func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 
 	dt := expected.Sub(actual)
 	if dt < -delta || dt > delta {
@@ -890,6 +973,9 @@ func toFloat(x interface{}) (float64, bool) {
 //
 // 	 assert.InDelta(t, math.Pi, (22 / 7.0), 0.01)
 func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 
 	af, aok := toFloat(expected)
 	bf, bok := toFloat(actual)
@@ -916,6 +1002,9 @@ func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs
 
 // InDeltaSlice is the same as InDelta, except it compares two slices.
 func InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	if expected == nil || actual == nil ||
 		reflect.TypeOf(actual).Kind() != reflect.Slice ||
 		reflect.TypeOf(expected).Kind() != reflect.Slice {
@@ -937,6 +1026,9 @@ func InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAn
 
 // InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys.
 func InDeltaMapValues(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	if expected == nil || actual == nil ||
 		reflect.TypeOf(actual).Kind() != reflect.Map ||
 		reflect.TypeOf(expected).Kind() != reflect.Map {
@@ -994,6 +1086,9 @@ func calcRelativeError(expected, actual interface{}) (float64, error) {
 
 // InEpsilon asserts that expected and actual have a relative error less than epsilon
 func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	actualEpsilon, err := calcRelativeError(expected, actual)
 	if err != nil {
 		return Fail(t, err.Error(), msgAndArgs...)
@@ -1008,6 +1103,9 @@ func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAnd
 
 // InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices.
 func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	if expected == nil || actual == nil ||
 		reflect.TypeOf(actual).Kind() != reflect.Slice ||
 		reflect.TypeOf(expected).Kind() != reflect.Slice {
@@ -1038,6 +1136,9 @@ func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, m
 //	   assert.Equal(t, expectedObj, actualObj)
 //   }
 func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	if err != nil {
 		return Fail(t, fmt.Sprintf("Received unexpected error:\n%+v", err), msgAndArgs...)
 	}
@@ -1052,6 +1153,9 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool {
 //	   assert.Equal(t, expectedError, err)
 //   }
 func Error(t TestingT, err error, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 
 	if err == nil {
 		return Fail(t, "An error is expected but got nil.", msgAndArgs...)
@@ -1066,6 +1170,9 @@ func Error(t TestingT, err error, msgAndArgs ...interface{}) bool {
 //   actualObj, err := SomeFunction()
 //   assert.EqualError(t, err,  expectedErrorString)
 func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	if !Error(t, theError, msgAndArgs...) {
 		return false
 	}
@@ -1099,6 +1206,9 @@ func matchRegexp(rx interface{}, str interface{}) bool {
 //  assert.Regexp(t, regexp.MustCompile("start"), "it's starting")
 //  assert.Regexp(t, "start...$", "it's not starting")
 func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 
 	match := matchRegexp(rx, str)
 
@@ -1114,6 +1224,9 @@ func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface
 //  assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting")
 //  assert.NotRegexp(t, "^start", "it's not starting")
 func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	match := matchRegexp(rx, str)
 
 	if match {
@@ -1126,6 +1239,9 @@ func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interf
 
 // Zero asserts that i is the zero value for its type.
 func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	if i != nil && !reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) {
 		return Fail(t, fmt.Sprintf("Should be zero, but was %v", i), msgAndArgs...)
 	}
@@ -1134,6 +1250,9 @@ func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {
 
 // NotZero asserts that i is not the zero value for its type.
 func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	if i == nil || reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) {
 		return Fail(t, fmt.Sprintf("Should not be zero, but was %v", i), msgAndArgs...)
 	}
@@ -1142,6 +1261,9 @@ func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool {
 
 // FileExists checks whether a file exists in the given path. It also fails if the path points to a directory or there is an error when trying to check the file.
 func FileExists(t TestingT, path string, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	info, err := os.Lstat(path)
 	if err != nil {
 		if os.IsNotExist(err) {
@@ -1157,6 +1279,9 @@ func FileExists(t TestingT, path string, msgAndArgs ...interface{}) bool {
 
 // DirExists checks whether a directory exists in the given path. It also fails if the path is a file rather a directory or there is an error checking whether it exists.
 func DirExists(t TestingT, path string, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	info, err := os.Lstat(path)
 	if err != nil {
 		if os.IsNotExist(err) {
@@ -1174,6 +1299,9 @@ func DirExists(t TestingT, path string, msgAndArgs ...interface{}) bool {
 //
 //  assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`)
 func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	var expectedJSONAsInterface, actualJSONAsInterface interface{}
 
 	if err := json.Unmarshal([]byte(expected), &expectedJSONAsInterface); err != nil {
@@ -1212,12 +1340,18 @@ func diff(expected interface{}, actual interface{}) string {
 		return ""
 	}
 
-	if ek != reflect.Struct && ek != reflect.Map && ek != reflect.Slice && ek != reflect.Array {
+	if ek != reflect.Struct && ek != reflect.Map && ek != reflect.Slice && ek != reflect.Array && ek != reflect.String {
 		return ""
 	}
 
-	e := spewConfig.Sdump(expected)
-	a := spewConfig.Sdump(actual)
+	var e, a string
+	if ek != reflect.String {
+		e = spewConfig.Sdump(expected)
+		a = spewConfig.Sdump(actual)
+	} else {
+		e = expected.(string)
+		a = actual.(string)
+	}
 
 	diff, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{
 		A:        difflib.SplitLines(e),
@@ -1254,3 +1388,7 @@ var spewConfig = spew.ConfigState{
 	DisableCapacities:       true,
 	SortKeys:                true,
 }
+
+type tHelper interface {
+	Helper()
+}
diff --git a/vendor/github.com/stretchr/testify/assert/http_assertions.go b/vendor/github.com/stretchr/testify/assert/http_assertions.go
index 3101e78..df46fa7 100644
--- a/vendor/github.com/stretchr/testify/assert/http_assertions.go
+++ b/vendor/github.com/stretchr/testify/assert/http_assertions.go
@@ -12,10 +12,11 @@ import (
 // an error if building a new request fails.
 func httpCode(handler http.HandlerFunc, method, url string, values url.Values) (int, error) {
 	w := httptest.NewRecorder()
-	req, err := http.NewRequest(method, url+"?"+values.Encode(), nil)
+	req, err := http.NewRequest(method, url, nil)
 	if err != nil {
 		return -1, err
 	}
+	req.URL.RawQuery = values.Encode()
 	handler(w, req)
 	return w.Code, nil
 }
@@ -26,6 +27,9 @@ func httpCode(handler http.HandlerFunc, method, url string, values url.Values) (
 //
 // Returns whether the assertion was successful (true) or not (false).
 func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	code, err := httpCode(handler, method, url, values)
 	if err != nil {
 		Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err))
@@ -46,6 +50,9 @@ func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, value
 //
 // Returns whether the assertion was successful (true) or not (false).
 func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	code, err := httpCode(handler, method, url, values)
 	if err != nil {
 		Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err))
@@ -66,6 +73,9 @@ func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, valu
 //
 // Returns whether the assertion was successful (true) or not (false).
 func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	code, err := httpCode(handler, method, url, values)
 	if err != nil {
 		Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err))
@@ -95,10 +105,13 @@ func HTTPBody(handler http.HandlerFunc, method, url string, values url.Values) s
 // HTTPBodyContains asserts that a specified handler returns a
 // body that contains a string.
 //
-//  assert.HTTPBodyContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
+//  assert.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky")
 //
 // Returns whether the assertion was successful (true) or not (false).
 func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	body := HTTPBody(handler, method, url, values)
 
 	contains := strings.Contains(body, fmt.Sprint(str))
@@ -112,10 +125,13 @@ func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string,
 // HTTPBodyNotContains asserts that a specified handler returns a
 // body that does not contain a string.
 //
-//  assert.HTTPBodyNotContains(t, myHandler, "www.google.com", nil, "I'm Feeling Lucky")
+//  assert.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky")
 //
 // Returns whether the assertion was successful (true) or not (false).
 func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool {
+	if h, ok := t.(tHelper); ok {
+		h.Helper()
+	}
 	body := HTTPBody(handler, method, url, values)
 
 	contains := strings.Contains(body, fmt.Sprint(str))
diff --git a/vendor/github.com/zyedidia/clipboard/LICENSE b/vendor/github.com/zyedidia/clipboard/LICENSE
index dee3257..bdec9a5 100644
--- a/vendor/github.com/zyedidia/clipboard/LICENSE
+++ b/vendor/github.com/zyedidia/clipboard/LICENSE
@@ -1,3 +1,7 @@
+Copyright (c) 2018 Zachary Yedidia. Modifications to atotto/clipboard.
+
+Original license:
+
 Copyright (c) 2013 Ato Araki. All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/vendor/github.com/zyedidia/clipboard/README.md b/vendor/github.com/zyedidia/clipboard/README.md
index 6e2d15f..8691eb1 100644
--- a/vendor/github.com/zyedidia/clipboard/README.md
+++ b/vendor/github.com/zyedidia/clipboard/README.md
@@ -1,3 +1,7 @@
+# This is a fork of atotto/clipboard
+
+This fork is used for `zyedidia/micro` and has some modifications, namely: support for the primary clipboard on linux and support for an internal clipboard if the system clipboard is not available.
+
 [![Build Status](https://travis-ci.org/atotto/clipboard.svg?branch=master)](https://travis-ci.org/atotto/clipboard) [![Build Status](https://drone.io/github.com/atotto/clipboard/status.png)](https://drone.io/github.com/atotto/clipboard/latest) 
 
 [![GoDoc](https://godoc.org/github.com/atotto/clipboard?status.svg)](http://godoc.org/github.com/atotto/clipboard)
diff --git a/vendor/golang.org/x/image/bmp/writer.go b/vendor/golang.org/x/image/bmp/writer.go
index 6947968..f07b39d 100644
--- a/vendor/golang.org/x/image/bmp/writer.go
+++ b/vendor/golang.org/x/image/bmp/writer.go
@@ -49,20 +49,91 @@ func encodePaletted(w io.Writer, pix []uint8, dx, dy, stride, step int) error {
 	return nil
 }
 
-func encodeRGBA(w io.Writer, pix []uint8, dx, dy, stride, step int) error {
+func encodeRGBA(w io.Writer, pix []uint8, dx, dy, stride, step int, opaque bool) error {
 	buf := make([]byte, step)
-	for y := dy - 1; y >= 0; y-- {
-		min := y*stride + 0
-		max := y*stride + dx*4
-		off := 0
-		for i := min; i < max; i += 4 {
-			buf[off+2] = pix[i+0]
-			buf[off+1] = pix[i+1]
-			buf[off+0] = pix[i+2]
-			off += 3
+	if opaque {
+		for y := dy - 1; y >= 0; y-- {
+			min := y*stride + 0
+			max := y*stride + dx*4
+			off := 0
+			for i := min; i < max; i += 4 {
+				buf[off+2] = pix[i+0]
+				buf[off+1] = pix[i+1]
+				buf[off+0] = pix[i+2]
+				off += 3
+			}
+			if _, err := w.Write(buf); err != nil {
+				return err
+			}
 		}
-		if _, err := w.Write(buf); err != nil {
-			return err
+	} else {
+		for y := dy - 1; y >= 0; y-- {
+			min := y*stride + 0
+			max := y*stride + dx*4
+			off := 0
+			for i := min; i < max; i += 4 {
+				a := uint32(pix[i+3])
+				if a == 0 {
+					buf[off+2] = 0
+					buf[off+1] = 0
+					buf[off+0] = 0
+					buf[off+3] = 0
+					off += 4
+					continue
+				} else if a == 0xff {
+					buf[off+2] = pix[i+0]
+					buf[off+1] = pix[i+1]
+					buf[off+0] = pix[i+2]
+					buf[off+3] = 0xff
+					off += 4
+					continue
+				}
+				buf[off+2] = uint8(((uint32(pix[i+0]) * 0xffff) / a) >> 8)
+				buf[off+1] = uint8(((uint32(pix[i+1]) * 0xffff) / a) >> 8)
+				buf[off+0] = uint8(((uint32(pix[i+2]) * 0xffff) / a) >> 8)
+				buf[off+3] = uint8(a)
+				off += 4
+			}
+			if _, err := w.Write(buf); err != nil {
+				return err
+			}
+		}
+	}
+	return nil
+}
+
+func encodeNRGBA(w io.Writer, pix []uint8, dx, dy, stride, step int, opaque bool) error {
+	buf := make([]byte, step)
+	if opaque {
+		for y := dy - 1; y >= 0; y-- {
+			min := y*stride + 0
+			max := y*stride + dx*4
+			off := 0
+			for i := min; i < max; i += 4 {
+				buf[off+2] = pix[i+0]
+				buf[off+1] = pix[i+1]
+				buf[off+0] = pix[i+2]
+				off += 3
+			}
+			if _, err := w.Write(buf); err != nil {
+				return err
+			}
+		}
+	} else {
+		for y := dy - 1; y >= 0; y-- {
+			min := y*stride + 0
+			max := y*stride + dx*4
+			off := 0
+			for i := min; i < max; i += 4 {
+				buf[off+2] = pix[i+0]
+				buf[off+1] = pix[i+1]
+				buf[off+0] = pix[i+2]
+				buf[off+3] = pix[i+3]
+				off += 4
+			}
+			if _, err := w.Write(buf); err != nil {
+				return err
+			}
 		}
 	}
 	return nil
@@ -105,6 +176,7 @@ func Encode(w io.Writer, m image.Image) error {
 
 	var step int
 	var palette []byte
+	var opaque bool
 	switch m := m.(type) {
 	case *image.Gray:
 		step = (d.X + 3) &^ 3
@@ -134,6 +206,28 @@ func Encode(w io.Writer, m image.Image) error {
 		h.fileSize += uint32(len(palette)) + h.imageSize
 		h.pixOffset += uint32(len(palette))
 		h.bpp = 8
+	case *image.RGBA:
+		opaque = m.Opaque()
+		if opaque {
+			step = (3*d.X + 3) &^ 3
+			h.bpp = 24
+		} else {
+			step = 4 * d.X
+			h.bpp = 32
+		}
+		h.imageSize = uint32(d.Y * step)
+		h.fileSize += h.imageSize
+	case *image.NRGBA:
+		opaque = m.Opaque()
+		if opaque {
+			step = (3*d.X + 3) &^ 3
+			h.bpp = 24
+		} else {
+			step = 4 * d.X
+			h.bpp = 32
+		}
+		h.imageSize = uint32(d.Y * step)
+		h.fileSize += h.imageSize
 	default:
 		step = (3*d.X + 3) &^ 3
 		h.imageSize = uint32(d.Y * step)
@@ -160,7 +254,9 @@ func Encode(w io.Writer, m image.Image) error {
 	case *image.Paletted:
 		return encodePaletted(w, m.Pix, d.X, d.Y, m.Stride, step)
 	case *image.RGBA:
-		return encodeRGBA(w, m.Pix, d.X, d.Y, m.Stride, step)
+		return encodeRGBA(w, m.Pix, d.X, d.Y, m.Stride, step, opaque)
+	case *image.NRGBA:
+		return encodeNRGBA(w, m.Pix, d.X, d.Y, m.Stride, step, opaque)
 	}
 	return encode(w, m, step)
 }
diff --git a/vendor/golang.org/x/net/html/parse.go b/vendor/golang.org/x/net/html/parse.go
index d23e05e..4b1fa42 100644
--- a/vendor/golang.org/x/net/html/parse.go
+++ b/vendor/golang.org/x/net/html/parse.go
@@ -209,27 +209,6 @@ loop:
 	p.oe = p.oe[:i+1]
 }
 
-// generateAllImpliedEndTags pops nodes off the stack of open elements as long as
-// the top node has a tag name of caption, colgroup, dd, div, dt, li, optgroup, option, p, rb,
-// rp, rt, rtc, span, tbody, td, tfoot, th, thead or tr.
-func (p *parser) generateAllImpliedEndTags() {
-	var i int
-	for i = len(p.oe) - 1; i >= 0; i-- {
-		n := p.oe[i]
-		if n.Type == ElementNode {
-			switch n.DataAtom {
-			// TODO: remove this divergence from the HTML5 spec
-			case a.Caption, a.Colgroup, a.Dd, a.Div, a.Dt, a.Li, a.Optgroup, a.Option, a.P, a.Rb,
-				a.Rp, a.Rt, a.Rtc, a.Span, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr:
-				continue
-			}
-		}
-		break
-	}
-
-	p.oe = p.oe[:i+1]
-}
-
 // addChild adds a child node n to the top element, and pushes n onto the stack
 // of open elements if it is an element node.
 func (p *parser) addChild(n *Node) {
@@ -276,7 +255,7 @@ func (p *parser) fosterParent(n *Node) {
 		}
 	}
 
-	if template != nil && (table == nil || j < i) {
+	if template != nil && (table == nil || j > i) {
 		template.AppendChild(n)
 		return
 	}
@@ -679,11 +658,16 @@ func inHeadIM(p *parser) bool {
 			if !p.oe.contains(a.Template) {
 				return true
 			}
-			p.generateAllImpliedEndTags()
-			if n := p.oe.top(); n.DataAtom != a.Template {
-				return true
+			// TODO: remove this divergence from the HTML5 spec.
+			//
+			// See https://bugs.chromium.org/p/chromium/issues/detail?id=829668
+			p.generateImpliedEndTags()
+			for i := len(p.oe) - 1; i >= 0; i-- {
+				if n := p.oe[i]; n.Namespace == "" && n.DataAtom == a.Template {
+					p.oe = p.oe[:i]
+					break
+				}
 			}
-			p.popUntil(defaultScope, a.Template)
 			p.clearActiveFormattingElements()
 			p.templateStack.pop()
 			p.resetInsertionMode()
@@ -860,9 +844,13 @@ func inBodyIM(p *parser) bool {
 			// The newline, if any, will be dealt with by the TextToken case.
 			p.framesetOK = false
 		case a.Form:
-			if p.oe.contains(a.Template) || p.form == nil {
-				p.popUntil(buttonScope, a.P)
-				p.addElement()
+			if p.form != nil && !p.oe.contains(a.Template) {
+				// Ignore the token
+				return true
+			}
+			p.popUntil(buttonScope, a.P)
+			p.addElement()
+			if !p.oe.contains(a.Template) {
 				p.form = p.top()
 			}
 		case a.Li:
@@ -1070,13 +1058,7 @@ func inBodyIM(p *parser) bool {
 				p.acknowledgeSelfClosingTag()
 			}
 			return true
-		case a.Frame:
-			// TODO: remove this divergence from the HTML5 spec.
-			if p.oe.contains(a.Template) {
-				p.addElement()
-				return true
-			}
-		case a.Caption, a.Col, a.Colgroup, a.Head, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr:
+		case a.Caption, a.Col, a.Colgroup, a.Frame, a.Head, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr:
 			// Ignore the token.
 		default:
 			p.reconstructActiveFormattingElements()
@@ -1098,12 +1080,13 @@ func inBodyIM(p *parser) bool {
 			p.popUntil(defaultScope, p.tok.DataAtom)
 		case a.Form:
 			if p.oe.contains(a.Template) {
-				if !p.oe.contains(a.Form) {
+				i := p.indexOfElementInScope(defaultScope, a.Form)
+				if i == -1 {
 					// Ignore the token.
 					return true
 				}
 				p.generateImpliedEndTags()
-				if p.tok.DataAtom == a.Form {
+				if p.oe[i].DataAtom != a.Form {
 					// Ignore the token.
 					return true
 				}
@@ -1346,9 +1329,6 @@ func textIM(p *parser) bool {
 // Section 12.2.6.4.9.
 func inTableIM(p *parser) bool {
 	switch p.tok.Type {
-	case ErrorToken:
-		// Stop parsing.
-		return true
 	case TextToken:
 		p.tok.Data = strings.Replace(p.tok.Data, "\x00", "", -1)
 		switch p.oe.top().DataAtom {
@@ -1443,6 +1423,8 @@ func inTableIM(p *parser) bool {
 	case DoctypeToken:
 		// Ignore the token.
 		return true
+	case ErrorToken:
+		return inBodyIM(p)
 	}
 
 	p.fosterParenting = true
@@ -1545,6 +1527,8 @@ func inColumnGroupIM(p *parser) bool {
 		case a.Template:
 			return inHeadIM(p)
 		}
+	case ErrorToken:
+		return inBodyIM(p)
 	}
 	if p.oe.top().DataAtom != a.Colgroup {
 		return true
@@ -1709,9 +1693,6 @@ func inCellIM(p *parser) bool {
 // Section 12.2.6.4.16.
 func inSelectIM(p *parser) bool {
 	switch p.tok.Type {
-	case ErrorToken:
-		// Stop parsing.
-		return true
 	case TextToken:
 		p.addText(strings.Replace(p.tok.Data, "\x00", "", -1))
 	case StartTagToken:
@@ -1775,6 +1756,8 @@ func inSelectIM(p *parser) bool {
 	case DoctypeToken:
 		// Ignore the token.
 		return true
+	case ErrorToken:
+		return inBodyIM(p)
 	}
 
 	return true
@@ -1841,15 +1824,26 @@ func inTemplateIM(p *parser) bool {
 			// Ignore the token.
 			return true
 		}
+	case ErrorToken:
+		if !p.oe.contains(a.Template) {
+			// Ignore the token.
+			return true
+		}
+		// TODO: remove this divergence from the HTML5 spec.
+		//
+		// See https://bugs.chromium.org/p/chromium/issues/detail?id=829668
+		p.generateImpliedEndTags()
+		for i := len(p.oe) - 1; i >= 0; i-- {
+			if n := p.oe[i]; n.Namespace == "" && n.DataAtom == a.Template {
+				p.oe = p.oe[:i]
+				break
+			}
+		}
+		p.clearActiveFormattingElements()
+		p.templateStack.pop()
+		p.resetInsertionMode()
+		return false
 	}
-	if !p.oe.contains(a.Template) {
-		// Ignore the token.
-		return true
-	}
-	p.popUntil(defaultScope, a.Template)
-	p.clearActiveFormattingElements()
-	p.templateStack.pop()
-	p.resetInsertionMode()
 	return false
 }
 
@@ -1923,11 +1917,6 @@ func inFramesetIM(p *parser) bool {
 			p.acknowledgeSelfClosingTag()
 		case a.Noframes:
 			return inHeadIM(p)
-		case a.Template:
-			// TODO: remove this divergence from the HTML5 spec.
-			//
-			// See https://bugs.chromium.org/p/chromium/issues/detail?id=829668
-			return inTemplateIM(p)
 		}
 	case EndTagToken:
 		switch p.tok.DataAtom {
diff --git a/vendor/gopkg.in/toast.v1/toast.go b/vendor/gopkg.in/toast.v1/toast.go
index 1782e5e..7ea32c9 100644
--- a/vendor/gopkg.in/toast.v1/toast.go
+++ b/vendor/gopkg.in/toast.v1/toast.go
@@ -11,6 +11,7 @@ import (
 	"text/template"
 
 	"github.com/nu7hatch/gouuid"
+	"syscall"
 )
 
 var toastTemplate *template.Template
@@ -347,7 +348,9 @@ func invokeTemporaryScript(content string) error {
 	if err != nil {
 		return err
 	}
-	if err = exec.Command("PowerShell", "-ExecutionPolicy", "Bypass", "-File", file).Run(); err != nil {
+	cmd := exec.Command("PowerShell", "-ExecutionPolicy", "Bypass", "-File", file)
+	cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
+	if err = cmd.Run(); err != nil {
 		return err
 	}
 	return nil
diff --git a/vendor/maunium.net/go/gomatrix/client.go b/vendor/maunium.net/go/gomatrix/client.go
index 7725ac3..0806138 100644
--- a/vendor/maunium.net/go/gomatrix/client.go
+++ b/vendor/maunium.net/go/gomatrix/client.go
@@ -6,13 +6,16 @@ package gomatrix
 import (
 	"bytes"
 	"encoding/json"
+	"errors"
 	"fmt"
 	"io"
 	"io/ioutil"
+	"maunium.net/go/maulogger"
 	"net/http"
 	"net/url"
 	"path"
 	"strconv"
+	"strings"
 	"sync"
 	"time"
 )
@@ -26,6 +29,7 @@ type Client struct {
 	Client        *http.Client // The underlying HTTP client which will be used to make HTTP requests.
 	Syncer        Syncer       // The thing which can process /sync responses
 	Store         Storer       // The thing which can store rooms/tokens/ids
+	Logger        maulogger.Logger
 
 	// The ?user_id= query parameter for application services. This must be set *prior* to calling a method. If this is empty,
 	// no user_id parameter will be sent.
@@ -39,6 +43,7 @@ type Client struct {
 // HTTPError An HTTP Error response, which may wrap an underlying native Go Error.
 type HTTPError struct {
 	WrappedError error
+	RespError    *RespError
 	Message      string
 	Code         int
 }
@@ -177,6 +182,14 @@ func (cli *Client) StopSync() {
 	cli.incrementSyncingID()
 }
 
+func (cli *Client) LogRequest(req *http.Request, body string) {
+	if cli.Logger == nil {
+		return
+	}
+
+	cli.Logger.Debugfln("%s %s %s", req.Method, req.URL.Path, body)
+}
+
 // MakeRequest makes a JSON HTTP request to the given URL.
 // If "resBody" is not nil, the response body will be json.Unmarshalled into it.
 //
@@ -186,12 +199,14 @@ func (cli *Client) StopSync() {
 func (cli *Client) MakeRequest(method string, httpURL string, reqBody interface{}, resBody interface{}) ([]byte, error) {
 	var req *http.Request
 	var err error
+	logBody := "{}"
 	if reqBody != nil {
 		var jsonStr []byte
 		jsonStr, err = json.Marshal(reqBody)
 		if err != nil {
 			return nil, err
 		}
+		logBody = string(jsonStr)
 		req, err = http.NewRequest(method, httpURL, bytes.NewBuffer(jsonStr))
 	} else {
 		req, err = http.NewRequest(method, httpURL, nil)
@@ -201,6 +216,7 @@ func (cli *Client) MakeRequest(method string, httpURL string, reqBody interface{
 		return nil, err
 	}
 	req.Header.Set("Content-Type", "application/json")
+	cli.LogRequest(req, logBody)
 	res, err := cli.Client.Do(req)
 	if res != nil {
 		defer res.Body.Close()
@@ -211,9 +227,11 @@ func (cli *Client) MakeRequest(method string, httpURL string, reqBody interface{
 	contents, err := ioutil.ReadAll(res.Body)
 	if res.StatusCode/100 != 2 { // not 2xx
 		var wrap error
-		var respErr RespError
-		if _ = json.Unmarshal(contents, &respErr); respErr.ErrCode != "" {
+		respErr := &RespError{}
+		if _ = json.Unmarshal(contents, respErr); respErr.ErrCode != "" {
 			wrap = respErr
+		} else {
+			respErr = nil
 		}
 
 		// If we failed to decode as RespError, don't just drop the HTTP body, include it in the
@@ -227,6 +245,7 @@ func (cli *Client) MakeRequest(method string, httpURL string, reqBody interface{
 			Code:         res.StatusCode,
 			Message:      msg,
 			WrappedError: wrap,
+			RespError:    respErr,
 		}
 	}
 	if err != nil {
@@ -342,7 +361,7 @@ func (cli *Client) RegisterDummy(req *ReqRegister) (*RespRegister, error) {
 		}
 	}
 	if res == nil {
-		return nil, fmt.Errorf("registration failed: does this server support m.login.dummy?")
+		return nil, fmt.Errorf("registration failed: does this server support m.login.dummy? ")
 	}
 	return res, nil
 }
@@ -442,17 +461,38 @@ func (cli *Client) SetAvatarURL(url string) (err error) {
 
 // SendMessageEvent sends a message event into a room. See http://matrix.org/docs/spec/client_server/r0.2.0.html#put-matrix-client-r0-rooms-roomid-send-eventtype-txnid
 // contentJSON should be a pointer to something that can be encoded as JSON using json.Marshal.
-func (cli *Client) SendMessageEvent(roomID string, eventType string, contentJSON interface{}) (resp *RespSendEvent, err error) {
+func (cli *Client) SendMessageEvent(roomID string, eventType EventType, contentJSON interface{}) (resp *RespSendEvent, err error) {
+	txnID := txnID()
+	urlPath := cli.BuildURL("rooms", roomID, "send", eventType.String(), txnID)
+	_, err = cli.MakeRequest("PUT", urlPath, contentJSON, &resp)
+	return
+}
+
+// SendMessageEvent sends a message event into a room. See http://matrix.org/docs/spec/client_server/r0.2.0.html#put-matrix-client-r0-rooms-roomid-send-eventtype-txnid
+// contentJSON should be a pointer to something that can be encoded as JSON using json.Marshal.
+func (cli *Client) SendMassagedMessageEvent(roomID string, eventType EventType, contentJSON interface{}, ts int64) (resp *RespSendEvent, err error) {
 	txnID := txnID()
-	urlPath := cli.BuildURL("rooms", roomID, "send", eventType, txnID)
+	urlPath := cli.BuildURLWithQuery([]string{"rooms", roomID, "send", eventType.String(), txnID}, map[string]string{
+		"ts": strconv.FormatInt(ts, 10),
+	})
 	_, err = cli.MakeRequest("PUT", urlPath, contentJSON, &resp)
 	return
 }
 
 // SendStateEvent sends a state event into a room. See http://matrix.org/docs/spec/client_server/r0.2.0.html#put-matrix-client-r0-rooms-roomid-state-eventtype-statekey
 // contentJSON should be a pointer to something that can be encoded as JSON using json.Marshal.
-func (cli *Client) SendStateEvent(roomID, eventType, stateKey string, contentJSON interface{}) (resp *RespSendEvent, err error) {
-	urlPath := cli.BuildURL("rooms", roomID, "state", eventType, stateKey)
+func (cli *Client) SendStateEvent(roomID string, eventType EventType, stateKey string, contentJSON interface{}) (resp *RespSendEvent, err error) {
+	urlPath := cli.BuildURL("rooms", roomID, "state", eventType.String(), stateKey)
+	_, err = cli.MakeRequest("PUT", urlPath, contentJSON, &resp)
+	return
+}
+
+// SendStateEvent sends a state event into a room. See http://matrix.org/docs/spec/client_server/r0.2.0.html#put-matrix-client-r0-rooms-roomid-state-eventtype-statekey
+// contentJSON should be a pointer to something that can be encoded as JSON using json.Marshal.
+func (cli *Client) SendMassagedStateEvent(roomID string, eventType EventType, stateKey string, contentJSON interface{}, ts int64) (resp *RespSendEvent, err error) {
+	urlPath := cli.BuildURLWithQuery([]string{"rooms", roomID, "state", eventType.String(), stateKey}, map[string]string{
+		"ts": strconv.FormatInt(ts, 10),
+	})
 	_, err = cli.MakeRequest("PUT", urlPath, contentJSON, &resp)
 	return
 }
@@ -460,37 +500,39 @@ func (cli *Client) SendStateEvent(roomID, eventType, stateKey string, contentJSO
 // SendText sends an m.room.message event into the given room with a msgtype of m.text
 // See http://matrix.org/docs/spec/client_server/r0.2.0.html#m-text
 func (cli *Client) SendText(roomID, text string) (*RespSendEvent, error) {
-	return cli.SendMessageEvent(roomID, "m.room.message",
-		TextMessage{"m.text", text})
+	return cli.SendMessageEvent(roomID, EventMessage, Content{
+		MsgType: MsgText,
+		Body:    text,
+	})
 }
 
 // SendImage sends an m.room.message event into the given room with a msgtype of m.image
 // See https://matrix.org/docs/spec/client_server/r0.2.0.html#m-image
 func (cli *Client) SendImage(roomID, body, url string) (*RespSendEvent, error) {
-	return cli.SendMessageEvent(roomID, "m.room.message",
-		ImageMessage{
-			MsgType: "m.image",
-			Body:    body,
-			URL:     url,
-		})
+	return cli.SendMessageEvent(roomID, EventMessage, Content{
+		MsgType: MsgImage,
+		Body:    body,
+		URL:     url,
+	})
 }
 
 // SendVideo sends an m.room.message event into the given room with a msgtype of m.video
 // See https://matrix.org/docs/spec/client_server/r0.2.0.html#m-video
 func (cli *Client) SendVideo(roomID, body, url string) (*RespSendEvent, error) {
-	return cli.SendMessageEvent(roomID, "m.room.message",
-		VideoMessage{
-			MsgType: "m.video",
-			Body:    body,
-			URL:     url,
-		})
+	return cli.SendMessageEvent(roomID, EventMessage, Content{
+		MsgType: MsgVideo,
+		Body:    body,
+		URL:     url,
+	})
 }
 
 // SendNotice sends an m.room.message event into the given room with a msgtype of m.notice
 // See http://matrix.org/docs/spec/client_server/r0.2.0.html#m-notice
 func (cli *Client) SendNotice(roomID, text string) (*RespSendEvent, error) {
-	return cli.SendMessageEvent(roomID, "m.room.message",
-		TextMessage{"m.notice", text})
+	return cli.SendMessageEvent(roomID, EventMessage, Content{
+		MsgType: MsgNotice,
+		Body:    text,
+	})
 }
 
 // RedactEvent redacts the given event. See http://matrix.org/docs/spec/client_server/r0.2.0.html#put-matrix-client-r0-rooms-roomid-redact-eventid-txnid
@@ -569,11 +611,18 @@ func (cli *Client) UserTyping(roomID string, typing bool, timeout int64) (resp *
 	return
 }
 
+func (cli *Client) SetPresence(status string) (err error) {
+	req := ReqPresence{Presence: status}
+	u := cli.BuildURL("presence", cli.UserID, "status")
+	_, err = cli.MakeRequest("PUT", u, req, nil)
+	return
+}
+
 // StateEvent gets a single state event in a room. It will attempt to JSON unmarshal into the given "outContent" struct with
 // the HTTP response body, or return an error.
 // See http://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-rooms-roomid-state-eventtype-statekey
-func (cli *Client) StateEvent(roomID, eventType, stateKey string, outContent interface{}) (err error) {
-	u := cli.BuildURL("rooms", roomID, "state", eventType, stateKey)
+func (cli *Client) StateEvent(roomID string, eventType EventType, stateKey string, outContent interface{}) (err error) {
+	u := cli.BuildURL("rooms", roomID, "state", eventType.String(), stateKey)
 	_, err = cli.MakeRequest("GET", u, nil, outContent)
 	return
 }
@@ -587,18 +636,48 @@ func (cli *Client) UploadLink(link string) (*RespMediaUpload, error) {
 	if err != nil {
 		return nil, err
 	}
-	return cli.UploadToContentRepo(res.Body, res.Header.Get("Content-Type"), res.ContentLength)
+	return cli.Upload(res.Body, res.Header.Get("Content-Type"), res.ContentLength)
+}
+
+func (cli *Client) Download(mxcURL string) (io.ReadCloser, error) {
+	if !strings.HasPrefix(mxcURL, "mxc://") {
+		return nil, errors.New("invalid Matrix content URL")
+	}
+	parts := strings.Split(mxcURL[len("mxc://"):], "/")
+	if len(parts) != 2 {
+		return nil, errors.New("invalid Matrix content URL")
+	}
+	u := cli.BuildBaseURL("_matrix/media/r0/download", parts[0], parts[1])
+	resp, err := cli.Client.Get(u)
+	if err != nil {
+		return nil, err
+	}
+	return resp.Body, nil
+}
+
+func (cli *Client) DownloadBytes(mxcURL string) ([]byte, error) {
+	resp, err := cli.Download(mxcURL)
+	if err != nil {
+		return nil, err
+	}
+	defer resp.Close()
+	return ioutil.ReadAll(resp)
+}
+
+func (cli *Client) UploadBytes(data []byte, contentType string) (*RespMediaUpload, error) {
+	return cli.Upload(bytes.NewReader(data), contentType, int64(len(data)))
 }
 
 // UploadToContentRepo uploads the given bytes to the content repository and returns an MXC URI.
 // See http://matrix.org/docs/spec/client_server/r0.2.0.html#post-matrix-media-r0-upload
-func (cli *Client) UploadToContentRepo(content io.Reader, contentType string, contentLength int64) (*RespMediaUpload, error) {
+func (cli *Client) Upload(content io.Reader, contentType string, contentLength int64) (*RespMediaUpload, error) {
 	req, err := http.NewRequest("POST", cli.BuildBaseURL("_matrix/media/r0/upload"), content)
 	if err != nil {
 		return nil, err
 	}
 	req.Header.Set("Content-Type", contentType)
 	req.ContentLength = contentLength
+	cli.LogRequest(req, fmt.Sprintf("%d bytes", contentLength))
 	res, err := cli.Client.Do(req)
 	if res != nil {
 		defer res.Body.Close()
@@ -666,6 +745,18 @@ func (cli *Client) Messages(roomID, from, to string, dir rune, limit int) (resp
 	return
 }
 
+func (cli *Client) GetEvent(roomID, eventID string) (resp *Event, err error) {
+	urlPath := cli.BuildURL("rooms", roomID, "event", eventID)
+	_, err = cli.MakeRequest("GET", urlPath, nil, &resp)
+	return
+}
+
+func (cli *Client) MarkRead(roomID, eventID string) (err error) {
+	urlPath := cli.BuildURL("rooms", roomID, "receipt", "m.read", eventID)
+	_, err = cli.MakeRequest("POST", urlPath, struct{}{}, nil)
+	return
+}
+
 // TurnServer returns turn server details and credentials for the client to use when initiating calls.
 // See http://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-voip-turnserver
 func (cli *Client) TurnServer() (resp *RespTurnServer, err error) {
diff --git a/vendor/maunium.net/go/gomatrix/events.go b/vendor/maunium.net/go/gomatrix/events.go
index 7233c7c..30166cd 100644
--- a/vendor/maunium.net/go/gomatrix/events.go
+++ b/vendor/maunium.net/go/gomatrix/events.go
@@ -1,110 +1,413 @@
 package gomatrix
 
 import (
-	"html"
-	"regexp"
+	"encoding/json"
+	"strings"
+	"sync"
+)
+
+type EventTypeClass int
+
+const (
+	// Normal message events
+	MessageEventType EventTypeClass = iota
+	// State events
+	StateEventType
+	// Ephemeral events
+	EphemeralEventType
+	// Account data events
+	AccountDataEventType
+	// Unknown events
+	UnknownEventType
+)
+
+type EventType struct {
+	Type  string
+	Class EventTypeClass
+}
+
+func NewEventType(name string) EventType {
+	evtType := EventType{Type: name}
+	evtType.Class = evtType.GuessClass()
+	return evtType
+}
+
+func (et *EventType) IsState() bool {
+	return et.Class == StateEventType
+}
+
+func (et *EventType) IsEphemeral() bool {
+	return et.Class == EphemeralEventType
+}
+
+func (et *EventType) IsCustom() bool {
+	return !strings.HasPrefix(et.Type, "m.")
+}
+
+func (et *EventType) GuessClass() EventTypeClass {
+	switch et.Type {
+	case StateAliases.Type, StateCanonicalAlias.Type, StateCreate.Type, StateJoinRules.Type, StateMember.Type,
+		StatePowerLevels.Type, StateRoomName.Type, StateRoomAvatar.Type, StateTopic.Type, StatePinnedEvents.Type:
+		return StateEventType
+	case EphemeralEventReceipt.Type, EphemeralEventTyping.Type:
+		return EphemeralEventType
+	case AccountDataDirectChats.Type, AccountDataPushRules.Type, AccountDataRoomTags.Type:
+		return AccountDataEventType
+	case EventRedaction.Type, EventMessage.Type, EventSticker.Type:
+		return MessageEventType
+	default:
+		return UnknownEventType
+	}
+}
+
+func (et *EventType) UnmarshalJSON(data []byte) error {
+	err := json.Unmarshal(data, &et.Type)
+	if err != nil {
+		return err
+	}
+	et.Class = et.GuessClass()
+	return nil
+}
+
+func (et *EventType) MarshalJSON() ([]byte, error) {
+	return json.Marshal(&et.Type)
+}
+
+func (et *EventType) String() string {
+	return et.Type
+}
+
+// State events
+var (
+	StateAliases        = EventType{"m.room.aliases", StateEventType}
+	StateCanonicalAlias = EventType{"m.room.canonical_alias", StateEventType}
+	StateCreate         = EventType{"m.room.create", StateEventType}
+	StateJoinRules      = EventType{"m.room.join_rules", StateEventType}
+	StateMember         = EventType{"m.room.member", StateEventType}
+	StatePowerLevels    = EventType{"m.room.power_levels", StateEventType}
+	StateRoomName       = EventType{"m.room.name", StateEventType}
+	StateTopic          = EventType{"m.room.topic", StateEventType}
+	StateRoomAvatar     = EventType{"m.room.avatar", StateEventType}
+	StatePinnedEvents   = EventType{"m.room.pinned_events", StateEventType}
+)
+
+// Message events
+var (
+	EventRedaction = EventType{"m.room.redaction", MessageEventType}
+	EventMessage   = EventType{"m.room.message", MessageEventType}
+	EventSticker   = EventType{"m.sticker", MessageEventType}
+)
+
+// Ephemeral events
+var (
+	EphemeralEventReceipt = EventType{"m.receipt", EphemeralEventType}
+	EphemeralEventTyping  = EventType{"m.receipt", EphemeralEventType}
+)
+
+// Account data events
+var (
+	AccountDataDirectChats = EventType{"m.direct", AccountDataEventType}
+	AccountDataPushRules   = EventType{"m.push_rules", AccountDataEventType}
+	AccountDataRoomTags    = EventType{"m.tag", AccountDataEventType}
+)
+
+type MessageType string
+
+// Msgtypes
+const (
+	MsgText     MessageType = "m.text"
+	MsgEmote                = "m.emote"
+	MsgNotice               = "m.notice"
+	MsgImage                = "m.image"
+	MsgLocation             = "m.location"
+	MsgVideo                = "m.video"
+	MsgAudio                = "m.audio"
+	MsgFile                 = "m.file"
+)
+
+type Format string
+
+// Message formats
+const (
+	FormatHTML Format = "org.matrix.custom.html"
 )
 
 // Event represents a single Matrix event.
 type Event struct {
-	StateKey  *string                `json:"state_key,omitempty"` // The state key for the event. Only present on State Events.
-	Sender    string                 `json:"sender"`              // The user ID of the sender of the event
-	Type      string                 `json:"type"`                // The event type
-	Timestamp int64                  `json:"origin_server_ts"`    // The unix timestamp when this message was sent by the origin server
-	ID        string                 `json:"event_id"`            // The unique ID of this event
-	RoomID    string                 `json:"room_id"`             // The room the event was sent to. May be nil (e.g. for presence)
-	Content   map[string]interface{} `json:"content"`             // The JSON content of the event.
-	Redacts   string                 `json:"redacts,omitempty"`   // The event ID that was redacted if a m.room.redaction event
-	Unsigned  Unsigned               `json:"unsigned,omitempty"`  // Unsigned content set by own homeserver.
+	StateKey  *string   `json:"state_key,omitempty"` // The state key for the event. Only present on State Events.
+	Sender    string    `json:"sender"`              // The user ID of the sender of the event
+	Type      EventType `json:"type"`                // The event type
+	Timestamp int64     `json:"origin_server_ts"`    // The unix timestamp when this message was sent by the origin server
+	ID        string    `json:"event_id"`            // The unique ID of this event
+	RoomID    string    `json:"room_id"`             // The room the event was sent to. May be nil (e.g. for presence)
+	Content   Content   `json:"content"`             // The JSON content of the event.
+	Redacts   string    `json:"redacts,omitempty"`   // The event ID that was redacted if a m.room.redaction event
+	Unsigned  Unsigned  `json:"unsigned,omitempty"`  // Unsigned content set by own homeserver.
+
+	InviteRoomState []StrippedState `json:"invite_room_state"`
+}
+
+func (evt *Event) GetStateKey() string {
+	if evt.StateKey != nil {
+		return *evt.StateKey
+	}
+	return ""
+}
+
+type StrippedState struct {
+	Content  Content   `json:"content"`
+	Type     EventType `json:"type"`
+	StateKey string    `json:"state_key"`
 }
 
 type Unsigned struct {
-	PrevContent   map[string]interface{} `json:"prev_content,omitempty"`
-	PrevSender    string                 `json:"prev_sender,omitempty"`
-	ReplacesState string                 `json:"replaces_state,omitempty"`
-	Age           int64                  `json:"age"`
+	PrevContent   *Content `json:"prev_content,omitempty"`
+	PrevSender    string   `json:"prev_sender,omitempty"`
+	ReplacesState string   `json:"replaces_state,omitempty"`
+	Age           int64    `json:"age,omitempty"`
+}
+
+type Content struct {
+	VeryRaw json.RawMessage        `json:"-"`
+	Raw     map[string]interface{} `json:"-"`
+
+	MsgType       MessageType `json:"msgtype,omitempty"`
+	Body          string      `json:"body,omitempty"`
+	Format        Format      `json:"format,omitempty"`
+	FormattedBody string      `json:"formatted_body,omitempty"`
+
+	Info *FileInfo `json:"info,omitempty"`
+	URL  string    `json:"url,omitempty"`
+
+	// Membership key for easy access in m.room.member events
+	Membership Membership `json:"membership,omitempty"`
+
+	RelatesTo *RelatesTo `json:"m.relates_to,omitempty"`
+
+	PowerLevels
+	Member
+	Aliases []string `json:"aliases,omitempty"`
+	CanonicalAlias
+	RoomName
+	RoomTopic
+
+	RoomTags      Tags     `json:"tags,omitempty"`
+	TypingUserIDs []string `json:"user_ids,omitempty"`
 }
 
-// Body returns the value of the "body" key in the event content if it is
-// present and is a string.
-func (event *Event) Body() (body string, ok bool) {
-	value, exists := event.Content["body"]
-	if !exists {
-		return
+type serializableContent Content
+
+func (content *Content) UnmarshalJSON(data []byte) error {
+	content.VeryRaw = data
+	if err := json.Unmarshal(data, &content.Raw); err != nil {
+		return err
 	}
-	body, ok = value.(string)
+	return json.Unmarshal(data, (*serializableContent)(content))
+}
+
+func (content *Content) UnmarshalPowerLevels() (pl PowerLevels, err error) {
+	err = json.Unmarshal(content.VeryRaw, &pl)
 	return
 }
 
-// MessageType returns the value of the "msgtype" key in the event content if
-// it is present and is a string.
-func (event *Event) MessageType() (msgtype string, ok bool) {
-	value, exists := event.Content["msgtype"]
-	if !exists {
-		return
-	}
-	msgtype, ok = value.(string)
+func (content *Content) UnmarshalMember() (m Member, err error) {
+	err = json.Unmarshal(content.VeryRaw, &m)
+	return
+}
+
+func (content *Content) UnmarshalCanonicalAlias() (ca CanonicalAlias, err error) {
+	err = json.Unmarshal(content.VeryRaw, &ca)
 	return
 }
 
-// TextMessage is the contents of a Matrix formated message event.
-type TextMessage struct {
-	MsgType string `json:"msgtype"`
-	Body    string `json:"body"`
+func (content *Content) GetInfo() *FileInfo {
+	if content.Info == nil {
+		content.Info = &FileInfo{}
+	}
+	return content.Info
 }
 
-// ImageInfo contains info about an image - http://matrix.org/docs/spec/client_server/r0.2.0.html#m-image
-type ImageInfo struct {
-	Height   uint   `json:"h,omitempty"`
-	Width    uint   `json:"w,omitempty"`
-	Mimetype string `json:"mimetype,omitempty"`
-	Size     uint   `json:"size,omitempty"`
+type Tags map[string]struct {
+	Order string `json:"order"`
 }
 
-// VideoInfo contains info about a video - http://matrix.org/docs/spec/client_server/r0.2.0.html#m-video
-type VideoInfo struct {
-	Mimetype      string    `json:"mimetype,omitempty"`
-	ThumbnailInfo ImageInfo `json:"thumbnail_info"`
-	ThumbnailURL  string    `json:"thumbnail_url,omitempty"`
-	Height        uint      `json:"h,omitempty"`
-	Width         uint      `json:"w,omitempty"`
-	Duration      uint      `json:"duration,omitempty"`
-	Size          uint      `json:"size,omitempty"`
+type RoomName struct {
+	Name string `json:"name,omitempty"`
+}
+
+type RoomTopic struct {
+	Topic string `json:"topic,omitempty"`
+}
+
+// Membership is an enum specifying the membership state of a room member.
+type Membership string
+
+// The allowed membership states as specified in spec section 10.5.5.
+const (
+	MembershipJoin   Membership = "join"
+	MembershipLeave  Membership = "leave"
+	MembershipInvite Membership = "invite"
+	MembershipBan    Membership = "ban"
+	MembershipKnock  Membership = "knock"
+)
+
+type Member struct {
+	Membership       Membership        `json:"membership,omitempty"`
+	AvatarURL        string            `json:"avatar_url,omitempty"`
+	Displayname      string            `json:"displayname,omitempty"`
+	ThirdPartyInvite *ThirdPartyInvite `json:"third_party_invite,omitempty"`
+	Reason           string            `json:"reason,omitempty"`
+}
+
+type ThirdPartyInvite struct {
+	DisplayName string `json:"display_name"`
+	Signed      struct {
+		Token      string          `json:"token"`
+		Signatures json.RawMessage `json:"signatures"`
+		MXID       string          `json:"mxid"`
+	}
+}
+
+type CanonicalAlias struct {
+	Alias string `json:"alias,omitempty"`
+}
+
+type PowerLevels struct {
+	usersLock    sync.RWMutex   `json:"-"`
+	Users        map[string]int `json:"users,omitempty"`
+	UsersDefault int            `json:"users_default,omitempty"`
+
+	eventsLock    sync.RWMutex   `json:"-"`
+	Events        map[string]int `json:"events,omitempty"`
+	EventsDefault int            `json:"events_default,omitempty"`
+
+	StateDefaultPtr *int `json:"state_default,omitempty"`
+
+	InvitePtr *int `json:"invite,omitempty"`
+	KickPtr   *int `json:"kick,omitempty"`
+	BanPtr    *int `json:"ban,omitempty"`
+	RedactPtr *int `json:"redact,omitempty"`
+}
+
+func (pl *PowerLevels) Invite() int {
+	if pl.InvitePtr != nil {
+		return *pl.InvitePtr
+	}
+	return 50
+}
+
+func (pl *PowerLevels) Kick() int {
+	if pl.KickPtr != nil {
+		return *pl.KickPtr
+	}
+	return 50
 }
 
-// VideoMessage is an m.video  - http://matrix.org/docs/spec/client_server/r0.2.0.html#m-video
-type VideoMessage struct {
-	MsgType string    `json:"msgtype"`
-	Body    string    `json:"body"`
-	URL     string    `json:"url"`
-	Info    VideoInfo `json:"info"`
+func (pl *PowerLevels) Ban() int {
+	if pl.BanPtr != nil {
+		return *pl.BanPtr
+	}
+	return 50
+}
+
+func (pl *PowerLevels) Redact() int {
+	if pl.RedactPtr != nil {
+		return *pl.RedactPtr
+	}
+	return 50
+}
+
+func (pl *PowerLevels) StateDefault() int {
+	if pl.StateDefaultPtr != nil {
+		return *pl.StateDefaultPtr
+	}
+	return 50
+}
+
+func (pl *PowerLevels) GetUserLevel(userID string) int {
+	pl.usersLock.RLock()
+	defer pl.usersLock.RUnlock()
+	level, ok := pl.Users[userID]
+	if !ok {
+		return pl.UsersDefault
+	}
+	return level
+}
+
+func (pl *PowerLevels) SetUserLevel(userID string, level int) {
+	pl.usersLock.Lock()
+	defer pl.usersLock.Unlock()
+	if level == pl.UsersDefault {
+		delete(pl.Users, userID)
+	} else {
+		pl.Users[userID] = level
+	}
+}
+
+func (pl *PowerLevels) EnsureUserLevel(userID string, level int) bool {
+	existingLevel := pl.GetUserLevel(userID)
+	if existingLevel != level {
+		pl.SetUserLevel(userID, level)
+		return true
+	}
+	return false
 }
 
-// ImageMessage is an m.image event
-type ImageMessage struct {
-	MsgType string    `json:"msgtype"`
-	Body    string    `json:"body"`
-	URL     string    `json:"url"`
-	Info    ImageInfo `json:"info"`
+func (pl *PowerLevels) GetEventLevel(eventType EventType) int {
+	pl.eventsLock.RLock()
+	defer pl.eventsLock.RUnlock()
+	level, ok := pl.Events[eventType.String()]
+	if !ok {
+		if eventType.IsState() {
+			return pl.StateDefault()
+		}
+		return pl.EventsDefault
+	}
+	return level
 }
 
-// An HTMLMessage is the contents of a Matrix HTML formated message event.
-type HTMLMessage struct {
-	Body          string `json:"body"`
-	MsgType       string `json:"msgtype"`
-	Format        string `json:"format"`
-	FormattedBody string `json:"formatted_body"`
+func (pl *PowerLevels) SetEventLevel(eventType EventType, level int) {
+	pl.eventsLock.Lock()
+	defer pl.eventsLock.Unlock()
+	if (eventType.IsState() && level == pl.StateDefault()) || (!eventType.IsState() && level == pl.EventsDefault) {
+		delete(pl.Events, eventType.String())
+	} else {
+		pl.Events[eventType.String()] = level
+	}
+}
+
+func (pl *PowerLevels) EnsureEventLevel(eventType EventType, level int) bool {
+	existingLevel := pl.GetEventLevel(eventType)
+	if existingLevel != level {
+		pl.SetEventLevel(eventType, level)
+		return true
+	}
+	return false
 }
 
-var htmlRegex = regexp.MustCompile("<[^<]+?>")
+type FileInfo struct {
+	MimeType      string    `json:"mimetype,omitempty"`
+	ThumbnailInfo *FileInfo `json:"thumbnail_info,omitempty"`
+	ThumbnailURL  string    `json:"thumbnail_url,omitempty"`
+	Height        int       `json:"h,omitempty"`
+	Width         int       `json:"w,omitempty"`
+	Duration      uint      `json:"duration,omitempty"`
+	Size          int       `json:"size,omitempty"`
+}
 
-// GetHTMLMessage returns an HTMLMessage with the body set to a stripped version of the provided HTML, in addition
-// to the provided HTML.
-func GetHTMLMessage(msgtype, htmlText string) HTMLMessage {
-	return HTMLMessage{
-		Body:          html.UnescapeString(htmlRegex.ReplaceAllLiteralString(htmlText, "")),
-		MsgType:       msgtype,
-		Format:        "org.matrix.custom.html",
-		FormattedBody: htmlText,
+func (fileInfo *FileInfo) GetThumbnailInfo() *FileInfo {
+	if fileInfo.ThumbnailInfo == nil {
+		fileInfo.ThumbnailInfo = &FileInfo{}
 	}
+	return fileInfo.ThumbnailInfo
+}
+
+type RelatesTo struct {
+	InReplyTo InReplyTo `json:"m.in_reply_to,omitempty"`
+}
+
+type InReplyTo struct {
+	EventID string `json:"event_id,omitempty"`
+	// Not required, just for future-proofing
+	RoomID string `json:"room_id,omitempty"`
 }
diff --git a/vendor/maunium.net/go/gomatrix/reply.go b/vendor/maunium.net/go/gomatrix/reply.go
new file mode 100644
index 0000000..6985421
--- /dev/null
+++ b/vendor/maunium.net/go/gomatrix/reply.go
@@ -0,0 +1,96 @@
+package gomatrix
+
+import (
+	"fmt"
+	"regexp"
+	"strings"
+
+	"golang.org/x/net/html"
+)
+
+var HTMLReplyFallbackRegex = regexp.MustCompile(`^<mx-reply>[\s\S]+?</mx-reply>`)
+
+func TrimReplyFallbackHTML(html string) string {
+	return HTMLReplyFallbackRegex.ReplaceAllString(html, "")
+}
+
+func TrimReplyFallbackText(text string) string {
+	if !strings.HasPrefix(text, "> ") || !strings.Contains(text, "\n") {
+		return text
+	}
+
+	lines := strings.Split(text, "\n")
+	for len(lines) > 0 && strings.HasPrefix(lines[0], "> ") {
+		lines = lines[1:]
+	}
+	return strings.TrimSpace(strings.Join(lines, "\n"))
+}
+
+func (content *Content) RemoveReplyFallback() {
+	if len(content.GetReplyTo()) > 0 {
+		if content.Format == FormatHTML {
+			content.FormattedBody = TrimReplyFallbackHTML(content.FormattedBody)
+		}
+		content.Body = TrimReplyFallbackText(content.Body)
+	}
+}
+
+func (content *Content) GetReplyTo() string {
+	if content.RelatesTo != nil {
+		return content.RelatesTo.InReplyTo.EventID
+	}
+	return ""
+}
+
+const ReplyFormat = `<mx-reply><blockquote>
+<a href="https://matrix.to/#/%s/%s">In reply to</a>
+<a href="https://matrix.to/#/%s">%s</a>
+%s
+</blockquote></mx-reply>
+`
+
+func (evt *Event) GenerateReplyFallbackHTML() string {
+	body := evt.Content.FormattedBody
+	if len(body) == 0 {
+		body = html.EscapeString(evt.Content.Body)
+	}
+
+	senderDisplayName := evt.Sender
+
+	return fmt.Sprintf(ReplyFormat, evt.RoomID, evt.ID, evt.Sender, senderDisplayName, body)
+}
+
+func (evt *Event) GenerateReplyFallbackText() string {
+	body := evt.Content.Body
+	lines := strings.Split(strings.TrimSpace(body), "\n")
+	firstLine, lines := lines[0], lines[1:]
+
+	senderDisplayName := evt.Sender
+
+	var fallbackText strings.Builder
+	fmt.Fprintf(&fallbackText, "> <%s> %s", senderDisplayName, firstLine)
+	for _, line := range lines {
+		fmt.Fprintf(&fallbackText, "\n> %s", line)
+	}
+	fallbackText.WriteString("\n\n")
+	return fallbackText.String()
+}
+
+func (content *Content) SetReply(inReplyTo *Event) {
+	if content.RelatesTo == nil {
+		content.RelatesTo = &RelatesTo{}
+	}
+	content.RelatesTo.InReplyTo = InReplyTo{
+		EventID: inReplyTo.ID,
+		RoomID:  inReplyTo.RoomID,
+	}
+
+	if content.MsgType == MsgText || content.MsgType == MsgNotice {
+		if len(content.FormattedBody) == 0 || content.Format != FormatHTML {
+			content.FormattedBody = html.EscapeString(content.Body)
+			content.Format = FormatHTML
+		}
+		content.FormattedBody = inReplyTo.GenerateReplyFallbackHTML() + content.FormattedBody
+		content.Body = inReplyTo.GenerateReplyFallbackText() + content.Body
+	}
+}
diff --git a/vendor/maunium.net/go/gomatrix/requests.go b/vendor/maunium.net/go/gomatrix/requests.go
index af99a22..d8e10a6 100644
--- a/vendor/maunium.net/go/gomatrix/requests.go
+++ b/vendor/maunium.net/go/gomatrix/requests.go
@@ -31,7 +31,7 @@ type ReqCreateRoom struct {
 	Invite          []string               `json:"invite,omitempty"`
 	Invite3PID      []ReqInvite3PID        `json:"invite_3pid,omitempty"`
 	CreationContent map[string]interface{} `json:"creation_content,omitempty"`
-	InitialState    []Event                `json:"initial_state,omitempty"`
+	InitialState    []*Event                `json:"initial_state,omitempty"`
 	Preset          string                 `json:"preset,omitempty"`
 	IsDirect        bool                   `json:"is_direct,omitempty"`
 }
@@ -74,5 +74,9 @@ type ReqUnbanUser struct {
 // ReqTyping is the JSON request for https://matrix.org/docs/spec/client_server/r0.2.0.html#put-matrix-client-r0-rooms-roomid-typing-userid
 type ReqTyping struct {
 	Typing  bool  `json:"typing"`
-	Timeout int64 `json:"timeout"`
+	Timeout int64 `json:"timeout,omitempty"`
 }
+
+type ReqPresence struct {
+	Presence string `json:"presence"`
+}
\ No newline at end of file
diff --git a/vendor/maunium.net/go/gomatrix/responses.go b/vendor/maunium.net/go/gomatrix/responses.go
index 6d43bd3..9524d62 100644
--- a/vendor/maunium.net/go/gomatrix/responses.go
+++ b/vendor/maunium.net/go/gomatrix/responses.go
@@ -64,7 +64,7 @@ type RespJoinedMembers struct {
 // RespMessages is the JSON response for https://matrix.org/docs/spec/client_server/r0.2.0.html#get-matrix-client-r0-rooms-roomid-messages
 type RespMessages struct {
 	Start string  `json:"start"`
-	Chunk []Event `json:"chunk"`
+	Chunk []*Event `json:"chunk"`
 	End   string  `json:"end"`
 }
 
diff --git a/vendor/maunium.net/go/gomatrix/room.go b/vendor/maunium.net/go/gomatrix/room.go
index c9b2351..80a91d8 100644
--- a/vendor/maunium.net/go/gomatrix/room.go
+++ b/vendor/maunium.net/go/gomatrix/room.go
@@ -3,7 +3,7 @@ package gomatrix
 // Room represents a single Matrix room.
 type Room struct {
 	ID    string
-	State map[string]map[string]*Event
+	State map[EventType]map[string]*Event
 }
 
 // UpdateState updates the room's current state with the given Event. This will clobber events based
@@ -17,7 +17,7 @@ func (room Room) UpdateState(event *Event) {
 }
 
 // GetStateEvent returns the state event for the given type/state_key combo, or nil.
-func (room Room) GetStateEvent(eventType string, stateKey string) *Event {
+func (room Room) GetStateEvent(eventType EventType, stateKey string) *Event {
 	stateEventMap, _ := room.State[eventType]
 	event, _ := stateEventMap[stateKey]
 	return event
@@ -25,17 +25,11 @@ func (room Room) GetStateEvent(eventType string, stateKey string) *Event {
 
 // GetMembershipState returns the membership state of the given user ID in this room. If there is
 // no entry for this member, 'leave' is returned for consistency with left users.
-func (room Room) GetMembershipState(userID string) string {
-	state := "leave"
-	event := room.GetStateEvent("m.room.member", userID)
+func (room Room) GetMembershipState(userID string) Membership {
+	state := MembershipLeave
+	event := room.GetStateEvent(StateMember, userID)
 	if event != nil {
-		membershipState, found := event.Content["membership"]
-		if found {
-			mState, isString := membershipState.(string)
-			if isString {
-				state = mState
-			}
-		}
+		state = event.Content.Membership
 	}
 	return state
 }
@@ -45,6 +39,6 @@ func NewRoom(roomID string) *Room {
 	// Init the State map and return a pointer to the Room
 	return &Room{
 		ID:    roomID,
-		State: make(map[string]map[string]*Event),
+		State: make(map[EventType]map[string]*Event),
 	}
 }
diff --git a/vendor/maunium.net/go/gomatrix/sync.go b/vendor/maunium.net/go/gomatrix/sync.go
index e1233a4..09170d7 100644
--- a/vendor/maunium.net/go/gomatrix/sync.go
+++ b/vendor/maunium.net/go/gomatrix/sync.go
@@ -25,7 +25,7 @@ type Syncer interface {
 type DefaultSyncer struct {
 	UserID    string
 	Store     Storer
-	listeners map[string][]OnEventListener // event type to listeners array
+	listeners map[EventType][]OnEventListener // event type to listeners array
 }
 
 // OnEventListener can be used with DefaultSyncer.OnEventType to be informed of incoming events.
@@ -36,7 +36,7 @@ func NewDefaultSyncer(userID string, store Storer) *DefaultSyncer {
 	return &DefaultSyncer{
 		UserID:    userID,
 		Store:     store,
-		listeners: make(map[string][]OnEventListener),
+		listeners: make(map[EventType][]OnEventListener),
 	}
 }
 
@@ -88,7 +88,7 @@ func (s *DefaultSyncer) ProcessResponse(res *RespSync, since string) (err error)
 
 // OnEventType allows callers to be notified when there are new events for the given event type.
 // There are no duplicate checks.
-func (s *DefaultSyncer) OnEventType(eventType string, callback OnEventListener) {
+func (s *DefaultSyncer) OnEventType(eventType EventType, callback OnEventListener) {
 	_, exists := s.listeners[eventType]
 	if !exists {
 		s.listeners[eventType] = []OnEventListener{}
@@ -112,13 +112,8 @@ func (s *DefaultSyncer) shouldProcessResponse(resp *RespSync, since string) bool
 	for roomID, roomData := range resp.Rooms.Join {
 		for i := len(roomData.Timeline.Events) - 1; i >= 0; i-- {
 			e := roomData.Timeline.Events[i]
-			if e.Type == "m.room.member" && e.StateKey != nil && *e.StateKey == s.UserID {
-				m := e.Content["membership"]
-				mship, ok := m.(string)
-				if !ok {
-					continue
-				}
-				if mship == "join" {
+			if e.Type == StateMember && e.GetStateKey() == s.UserID {
+				if e.Content.Membership == "join" {
 					_, ok := resp.Rooms.Join[roomID]
 					if !ok {
 						continue
diff --git a/vendor/maunium.net/go/maulogger/LICENSE b/vendor/maunium.net/go/maulogger/LICENSE
new file mode 100644
index 0000000..c9739fb
--- /dev/null
+++ b/vendor/maunium.net/go/maulogger/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 Tulir Asokan
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/maunium.net/go/maulogger/README.md b/vendor/maunium.net/go/maulogger/README.md
new file mode 100644
index 0000000..68fe253
--- /dev/null
+++ b/vendor/maunium.net/go/maulogger/README.md
@@ -0,0 +1,6 @@
+# maulogger
+A logger in Go.
+
+Docs: [godoc.org/maunium.net/go/maulogger](https://godoc.org/maunium.net/go/maulogger)
+
+Go get: `go get maunium.net/go/maulogger`
diff --git a/vendor/maunium.net/go/maulogger/logger.go b/vendor/maunium.net/go/maulogger/logger.go
new file mode 100644
index 0000000..e887237
--- /dev/null
+++ b/vendor/maunium.net/go/maulogger/logger.go
@@ -0,0 +1,219 @@
+package maulog
+
+import (
+	"bufio"
+	"fmt"
+	"os"
+	"time"
+)
+
+// Level is the severity level of a log entry.
+type Level struct {
+	Name            string
+	Severity, Color int
+}
+
+// LogWriter writes to the log with an optional prefix
+type LogWriter struct {
+	Level  Level
+	Prefix string
+}
+
+func (lw LogWriter) Write(p []byte) (n int, err error) {
+	log(lw.Level, fmt.Sprint(lw.Prefix, string(p)))
+	return len(p), nil
+}
+
+// GetColor gets the ANSI escape color code for the log level.
+func (lvl Level) GetColor() []byte {
+	if lvl.Color < 0 {
+		return []byte("")
+	}
+	return []byte(fmt.Sprintf("\x1b[%dm", lvl.Color))
+}
+
+// GetReset gets the ANSI escape reset code.
+func (lvl Level) GetReset() []byte {
+	if lvl.Color < 0 {
+		return []byte("")
+	}
+	return []byte("\x1b[0m")
+}
+
+var (
+	// Debug is the level for debug messages.
+	Debug = Level{Name: "DEBUG", Color: 36, Severity: 0}
+	// Info is the level for basic log messages.
+	Info = Level{Name: "INFO", Color: -1, Severity: 10}
+	// Warn is the level saying that something went wrong, but the program will continue operating mostly normally.
+	Warn = Level{Name: "WARN", Color: 33, Severity: 50}
+	// Error is the level saying that something went wrong and the program may not operate as expected, but will still continue.
+	Error = Level{Name: "ERROR", Color: 31, Severity: 100}
+	// Fatal is the level saying that something went wrong and the program will not operate normally.
+	Fatal = Level{Name: "FATAL", Color: 35, Severity: 9001}
+)
+
+// PrintLevel tells the first severity level at which messages should be printed to stdout
+var PrintLevel = 10
+
+// PrintDebug means PrintLevel = 0, kept for backwards compatibility
+var PrintDebug = false
+
+// FileTimeformat is the time format used in log file names.
+var FileTimeformat = "2006-01-02"
+
+// FileformatArgs is an undocumented integer.
+var FileformatArgs = 3
+
+// Fileformat is the format used for log file names.
+var Fileformat = func(now string, i int) string { return fmt.Sprintf("%[1]s-%02[2]d.log", now, i) }
+
+// Timeformat is the time format used in logging.
+var Timeformat = "15:04:05 02.01.2006"
+
+var writer *bufio.Writer
+var lines int
+
+// InitWithWriter initializes MauLogger with the given writer.
+func InitWithWriter(w *bufio.Writer) {
+	writer = w
+}
+
+// Init initializes MauLogger.
+func Init() {
+	// Find the next file name.
+	now := time.Now().Format(FileTimeformat)
+	i := 1
+	for ; ; i++ {
+		if _, err := os.Stat(Fileformat(now, i)); os.IsNotExist(err) {
+			break
+		}
+		if i == 99 {
+			i = 1
+			break
+		}
+	}
+	// Open the file
+	file, err := os.OpenFile(Fileformat(now, i), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0700)
+	if err != nil {
+		panic(err)
+	}
+	if file == nil {
+		panic(os.ErrInvalid)
+	}
+	// Create a writer
+	writer = bufio.NewWriter(file)
+}
+
+// Debugf formats and logs a debug message.
+func Debugf(message string, args ...interface{}) {
+	logln(Debug, fmt.Sprintf(message, args...))
+}
+
+// Printf formats and logs a string in the Info log level.
+func Printf(message string, args ...interface{}) {
+	Infof(message, args...)
+}
+
+// Infof formats and logs a string in the Info log level.
+func Infof(message string, args ...interface{}) {
+	logln(Info, fmt.Sprintf(message, args...))
+}
+
+// Warnf formats and logs a string in the Warn log level.
+func Warnf(message string, args ...interface{}) {
+	logln(Warn, fmt.Sprintf(message, args...))
+}
+
+// Errorf formats and logs a string in the Error log level.
+func Errorf(message string, args ...interface{}) {
+	logln(Error, fmt.Sprintf(message, args...))
+}
+
+// Fatalf formats and logs a string in the Fatal log level.
+func Fatalf(message string, args ...interface{}) {
+	logln(Fatal, fmt.Sprintf(message, args...))
+}
+
+// Logf formats and logs a message in the given log level.
+func Logf(level Level, message string, args ...interface{}) {
+	logln(level, fmt.Sprintf(message, args...))
+}
+
+// Debugln logs a debug message.
+func Debugln(args ...interface{}) {
+	log(Debug, fmt.Sprintln(args...))
+}
+
+// Println logs a string in the Info log level.
+func Println(args ...interface{}) {
+	Infoln(args...)
+}
+
+// Infoln logs a string in the Info log level.
+func Infoln(args ...interface{}) {
+	log(Info, fmt.Sprintln(args...))
+}
+
+// Warnln logs a string in the Warn log level.
+func Warnln(args ...interface{}) {
+	log(Warn, fmt.Sprintln(args...))
+}
+
+// Errorln logs a string in the Error log level.
+func Errorln(args ...interface{}) {
+	log(Error, fmt.Sprintln(args...))
+}
+
+// Fatalln logs a string in the Fatal log level.
+func Fatalln(args ...interface{}) {
+	log(Fatal, fmt.Sprintln(args...))
+}
+
+// Logln logs a message in the given log level.
+func Logln(level Level, args ...interface{}) {
+	log(level, fmt.Sprintln(args...))
+}
+
+func logln(level Level, message string) {
+	log(level, fmt.Sprintln(message))
+}
+
+func log(level Level, message string) {
+	// Prefix the message with the timestamp and log level.
+	msg := []byte(fmt.Sprintf("[%[1]s] [%[2]s] %[3]s", time.Now().Format(Timeformat), level.Name, message))
+
+	if writer != nil {
+		// Write it to the log file.
+		_, err := writer.Write(msg)
+		if err != nil {
+			panic(err)
+		}
+		lines++
+		// Flush the file if needed
+		if lines == 5 {
+			lines = 0
+			writer.Flush()
+		}
+	}
+
+	// Print to stdout using correct color
+	if level.Severity >= PrintLevel || PrintDebug {
+		if level.Severity >= Error.Severity {
+			os.Stderr.Write(level.GetColor())
+			os.Stderr.Write(msg)
+			os.Stderr.Write(level.GetReset())
+		} else {
+			os.Stdout.Write(level.GetColor())
+			os.Stdout.Write(msg)
+			os.Stdout.Write(level.GetReset())
+		}
+	}
+}
+
+// Shutdown cleans up the logger.
+func Shutdown() {
+	if writer != nil {
+		writer.Flush()
+	}
+}
-- 
cgit v1.2.3-70-g09d2