diff --git a/.woodpecker/main.yml b/.woodpecker/main.yml index e92cd0998..646abb28e 100644 --- a/.woodpecker/main.yml +++ b/.woodpecker/main.yml @@ -49,8 +49,6 @@ pipeline: - go get github.com/woodpecker-ci/togo - (cd web/; go generate ./...) - make release - when: - event: [push, tag] # publish-server-alpine: # image: plugins/docker diff --git a/go.mod b/go.mod index 6f0c95c40..97e9a5332 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,8 @@ require ( docker.io/go-docker v1.0.0 github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 // indirect + github.com/bmatcuk/doublestar v1.3.4 + github.com/bradrydzewski/togo v0.0.0-20180401185031-50a0e4726e74 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect github.com/dgrijalva/jwt-go v0.0.0-20150904212456-c1da56349675 github.com/dimfeld/httptreemux v5.0.1+incompatible @@ -55,6 +57,7 @@ require ( github.com/tevino/abool v0.0.0-20170917061928-9b9efcf221b5 github.com/urfave/cli v1.22.4 github.com/woodpecker-ci/expr v0.0.0-20210628233344-164b8b3d0915 + github.com/woodpecker-ci/togo v0.0.0-20180401185031-50a0e4726e74 golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 golang.org/x/net v0.0.0-20210825183410-e898025ed96a golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d diff --git a/go.sum b/go.sum index 07a132dac..f44079b56 100644 --- a/go.sum +++ b/go.sum @@ -18,6 +18,10 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bmatcuk/doublestar v1.3.4 h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQrS0= +github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE= +github.com/bradrydzewski/togo v0.0.0-20180401185031-50a0e4726e74 h1:fE72rAOk9gpizJL3mNv+Ez+3yt/GCoZWtkKEPLTZvvM= +github.com/bradrydzewski/togo v0.0.0-20180401185031-50a0e4726e74/go.mod h1:+zgWTTgi3saXD5N9SSA+LYteMbFoIJKJ9WEPXoV0jQA= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -227,6 +231,8 @@ github.com/urfave/cli v1.22.4 h1:u7tSpNPPswAFymm8IehJhy4uJMlUuU/GmqSkvJ1InXA= github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/woodpecker-ci/expr v0.0.0-20210628233344-164b8b3d0915 h1:9zBOoKSR9CBeYoKQv6LFIuImg8lorCjh8XzK72bJMRg= github.com/woodpecker-ci/expr v0.0.0-20210628233344-164b8b3d0915/go.mod h1:PbzlZ93HrA1cf16OUP1vckAPq57gtF+ccnwZeDkmC9s= +github.com/woodpecker-ci/togo v0.0.0-20180401185031-50a0e4726e74 h1:q/tWgA3hMWrAQqsS4yfhc0+w4RevBGr9ghem/bFFDRY= +github.com/woodpecker-ci/togo v0.0.0-20180401185031-50a0e4726e74/go.mod h1:lykh/ei/caPO6sv4NN+pqnDTo8kEKhZcnhafN8GhGNs= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= diff --git a/tools.go b/tools.go new file mode 100644 index 000000000..d26da3563 --- /dev/null +++ b/tools.go @@ -0,0 +1,10 @@ +//go:build tools +// +build tools + +// this file make sure tools are vendored too +package tools + +import ( + _ "github.com/bmatcuk/doublestar" + _ "github.com/woodpecker-ci/togo" +) diff --git a/vendor/github.com/bmatcuk/doublestar/.gitignore b/vendor/github.com/bmatcuk/doublestar/.gitignore new file mode 100644 index 000000000..af212ecc2 --- /dev/null +++ b/vendor/github.com/bmatcuk/doublestar/.gitignore @@ -0,0 +1,32 @@ +# vi +*~ +*.swp +*.swo + +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof + +# test directory +test/ diff --git a/vendor/github.com/bmatcuk/doublestar/.travis.yml b/vendor/github.com/bmatcuk/doublestar/.travis.yml new file mode 100644 index 000000000..78a90e7b5 --- /dev/null +++ b/vendor/github.com/bmatcuk/doublestar/.travis.yml @@ -0,0 +1,20 @@ +language: go + +go: + - 1.12 + - 1.13 + - 1.14 + +os: + - linux + - windows + +before_install: + - go get -t -v ./... + +script: + - go test -race -coverprofile=coverage.txt -covermode=atomic + +after_success: + - bash <(curl -s https://codecov.io/bash) + diff --git a/vendor/github.com/bmatcuk/doublestar/LICENSE b/vendor/github.com/bmatcuk/doublestar/LICENSE new file mode 100644 index 000000000..309c9d1d1 --- /dev/null +++ b/vendor/github.com/bmatcuk/doublestar/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2014 Bob Matcuk + +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/github.com/bmatcuk/doublestar/README.md b/vendor/github.com/bmatcuk/doublestar/README.md new file mode 100644 index 000000000..074b77d85 --- /dev/null +++ b/vendor/github.com/bmatcuk/doublestar/README.md @@ -0,0 +1,140 @@ +# doublestar + +Path pattern matching and globbing supporting `doublestar` (`**`) patterns. + +![Release](https://img.shields.io/github/release/bmatcuk/doublestar.svg?branch=master) +[![Build Status](https://travis-ci.org/bmatcuk/doublestar.svg?branch=master)](https://travis-ci.org/bmatcuk/doublestar) +[![codecov.io](https://img.shields.io/codecov/c/github/bmatcuk/doublestar.svg?branch=master)](https://codecov.io/github/bmatcuk/doublestar?branch=master) + +## About + +**doublestar** is a [golang](http://golang.org/) implementation of path pattern +matching and globbing with support for "doublestar" (aka globstar: `**`) +patterns. + +doublestar patterns match files and directories recursively. For example, if +you had the following directory structure: + +```bash +grandparent +`-- parent + |-- child1 + `-- child2 +``` + +You could find the children with patterns such as: `**/child*`, +`grandparent/**/child?`, `**/parent/*`, or even just `**` by itself (which will +return all files and directories recursively). + +Bash's globstar is doublestar's inspiration and, as such, works similarly. +Note that the doublestar must appear as a path component by itself. A pattern +such as `/path**` is invalid and will be treated the same as `/path*`, but +`/path*/**` should achieve the desired result. Additionally, `/path/**` will +match all directories and files under the path directory, but `/path/**/` will +only match directories. + +## Installation + +**doublestar** can be installed via `go get`: + +```bash +go get github.com/bmatcuk/doublestar +``` + +To use it in your code, you must import it: + +```go +import "github.com/bmatcuk/doublestar" +``` + +## Usage + +### Match + +```go +func Match(pattern, name string) (bool, error) +``` + +Match returns true if `name` matches the file name `pattern` +([see below](#patterns)). `name` and `pattern` are split on forward slash (`/`) +characters and may be relative or absolute. + +Note: `Match()` is meant to be a drop-in replacement for `path.Match()`. As +such, it always uses `/` as the path separator. If you are writing code that +will run on systems where `/` is not the path separator (such as Windows), you +want to use `PathMatch()` (below) instead. + + +### PathMatch + +```go +func PathMatch(pattern, name string) (bool, error) +``` + +PathMatch returns true if `name` matches the file name `pattern` +([see below](#patterns)). The difference between Match and PathMatch is that +PathMatch will automatically use your system's path separator to split `name` +and `pattern`. + +`PathMatch()` is meant to be a drop-in replacement for `filepath.Match()`. + +### Glob + +```go +func Glob(pattern string) ([]string, error) +``` + +Glob finds all files and directories in the filesystem that match `pattern` +([see below](#patterns)). `pattern` may be relative (to the current working +directory), or absolute. + +`Glob()` is meant to be a drop-in replacement for `filepath.Glob()`. + +### Patterns + +**doublestar** supports the following special terms in the patterns: + +Special Terms | Meaning +------------- | ------- +`*` | matches any sequence of non-path-separators +`**` | matches any sequence of characters, including path separators +`?` | matches any single non-path-separator character +`[class]` | matches any single non-path-separator character against a class of characters ([see below](#character-classes)) +`{alt1,...}` | matches a sequence of characters if one of the comma-separated alternatives matches + +Any character with a special meaning can be escaped with a backslash (`\`). + +#### Character Classes + +Character classes support the following: + +Class | Meaning +---------- | ------- +`[abc]` | matches any single character within the set +`[a-z]` | matches any single character in the range +`[^class]` | matches any single character which does *not* match the class + +### Abstracting the `os` package + +**doublestar** by default uses the `Open`, `Stat`, and `Lstat`, functions and +`PathSeparator` value from the standard library's `os` package. To abstract +this, for example to be able to perform tests of Windows paths on Linux, or to +interoperate with your own filesystem code, it includes the functions `GlobOS` +and `PathMatchOS` which are identical to `Glob` and `PathMatch` except that they +operate on an `OS` interface: + +```go +type OS interface { + Lstat(name string) (os.FileInfo, error) + Open(name string) (*os.File, error) + PathSeparator() rune + Stat(name string) (os.FileInfo, error) +} +``` + +`StandardOS` is a value that implements this interface by calling functions in +the standard library's `os` package. + +## License + +[MIT License](LICENSE) diff --git a/vendor/github.com/bmatcuk/doublestar/doublestar.go b/vendor/github.com/bmatcuk/doublestar/doublestar.go new file mode 100644 index 000000000..206e01202 --- /dev/null +++ b/vendor/github.com/bmatcuk/doublestar/doublestar.go @@ -0,0 +1,684 @@ +package doublestar + +import ( + "fmt" + "os" + "path" + "path/filepath" + "sort" + "strings" + "unicode/utf8" +) + +// An OS abstracts functions in the standard library's os package. +type OS interface { + Lstat(name string) (os.FileInfo, error) + Open(name string) (*os.File, error) + PathSeparator() rune + Stat(name string) (os.FileInfo, error) +} + +// StandardOS is a value that implements the OS interface by calling functions +// in the standard libray's os package. +var StandardOS OS = standardOS{} + +// A standardOS implements OS by calling functions in the standard library's os +// package. +type standardOS struct{} + +func (standardOS) Lstat(name string) (os.FileInfo, error) { return os.Lstat(name) } +func (standardOS) Open(name string) (*os.File, error) { return os.Open(name) } +func (standardOS) PathSeparator() rune { return os.PathSeparator } +func (standardOS) Stat(name string) (os.FileInfo, error) { return os.Stat(name) } + +// ErrBadPattern indicates a pattern was malformed. +var ErrBadPattern = path.ErrBadPattern + +// Split a path on the given separator, respecting escaping. +func splitPathOnSeparator(path string, separator rune) (ret []string) { + idx := 0 + if separator == '\\' { + // if the separator is '\\', then we can just split... + ret = strings.Split(path, string(separator)) + idx = len(ret) + } else { + // otherwise, we need to be careful of situations where the separator was escaped + cnt := strings.Count(path, string(separator)) + if cnt == 0 { + return []string{path} + } + + ret = make([]string, cnt+1) + pathlen := len(path) + separatorLen := utf8.RuneLen(separator) + emptyEnd := false + for start := 0; start < pathlen; { + end := indexRuneWithEscaping(path[start:], separator) + if end == -1 { + emptyEnd = false + end = pathlen + } else { + emptyEnd = true + end += start + } + ret[idx] = path[start:end] + start = end + separatorLen + idx++ + } + + // If the last rune is a path separator, we need to append an empty string to + // represent the last, empty path component. By default, the strings from + // make([]string, ...) will be empty, so we just need to icrement the count + if emptyEnd { + idx++ + } + } + + return ret[:idx] +} + +// Find the first index of a rune in a string, +// ignoring any times the rune is escaped using "\". +func indexRuneWithEscaping(s string, r rune) int { + end := strings.IndexRune(s, r) + if end == -1 { + return -1 + } + if end > 0 && s[end-1] == '\\' { + start := end + utf8.RuneLen(r) + end = indexRuneWithEscaping(s[start:], r) + if end != -1 { + end += start + } + } + return end +} + +// Find the last index of a rune in a string, +// ignoring any times the rune is escaped using "\". +func lastIndexRuneWithEscaping(s string, r rune) int { + end := strings.LastIndex(s, string(r)) + if end == -1 { + return -1 + } + if end > 0 && s[end-1] == '\\' { + end = lastIndexRuneWithEscaping(s[:end-1], r) + } + return end +} + +// Find the index of the first instance of one of the unicode characters in +// chars, ignoring any times those characters are escaped using "\". +func indexAnyWithEscaping(s, chars string) int { + end := strings.IndexAny(s, chars) + if end == -1 { + return -1 + } + if end > 0 && s[end-1] == '\\' { + _, adj := utf8.DecodeRuneInString(s[end:]) + start := end + adj + end = indexAnyWithEscaping(s[start:], chars) + if end != -1 { + end += start + } + } + return end +} + +// Split a set of alternatives such as {alt1,alt2,...} and returns the index of +// the rune after the closing curly brace. Respects nested alternatives and +// escaped runes. +func splitAlternatives(s string) (ret []string, idx int) { + ret = make([]string, 0, 2) + idx = 0 + slen := len(s) + braceCnt := 1 + esc := false + start := 0 + for braceCnt > 0 { + if idx >= slen { + return nil, -1 + } + + sRune, adj := utf8.DecodeRuneInString(s[idx:]) + if esc { + esc = false + } else if sRune == '\\' { + esc = true + } else if sRune == '{' { + braceCnt++ + } else if sRune == '}' { + braceCnt-- + } else if sRune == ',' && braceCnt == 1 { + ret = append(ret, s[start:idx]) + start = idx + adj + } + + idx += adj + } + ret = append(ret, s[start:idx-1]) + return +} + +// Returns true if the pattern is "zero length", meaning +// it could match zero or more characters. +func isZeroLengthPattern(pattern string) (ret bool, err error) { + // * can match zero + if pattern == "" || pattern == "*" || pattern == "**" { + return true, nil + } + + // an alternative with zero length can match zero, for example {,x} - the + // first alternative has zero length + r, adj := utf8.DecodeRuneInString(pattern) + if r == '{' { + options, endOptions := splitAlternatives(pattern[adj:]) + if endOptions == -1 { + return false, ErrBadPattern + } + if ret, err = isZeroLengthPattern(pattern[adj+endOptions:]); !ret || err != nil { + return + } + for _, o := range options { + if ret, err = isZeroLengthPattern(o); ret || err != nil { + return + } + } + } + + return false, nil +} + +// Match returns true if name matches the shell file name pattern. +// The pattern syntax is: +// +// pattern: +// { term } +// term: +// '*' matches any sequence of non-path-separators +// '**' matches any sequence of characters, including +// path separators. +// '?' matches any single non-path-separator character +// '[' [ '^' ] { character-range } ']' +// character class (must be non-empty) +// '{' { term } [ ',' { term } ... ] '}' +// c matches character c (c != '*', '?', '\\', '[') +// '\\' c matches character c +// +// character-range: +// c matches character c (c != '\\', '-', ']') +// '\\' c matches character c +// lo '-' hi matches character c for lo <= c <= hi +// +// Match requires pattern to match all of name, not just a substring. +// The path-separator defaults to the '/' character. The only possible +// returned error is ErrBadPattern, when pattern is malformed. +// +// Note: this is meant as a drop-in replacement for path.Match() which +// always uses '/' as the path separator. If you want to support systems +// which use a different path separator (such as Windows), what you want +// is the PathMatch() function below. +// +func Match(pattern, name string) (bool, error) { + return matchWithSeparator(pattern, name, '/') +} + +// PathMatch is like Match except that it uses your system's path separator. +// For most systems, this will be '/'. However, for Windows, it would be '\\'. +// Note that for systems where the path separator is '\\', escaping is +// disabled. +// +// Note: this is meant as a drop-in replacement for filepath.Match(). +// +func PathMatch(pattern, name string) (bool, error) { + return PathMatchOS(StandardOS, pattern, name) +} + +// PathMatchOS is like PathMatch except that it uses vos's path separator. +func PathMatchOS(vos OS, pattern, name string) (bool, error) { + pattern = filepath.ToSlash(pattern) + return matchWithSeparator(pattern, name, vos.PathSeparator()) +} + +// Match returns true if name matches the shell file name pattern. +// The pattern syntax is: +// +// pattern: +// { term } +// term: +// '*' matches any sequence of non-path-separators +// '**' matches any sequence of characters, including +// path separators. +// '?' matches any single non-path-separator character +// '[' [ '^' ] { character-range } ']' +// character class (must be non-empty) +// '{' { term } [ ',' { term } ... ] '}' +// c matches character c (c != '*', '?', '\\', '[') +// '\\' c matches character c +// +// character-range: +// c matches character c (c != '\\', '-', ']') +// '\\' c matches character c, unless separator is '\\' +// lo '-' hi matches character c for lo <= c <= hi +// +// Match requires pattern to match all of name, not just a substring. +// The only possible returned error is ErrBadPattern, when pattern +// is malformed. +// +func matchWithSeparator(pattern, name string, separator rune) (bool, error) { + nameComponents := splitPathOnSeparator(name, separator) + return doMatching(pattern, nameComponents) +} + +func doMatching(pattern string, nameComponents []string) (matched bool, err error) { + // check for some base-cases + patternLen, nameLen := len(pattern), len(nameComponents) + if patternLen == 0 && nameLen == 0 { + return true, nil + } + if patternLen == 0 { + if nameLen == 1 && nameComponents[0] == "" { + return true, nil + } else if nameLen == 0 { + return false, nil + } + } + + slashIdx := indexRuneWithEscaping(pattern, '/') + lastComponent := slashIdx == -1 + if lastComponent { + slashIdx = len(pattern) + } + if pattern[:slashIdx] == "**" { + // if our last pattern component is a doublestar, we're done - + // doublestar will match any remaining name components, if any. + if lastComponent { + return true, nil + } + + // otherwise, try matching remaining components + for nameIdx := 0; nameIdx < nameLen; nameIdx++ { + if m, _ := doMatching(pattern[slashIdx+1:], nameComponents[nameIdx:]); m { + return true, nil + } + } + return false, nil + } + + var matches []string + matches, err = matchComponent(pattern, nameComponents[0]) + if matches == nil || err != nil { + return + } + if len(matches) == 0 && nameLen == 1 { + return true, nil + } + + if nameLen > 1 { + for _, alt := range matches { + matched, err = doMatching(alt, nameComponents[1:]) + if matched || err != nil { + return + } + } + } + + return false, nil +} + +// Glob returns the names of all files matching pattern or nil +// if there is no matching file. The syntax of pattern is the same +// as in Match. The pattern may describe hierarchical names such as +// /usr/*/bin/ed (assuming the Separator is '/'). +// +// Glob ignores file system errors such as I/O errors reading directories. +// The only possible returned error is ErrBadPattern, when pattern +// is malformed. +// +// Your system path separator is automatically used. This means on +// systems where the separator is '\\' (Windows), escaping will be +// disabled. +// +// Note: this is meant as a drop-in replacement for filepath.Glob(). +// +func Glob(pattern string) (matches []string, err error) { + return GlobOS(StandardOS, pattern) +} + +// GlobOS is like Glob except that it operates on vos. +func GlobOS(vos OS, pattern string) (matches []string, err error) { + if len(pattern) == 0 { + return nil, nil + } + + // if the pattern starts with alternatives, we need to handle that here - the + // alternatives may be a mix of relative and absolute + if pattern[0] == '{' { + options, endOptions := splitAlternatives(pattern[1:]) + if endOptions == -1 { + return nil, ErrBadPattern + } + for _, o := range options { + m, e := GlobOS(vos, o+pattern[endOptions+1:]) + if e != nil { + return nil, e + } + matches = append(matches, m...) + } + return matches, nil + } + + // If the pattern is relative or absolute and we're on a non-Windows machine, + // volumeName will be an empty string. If it is absolute and we're on a + // Windows machine, volumeName will be a drive letter ("C:") for filesystem + // paths or \\\ for UNC paths. + isAbs := filepath.IsAbs(pattern) || pattern[0] == '\\' || pattern[0] == '/' + volumeName := filepath.VolumeName(pattern) + isWindowsUNC := strings.HasPrefix(volumeName, `\\`) + if isWindowsUNC || isAbs { + startIdx := len(volumeName) + 1 + return doGlob(vos, fmt.Sprintf("%s%s", volumeName, string(vos.PathSeparator())), filepath.ToSlash(pattern[startIdx:]), matches) + } + + // otherwise, it's a relative pattern + return doGlob(vos, ".", filepath.ToSlash(pattern), matches) +} + +// Perform a glob +func doGlob(vos OS, basedir, pattern string, matches []string) (m []string, e error) { + m = matches + e = nil + + // if the pattern starts with any path components that aren't globbed (ie, + // `path/to/glob*`), we can skip over the un-globbed components (`path/to` in + // our example). + globIdx := indexAnyWithEscaping(pattern, "*?[{\\") + if globIdx > 0 { + globIdx = lastIndexRuneWithEscaping(pattern[:globIdx], '/') + } else if globIdx == -1 { + globIdx = lastIndexRuneWithEscaping(pattern, '/') + } + if globIdx > 0 { + basedir = filepath.Join(basedir, pattern[:globIdx]) + pattern = pattern[globIdx+1:] + } + + // Lstat will return an error if the file/directory doesn't exist + fi, err := vos.Lstat(basedir) + if err != nil { + return + } + + // if the pattern is empty, we've found a match + if len(pattern) == 0 { + m = append(m, basedir) + return + } + + // otherwise, we need to check each item in the directory... + + // first, if basedir is a symlink, follow it... + if (fi.Mode() & os.ModeSymlink) != 0 { + fi, err = vos.Stat(basedir) + if err != nil { + return + } + } + + // confirm it's a directory... + if !fi.IsDir() { + return + } + + files, err := filesInDir(vos, basedir) + if err != nil { + return + } + + sort.Slice(files, func(i, j int) bool { return files[i].Name() < files[j].Name() }) + + slashIdx := indexRuneWithEscaping(pattern, '/') + lastComponent := slashIdx == -1 + if lastComponent { + slashIdx = len(pattern) + } + if pattern[:slashIdx] == "**" { + // if the current component is a doublestar, we'll try depth-first + for _, file := range files { + // if symlink, we may want to follow + if (file.Mode() & os.ModeSymlink) != 0 { + file, err = vos.Stat(filepath.Join(basedir, file.Name())) + if err != nil { + continue + } + } + + if file.IsDir() { + // recurse into directories + if lastComponent { + m = append(m, filepath.Join(basedir, file.Name())) + } + m, e = doGlob(vos, filepath.Join(basedir, file.Name()), pattern, m) + } else if lastComponent { + // if the pattern's last component is a doublestar, we match filenames, too + m = append(m, filepath.Join(basedir, file.Name())) + } + } + if lastComponent { + return // we're done + } + + pattern = pattern[slashIdx+1:] + } + + // check items in current directory and recurse + var match []string + for _, file := range files { + match, e = matchComponent(pattern, file.Name()) + if e != nil { + return + } + if match != nil { + if len(match) == 0 { + m = append(m, filepath.Join(basedir, file.Name())) + } else { + for _, alt := range match { + m, e = doGlob(vos, filepath.Join(basedir, file.Name()), alt, m) + } + } + } + } + return +} + +func filesInDir(vos OS, dirPath string) (files []os.FileInfo, e error) { + dir, err := vos.Open(dirPath) + if err != nil { + return nil, nil + } + defer func() { + if err := dir.Close(); e == nil { + e = err + } + }() + + files, err = dir.Readdir(-1) + if err != nil { + return nil, nil + } + + return +} + +// Attempt to match a single path component with a pattern. Note that the +// pattern may include multiple components but that the "name" is just a single +// path component. The return value is a slice of patterns that should be +// checked against subsequent path components or nil, indicating that the +// pattern does not match this path. It is assumed that pattern components are +// separated by '/' +func matchComponent(pattern, name string) ([]string, error) { + // check for matches one rune at a time + patternLen, nameLen := len(pattern), len(name) + patIdx, nameIdx := 0, 0 + for patIdx < patternLen && nameIdx < nameLen { + patRune, patAdj := utf8.DecodeRuneInString(pattern[patIdx:]) + nameRune, nameAdj := utf8.DecodeRuneInString(name[nameIdx:]) + if patRune == '/' { + patIdx++ + break + } else if patRune == '\\' { + // handle escaped runes, only if separator isn't '\\' + patIdx += patAdj + patRune, patAdj = utf8.DecodeRuneInString(pattern[patIdx:]) + if patRune == utf8.RuneError { + return nil, ErrBadPattern + } else if patRune == nameRune { + patIdx += patAdj + nameIdx += nameAdj + } else { + return nil, nil + } + } else if patRune == '*' { + // handle stars - a star at the end of the pattern or before a separator + // will always match the rest of the path component + if patIdx += patAdj; patIdx >= patternLen { + return []string{}, nil + } + if patRune, patAdj = utf8.DecodeRuneInString(pattern[patIdx:]); patRune == '/' { + return []string{pattern[patIdx+patAdj:]}, nil + } + + // check if we can make any matches + for ; nameIdx < nameLen; nameIdx += nameAdj { + if m, e := matchComponent(pattern[patIdx:], name[nameIdx:]); m != nil || e != nil { + return m, e + } + _, nameAdj = utf8.DecodeRuneInString(name[nameIdx:]) + } + return nil, nil + } else if patRune == '[' { + // handle character sets + patIdx += patAdj + endClass := indexRuneWithEscaping(pattern[patIdx:], ']') + if endClass == -1 { + return nil, ErrBadPattern + } + endClass += patIdx + classRunes := []rune(pattern[patIdx:endClass]) + classRunesLen := len(classRunes) + if classRunesLen > 0 { + classIdx := 0 + matchClass := false + if classRunes[0] == '^' { + classIdx++ + } + for classIdx < classRunesLen { + low := classRunes[classIdx] + if low == '-' { + return nil, ErrBadPattern + } + classIdx++ + if low == '\\' { + if classIdx < classRunesLen { + low = classRunes[classIdx] + classIdx++ + } else { + return nil, ErrBadPattern + } + } + high := low + if classIdx < classRunesLen && classRunes[classIdx] == '-' { + // we have a range of runes + if classIdx++; classIdx >= classRunesLen { + return nil, ErrBadPattern + } + high = classRunes[classIdx] + if high == '-' { + return nil, ErrBadPattern + } + classIdx++ + if high == '\\' { + if classIdx < classRunesLen { + high = classRunes[classIdx] + classIdx++ + } else { + return nil, ErrBadPattern + } + } + } + if low <= nameRune && nameRune <= high { + matchClass = true + } + } + if matchClass == (classRunes[0] == '^') { + return nil, nil + } + } else { + return nil, ErrBadPattern + } + patIdx = endClass + 1 + nameIdx += nameAdj + } else if patRune == '{' { + // handle alternatives such as {alt1,alt2,...} + patIdx += patAdj + options, endOptions := splitAlternatives(pattern[patIdx:]) + if endOptions == -1 { + return nil, ErrBadPattern + } + patIdx += endOptions + + results := make([][]string, 0, len(options)) + totalResults := 0 + for _, o := range options { + m, e := matchComponent(o+pattern[patIdx:], name[nameIdx:]) + if e != nil { + return nil, e + } + if m != nil { + results = append(results, m) + totalResults += len(m) + } + } + if len(results) > 0 { + lst := make([]string, 0, totalResults) + for _, m := range results { + lst = append(lst, m...) + } + return lst, nil + } + + return nil, nil + } else if patRune == '?' || patRune == nameRune { + // handle single-rune wildcard + patIdx += patAdj + nameIdx += nameAdj + } else { + return nil, nil + } + } + if nameIdx >= nameLen { + if patIdx >= patternLen { + return []string{}, nil + } + + pattern = pattern[patIdx:] + slashIdx := indexRuneWithEscaping(pattern, '/') + testPattern := pattern + if slashIdx >= 0 { + testPattern = pattern[:slashIdx] + } + + zeroLength, err := isZeroLengthPattern(testPattern) + if err != nil { + return nil, err + } + if zeroLength { + if slashIdx == -1 { + return []string{}, nil + } else { + return []string{pattern[slashIdx+1:]}, nil + } + } + } + return nil, nil +} diff --git a/vendor/github.com/bmatcuk/doublestar/go.mod b/vendor/github.com/bmatcuk/doublestar/go.mod new file mode 100644 index 000000000..ce1688f73 --- /dev/null +++ b/vendor/github.com/bmatcuk/doublestar/go.mod @@ -0,0 +1,3 @@ +module github.com/bmatcuk/doublestar + +go 1.12 diff --git a/vendor/github.com/bradrydzewski/togo/parser/parser.go b/vendor/github.com/bradrydzewski/togo/parser/parser.go new file mode 100644 index 000000000..26a9a0176 --- /dev/null +++ b/vendor/github.com/bradrydzewski/togo/parser/parser.go @@ -0,0 +1,83 @@ +package parser + +import ( + "bufio" + "fmt" + "io" + "os" + "strings" +) + +const ( + prefix = "-- name: " + comment = "--" + newline = "\n" + delimiter = ";" +) + +// Statement represents a statment in the sql file. +type Statement struct { + Name string + Value string + Driver string +} + +// Parser parses the sql file. +type Parser struct { + prefix string +} + +// New returns a new parser. +func New() *Parser { + return NewPrefix(prefix) +} + +// NewPrefix returns a new parser with the given prefix. +func NewPrefix(prefix string) *Parser { + return &Parser{prefix: prefix} +} + +// ParseFile parses the sql file. +func (p *Parser) ParseFile(filepath string) ([]*Statement, error) { + f, err := os.Open(filepath) + if err != nil { + return nil, err + } + defer f.Close() + return p.Parse(f) +} + +// Parse parses the sql file and returns a list of statements. +func (p *Parser) Parse(r io.Reader) ([]*Statement, error) { + var ( + stmts []*Statement + stmt *Statement + ) + scanner := bufio.NewScanner(r) + for scanner.Scan() { + line := scanner.Text() + + if strings.HasPrefix(line, prefix) { + stmt = new(Statement) + stmt.Name, stmt.Driver = parsePrefix(line, p.prefix) + stmts = append(stmts, stmt) + } + if strings.HasPrefix(line, comment) { + continue + } + if stmt != nil { + stmt.Value += line + newline + } + } + for _, stmt := range stmts { + stmt.Value = strings.TrimSpace(stmt.Value) + } + return stmts, nil +} + +func parsePrefix(line, prefix string) (name string, driver string) { + line = strings.TrimPrefix(line, prefix) + line = strings.TrimSpace(line) + fmt.Sscanln(line, &name, &driver) + return +} diff --git a/vendor/github.com/bradrydzewski/togo/template/format.go b/vendor/github.com/bradrydzewski/togo/template/format.go new file mode 100644 index 000000000..da7024b02 --- /dev/null +++ b/vendor/github.com/bradrydzewski/togo/template/format.go @@ -0,0 +1,20 @@ +package template + +import ( + "bytes" + "io" + "os" + "os/exec" +) + +// format formats a template using gofmt. +func format(in io.Reader) (io.Reader, error) { + var out bytes.Buffer + + gofmt := exec.Command("gofmt", "-s") + gofmt.Stdin = in + gofmt.Stdout = &out + gofmt.Stderr = os.Stderr + err := gofmt.Run() + return &out, err +} diff --git a/vendor/github.com/bradrydzewski/togo/template/funcs.go b/vendor/github.com/bradrydzewski/togo/template/funcs.go new file mode 100644 index 000000000..12e9ca2d1 --- /dev/null +++ b/vendor/github.com/bradrydzewski/togo/template/funcs.go @@ -0,0 +1,48 @@ +package template + +import "bytes" + +// hexdump is a template function that creates a hux dump +// similar to xxd -i. +func hexdump(v interface{}) string { + var data []byte + switch vv := v.(type) { + case []byte: + data = vv + case string: + data = []byte(vv) + default: + return "" + } + var buf bytes.Buffer + for i, b := range data { + dst := make([]byte, 4) + src := []byte{b} + encode(dst, src, ldigits) + buf.Write(dst) + + buf.WriteString(",") + if (i+1)%cols == 0 { + buf.WriteString("\n") + } + } + return buf.String() +} + +// default number of columns +const cols = 12 + +// hex lookup table for hex encoding +const ( + ldigits = "0123456789abcdef" + udigits = "0123456789ABCDEF" +) + +func encode(dst, src []byte, hextable string) { + dst[0] = '0' + dst[1] = 'x' + for i, v := range src { + dst[i+1*2] = hextable[v>>4] + dst[i+1*2+1] = hextable[v&0x0f] + } +} diff --git a/vendor/github.com/bradrydzewski/togo/template/template.go b/vendor/github.com/bradrydzewski/togo/template/template.go new file mode 100644 index 000000000..076dc28dd --- /dev/null +++ b/vendor/github.com/bradrydzewski/togo/template/template.go @@ -0,0 +1,61 @@ +package template + +//go:generate togo tmpl -func FuncMap -format text -encode + +import ( + "bytes" + "io" + "strings" + "text/template" + "unicode" +) + +// Execute renders the named template and writes to io.Writer wr. +func Execute(wr io.Writer, name string, data interface{}) error { + buf := new(bytes.Buffer) + err := T.ExecuteTemplate(buf, name, data) + if err != nil { + return err + } + src, err := format(buf) + if err != nil { + return err + } + _, err = io.Copy(wr, src) + return err +} + +// FuncMap provides extra functions for the templates. +var FuncMap = template.FuncMap{ + "substr": substr, + "camelize": camelize, + "hexdump": hexdump, +} + +func substr(s string, i int) string { + return s[:i] +} + +func camelize(kebab string) (camelCase string) { + isToUpper := false + for _, runeValue := range kebab { + if !isCamelCase(runeValue) { + continue + } + if isToUpper { + camelCase += strings.ToUpper(string(runeValue)) + isToUpper = false + } else { + if runeValue == '-' { + isToUpper = true + } else { + camelCase += string(runeValue) + } + } + } + return +} + +func isCamelCase(r rune) bool { + return r == '-' || unicode.IsLetter(r) || unicode.IsDigit(r) +} diff --git a/vendor/github.com/bradrydzewski/togo/template/template_gen.go b/vendor/github.com/bradrydzewski/togo/template/template_gen.go new file mode 100644 index 000000000..97ebbcfb8 --- /dev/null +++ b/vendor/github.com/bradrydzewski/togo/template/template_gen.go @@ -0,0 +1,770 @@ +package template + +import "text/template" + +// list of embedded template files. +var files = []struct { + name string + data string +}{ + { + name: "ddl.tmpl", + data: string(ddl), + }, { + name: "http.tmpl", + data: string(http), + }, { + name: "httptest.tmpl", + data: string(httptest), + }, { + name: "i18n.tmpl", + data: string(i18n), + }, { + name: "sql.tmpl", + data: string(sql), + }, { + name: "tmpl.tmpl", + data: string(tmpl), + }, +} + +// T exposes the embedded templates. +var T *template.Template + +func init() { + T = template.New("_").Funcs(FuncMap) + for _, file := range files { + T = template.Must( + T.New(file.name).Parse(file.data), + ) + } +} + +// +// embedded template files. +// + +// files/ddl.tmpl +var ddl = []byte{ + 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x20, 0x7b, 0x7b, 0x20, 0x2e, + 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x20, 0x7d, 0x7d, 0x0a, 0x0a, + 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x28, 0x0a, 0x09, 0x22, 0x64, + 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x2f, 0x73, 0x71, 0x6c, 0x22, + 0x0a, 0x09, 0x7b, 0x7b, 0x2d, 0x20, 0x69, 0x66, 0x20, 0x2e, 0x4c, 0x6f, + 0x67, 0x67, 0x65, 0x72, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x20, 0x7d, 0x7d, 0x0a, 0x09, 0x22, 0x6c, 0x6f, 0x67, 0x22, 0x0a, 0x09, + 0x7b, 0x7b, 0x2d, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x7d, 0x7d, 0x0a, 0x29, + 0x0a, 0x0a, 0x76, 0x61, 0x72, 0x20, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3d, 0x20, 0x5b, 0x5d, 0x73, 0x74, 0x72, + 0x75, 0x63, 0x74, 0x20, 0x7b, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x20, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x0a, 0x09, 0x73, 0x74, 0x6d, 0x74, + 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x0a, 0x7d, 0x7b, 0x0a, 0x09, + 0x7b, 0x7b, 0x2d, 0x20, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x2e, 0x4d, + 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x7d, 0x7d, + 0x0a, 0x09, 0x7b, 0x7b, 0x2d, 0x20, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x20, + 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, + 0x7d, 0x7d, 0x0a, 0x09, 0x7b, 0x0a, 0x09, 0x09, 0x6e, 0x61, 0x6d, 0x65, + 0x3a, 0x20, 0x7b, 0x7b, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x66, 0x20, + 0x22, 0x25, 0x71, 0x22, 0x20, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x20, 0x7d, + 0x7d, 0x2c, 0x0a, 0x09, 0x09, 0x73, 0x74, 0x6d, 0x74, 0x3a, 0x20, 0x7b, + 0x7b, 0x20, 0x63, 0x61, 0x6d, 0x65, 0x6c, 0x69, 0x7a, 0x65, 0x20, 0x2e, + 0x4e, 0x61, 0x6d, 0x65, 0x20, 0x7d, 0x7d, 0x2c, 0x0a, 0x09, 0x7d, 0x2c, + 0x0a, 0x09, 0x7b, 0x7b, 0x2d, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x7d, 0x7d, + 0x0a, 0x09, 0x7b, 0x7b, 0x2d, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x7d, 0x7d, + 0x0a, 0x7d, 0x0a, 0x0a, 0x2f, 0x2f, 0x20, 0x4d, 0x69, 0x67, 0x72, 0x61, + 0x74, 0x65, 0x20, 0x70, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x73, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, + 0x20, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x20, + 0x49, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d, 0x69, 0x67, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x73, 0x0a, 0x2f, + 0x2f, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, + 0x69, 0x73, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x64, 0x2e, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, + 0x65, 0x28, 0x64, 0x62, 0x20, 0x2a, 0x73, 0x71, 0x6c, 0x2e, 0x44, 0x42, + 0x29, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x7b, 0x0a, 0x09, 0x69, + 0x66, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x64, 0x62, 0x29, + 0x3b, 0x20, 0x65, 0x72, 0x72, 0x20, 0x21, 0x3d, 0x20, 0x6e, 0x69, 0x6c, + 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x65, 0x72, 0x72, 0x0a, 0x09, 0x7d, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x65, 0x64, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, + 0x3d, 0x20, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6d, 0x70, + 0x6c, 0x65, 0x74, 0x65, 0x64, 0x28, 0x64, 0x62, 0x29, 0x0a, 0x09, 0x69, + 0x66, 0x20, 0x65, 0x72, 0x72, 0x20, 0x21, 0x3d, 0x20, 0x6e, 0x69, 0x6c, + 0x20, 0x26, 0x26, 0x20, 0x65, 0x72, 0x72, 0x20, 0x21, 0x3d, 0x20, 0x73, + 0x71, 0x6c, 0x2e, 0x45, 0x72, 0x72, 0x4e, 0x6f, 0x52, 0x6f, 0x77, 0x73, + 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x65, 0x72, 0x72, 0x0a, 0x09, 0x7d, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x20, + 0x5f, 0x2c, 0x20, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x3a, 0x3d, 0x20, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x6d, 0x69, + 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x7b, 0x0a, 0x09, + 0x09, 0x69, 0x66, 0x20, 0x5f, 0x2c, 0x20, 0x6f, 0x6b, 0x20, 0x3a, 0x3d, + 0x20, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x5b, 0x6d, + 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x5d, 0x3b, 0x20, 0x6f, 0x6b, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, + 0x7b, 0x7b, 0x20, 0x69, 0x66, 0x20, 0x2e, 0x4c, 0x6f, 0x67, 0x67, 0x65, + 0x72, 0x2e, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x20, 0x7d, 0x7d, + 0x0a, 0x09, 0x09, 0x09, 0x64, 0x65, 0x62, 0x75, 0x67, 0x28, 0x22, 0x6d, + 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x6b, 0x69, + 0x70, 0x70, 0x65, 0x64, 0x3a, 0x20, 0x25, 0x73, 0x22, 0x2c, 0x20, 0x6d, + 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x6e, 0x61, 0x6d, + 0x65, 0x29, 0x0a, 0x09, 0x09, 0x09, 0x7b, 0x7b, 0x20, 0x65, 0x6e, 0x64, + 0x20, 0x7d, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x69, + 0x6e, 0x75, 0x65, 0x0a, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x7b, 0x7b, + 0x20, 0x69, 0x66, 0x20, 0x2e, 0x4c, 0x6f, 0x67, 0x67, 0x65, 0x72, 0x2e, + 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x20, 0x7d, 0x7d, 0x0a, 0x09, + 0x09, 0x69, 0x6e, 0x66, 0x6f, 0x28, 0x22, 0x6d, 0x69, 0x67, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, + 0x3a, 0x20, 0x25, 0x73, 0x22, 0x2c, 0x20, 0x6d, 0x69, 0x67, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x09, + 0x09, 0x7b, 0x7b, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x7d, 0x7d, 0x0a, 0x09, + 0x09, 0x69, 0x66, 0x20, 0x5f, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, + 0x3d, 0x20, 0x64, 0x62, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x28, 0x6d, 0x69, + 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x73, 0x74, 0x6d, 0x74, + 0x29, 0x3b, 0x20, 0x65, 0x72, 0x72, 0x20, 0x21, 0x3d, 0x20, 0x6e, 0x69, + 0x6c, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x20, 0x65, 0x72, 0x72, 0x0a, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, + 0x69, 0x66, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x69, 0x6e, + 0x73, 0x65, 0x72, 0x74, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x28, 0x64, 0x62, 0x2c, 0x20, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x3b, 0x20, 0x65, + 0x72, 0x72, 0x20, 0x21, 0x3d, 0x20, 0x6e, 0x69, 0x6c, 0x20, 0x7b, 0x0a, + 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x72, + 0x72, 0x0a, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x7b, 0x7b, 0x20, 0x69, + 0x66, 0x20, 0x2e, 0x4c, 0x6f, 0x67, 0x67, 0x65, 0x72, 0x2e, 0x45, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x20, 0x7d, 0x7d, 0x0a, 0x09, 0x09, 0x69, + 0x6e, 0x66, 0x6f, 0x28, 0x22, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x66, 0x69, 0x6e, 0x69, 0x73, 0x68, 0x65, 0x64, 0x3a, + 0x20, 0x25, 0x73, 0x22, 0x2c, 0x20, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x09, 0x09, + 0x7b, 0x7b, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x7d, 0x7d, 0x0a, 0x09, 0x7d, + 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, + 0x0a, 0x7d, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x28, 0x64, 0x62, 0x20, + 0x2a, 0x73, 0x71, 0x6c, 0x2e, 0x44, 0x42, 0x29, 0x20, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x20, 0x7b, 0x0a, 0x09, 0x5f, 0x2c, 0x20, 0x65, 0x72, 0x72, + 0x20, 0x3a, 0x3d, 0x20, 0x64, 0x62, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x28, + 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x29, 0x0a, 0x09, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x72, 0x72, 0x0a, 0x7d, 0x0a, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, + 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x64, 0x62, + 0x20, 0x2a, 0x73, 0x71, 0x6c, 0x2e, 0x44, 0x42, 0x2c, 0x20, 0x6e, 0x61, + 0x6d, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x29, 0x20, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x20, 0x7b, 0x0a, 0x09, 0x5f, 0x2c, 0x20, 0x65, + 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x64, 0x62, 0x2e, 0x45, 0x78, 0x65, + 0x63, 0x28, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, + 0x6e, 0x73, 0x65, 0x72, 0x74, 0x2c, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x29, + 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x65, 0x72, 0x72, + 0x0a, 0x7d, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x73, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, + 0x28, 0x64, 0x62, 0x20, 0x2a, 0x73, 0x71, 0x6c, 0x2e, 0x44, 0x42, 0x29, + 0x20, 0x28, 0x6d, 0x61, 0x70, 0x5b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x5d, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x7b, 0x7d, 0x2c, 0x20, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x6d, 0x69, 0x67, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3a, 0x3d, 0x20, 0x6d, + 0x61, 0x70, 0x5b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5d, 0x73, 0x74, + 0x72, 0x75, 0x63, 0x74, 0x7b, 0x7d, 0x7b, 0x7d, 0x0a, 0x09, 0x72, 0x6f, + 0x77, 0x73, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x64, + 0x62, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x28, 0x6d, 0x69, 0x67, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x29, + 0x0a, 0x09, 0x69, 0x66, 0x20, 0x65, 0x72, 0x72, 0x20, 0x21, 0x3d, 0x20, + 0x6e, 0x69, 0x6c, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x0a, + 0x09, 0x7d, 0x0a, 0x09, 0x64, 0x65, 0x66, 0x65, 0x72, 0x20, 0x72, 0x6f, + 0x77, 0x73, 0x2e, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x28, 0x29, 0x0a, 0x09, + 0x66, 0x6f, 0x72, 0x20, 0x72, 0x6f, 0x77, 0x73, 0x2e, 0x4e, 0x65, 0x78, + 0x74, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x76, 0x61, 0x72, 0x20, + 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x0a, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, + 0x72, 0x6f, 0x77, 0x73, 0x2e, 0x53, 0x63, 0x61, 0x6e, 0x28, 0x26, 0x6e, + 0x61, 0x6d, 0x65, 0x29, 0x3b, 0x20, 0x65, 0x72, 0x72, 0x20, 0x21, 0x3d, + 0x20, 0x6e, 0x69, 0x6c, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x09, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, 0x2c, 0x20, 0x65, 0x72, + 0x72, 0x0a, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x6d, 0x69, 0x67, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5b, 0x6e, 0x61, 0x6d, 0x65, 0x5d, + 0x20, 0x3d, 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x7b, 0x7d, 0x7b, + 0x7d, 0x0a, 0x09, 0x7d, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2c, + 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x7d, 0x0a, 0x0a, 0x7b, 0x7b, 0x20, 0x69, + 0x66, 0x20, 0x2e, 0x4c, 0x6f, 0x67, 0x67, 0x65, 0x72, 0x2e, 0x45, 0x6e, + 0x61, 0x62, 0x6c, 0x65, 0x64, 0x20, 0x7d, 0x7d, 0x0a, 0x2f, 0x2f, 0x0a, + 0x2f, 0x2f, 0x20, 0x6c, 0x6f, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x20, 0x66, + 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x0a, 0x2f, 0x2f, 0x0a, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x64, 0x65, 0x62, 0x75, 0x67, 0x28, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x2c, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x20, 0x2e, + 0x2e, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x7b, + 0x7d, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x6c, 0x6f, 0x67, 0x2e, 0x50, 0x72, + 0x69, 0x6e, 0x74, 0x66, 0x28, 0x22, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x64, 0x65, 0x62, 0x75, 0x67, 0x3a, 0x20, + 0x22, 0x2b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2c, 0x20, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, 0x7d, 0x0a, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x28, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x2c, 0x20, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x20, 0x2e, 0x2e, + 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x7b, 0x7d, + 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x6c, 0x6f, 0x67, 0x2e, 0x50, 0x72, 0x69, + 0x6e, 0x74, 0x66, 0x28, 0x22, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x3a, 0x20, 0x69, 0x6e, 0x66, 0x6f, 0x3a, 0x20, 0x22, 0x2b, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2c, 0x20, 0x70, 0x61, 0x72, + 0x61, 0x6d, 0x73, 0x2e, 0x2e, 0x2e, 0x29, 0x0a, 0x7d, 0x0a, 0x7b, 0x7b, + 0x20, 0x65, 0x6e, 0x64, 0x20, 0x7d, 0x7d, 0x0a, 0x0a, 0x2f, 0x2f, 0x0a, + 0x2f, 0x2f, 0x20, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x64, 0x64, 0x6c, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x73, 0x71, 0x6c, 0x0a, 0x2f, 0x2f, 0x0a, 0x0a, 0x76, + 0x61, 0x72, 0x20, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, + 0x3d, 0x20, 0x60, 0x0a, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x20, 0x54, + 0x41, 0x42, 0x4c, 0x45, 0x20, 0x49, 0x46, 0x20, 0x4e, 0x4f, 0x54, 0x20, + 0x45, 0x58, 0x49, 0x53, 0x54, 0x53, 0x20, 0x6d, 0x69, 0x67, 0x72, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x28, 0x0a, 0x20, 0x6e, 0x61, 0x6d, + 0x65, 0x20, 0x56, 0x41, 0x52, 0x43, 0x48, 0x41, 0x52, 0x28, 0x32, 0x35, + 0x35, 0x29, 0x0a, 0x2c, 0x55, 0x4e, 0x49, 0x51, 0x55, 0x45, 0x28, 0x6e, + 0x61, 0x6d, 0x65, 0x29, 0x0a, 0x29, 0x0a, 0x60, 0x0a, 0x0a, 0x76, 0x61, + 0x72, 0x20, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, + 0x6e, 0x73, 0x65, 0x72, 0x74, 0x20, 0x3d, 0x20, 0x60, 0x0a, 0x49, 0x4e, + 0x53, 0x45, 0x52, 0x54, 0x20, 0x49, 0x4e, 0x54, 0x4f, 0x20, 0x6d, 0x69, + 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x28, 0x6e, 0x61, + 0x6d, 0x65, 0x29, 0x20, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x53, 0x20, 0x28, + 0x7b, 0x7b, 0x20, 0x69, 0x66, 0x20, 0x65, 0x71, 0x20, 0x2e, 0x44, 0x69, + 0x61, 0x6c, 0x65, 0x63, 0x74, 0x20, 0x22, 0x70, 0x6f, 0x73, 0x74, 0x67, + 0x72, 0x65, 0x73, 0x22, 0x20, 0x2d, 0x7d, 0x7d, 0x20, 0x24, 0x31, 0x20, + 0x7b, 0x7b, 0x2d, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x2d, 0x7d, 0x7d, + 0x20, 0x3f, 0x20, 0x7b, 0x7b, 0x2d, 0x20, 0x20, 0x65, 0x6e, 0x64, 0x20, + 0x7d, 0x7d, 0x29, 0x0a, 0x60, 0x0a, 0x0a, 0x76, 0x61, 0x72, 0x20, 0x6d, + 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x20, 0x3d, 0x20, 0x60, 0x0a, 0x53, 0x45, 0x4c, 0x45, 0x43, + 0x54, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x46, 0x52, 0x4f, 0x4d, 0x20, + 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x0a, 0x60, + 0x0a, 0x0a, 0x7b, 0x7b, 0x20, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x2e, + 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x7d, + 0x7d, 0x0a, 0x2f, 0x2f, 0x0a, 0x2f, 0x2f, 0x20, 0x7b, 0x7b, 0x20, 0x2e, + 0x4e, 0x61, 0x6d, 0x65, 0x20, 0x7d, 0x7d, 0x0a, 0x2f, 0x2f, 0x0a, 0x7b, + 0x7b, 0x20, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x2e, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x7d, 0x7d, 0x0a, 0x0a, + 0x76, 0x61, 0x72, 0x20, 0x7b, 0x7b, 0x20, 0x63, 0x61, 0x6d, 0x65, 0x6c, + 0x69, 0x7a, 0x65, 0x20, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x20, 0x7d, 0x7d, + 0x20, 0x3d, 0x20, 0x60, 0x0a, 0x7b, 0x7b, 0x20, 0x2e, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x20, 0x7d, 0x7d, 0x0a, 0x60, 0x0a, 0x7b, 0x7b, 0x20, 0x65, + 0x6e, 0x64, 0x20, 0x7d, 0x7d, 0x0a, 0x7b, 0x7b, 0x20, 0x65, 0x6e, 0x64, + 0x20, 0x7d, 0x7d, 0x0a, +} + +// files/http.tmpl +var http = []byte{ + 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x20, 0x7b, 0x7b, 0x20, 0x2e, + 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x20, 0x7d, 0x7d, 0x0a, 0x0a, + 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x28, 0x0a, 0x09, 0x22, 0x62, + 0x79, 0x74, 0x65, 0x73, 0x22, 0x0a, 0x09, 0x22, 0x6e, 0x65, 0x74, 0x2f, + 0x68, 0x74, 0x74, 0x70, 0x22, 0x0a, 0x09, 0x22, 0x6f, 0x73, 0x22, 0x0a, + 0x09, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x73, 0x22, 0x0a, 0x09, + 0x22, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x0a, 0x29, 0x0a, 0x0a, 0x74, 0x79, + 0x70, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, + 0x6d, 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x7b, 0x0a, 0x09, + 0x66, 0x69, 0x6c, 0x65, 0x73, 0x20, 0x6d, 0x61, 0x70, 0x5b, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x5d, 0x66, 0x69, 0x6c, 0x65, 0x0a, 0x7d, 0x0a, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x28, 0x66, 0x73, 0x20, 0x2a, 0x66, + 0x69, 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x29, 0x20, 0x4f, + 0x70, 0x65, 0x6e, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x29, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70, 0x2e, 0x46, + 0x69, 0x6c, 0x65, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x29, 0x20, + 0x7b, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x3d, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, + 0x65, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x22, 0x2f, 0x2f, 0x22, + 0x2c, 0x20, 0x22, 0x2f, 0x22, 0x2c, 0x20, 0x2d, 0x31, 0x29, 0x0a, 0x09, + 0x66, 0x2c, 0x20, 0x6f, 0x6b, 0x20, 0x3a, 0x3d, 0x20, 0x66, 0x73, 0x2e, + 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5b, 0x6e, 0x61, 0x6d, 0x65, 0x5d, 0x0a, + 0x09, 0x69, 0x66, 0x20, 0x6f, 0x6b, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x65, 0x77, 0x48, 0x54, 0x54, + 0x50, 0x46, 0x69, 0x6c, 0x65, 0x28, 0x66, 0x2c, 0x20, 0x66, 0x61, 0x6c, + 0x73, 0x65, 0x29, 0x2c, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x09, 0x7d, 0x0a, + 0x09, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x3a, 0x3d, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x73, 0x2e, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, + 0x65, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x2b, 0x22, 0x2f, 0x69, 0x6e, 0x64, + 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x22, 0x2c, 0x20, 0x22, 0x2f, + 0x2f, 0x22, 0x2c, 0x20, 0x22, 0x2f, 0x22, 0x2c, 0x20, 0x2d, 0x31, 0x29, + 0x0a, 0x09, 0x66, 0x2c, 0x20, 0x6f, 0x6b, 0x20, 0x3d, 0x20, 0x66, 0x73, + 0x2e, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5b, 0x69, 0x6e, 0x64, 0x65, 0x78, + 0x5d, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x21, 0x6f, 0x6b, 0x20, 0x7b, 0x0a, + 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, + 0x2c, 0x20, 0x6f, 0x73, 0x2e, 0x45, 0x72, 0x72, 0x4e, 0x6f, 0x74, 0x45, + 0x78, 0x69, 0x73, 0x74, 0x0a, 0x09, 0x7d, 0x0a, 0x09, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x65, 0x77, 0x48, 0x54, 0x54, 0x50, 0x46, + 0x69, 0x6c, 0x65, 0x28, 0x66, 0x2c, 0x20, 0x74, 0x72, 0x75, 0x65, 0x29, + 0x2c, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x7d, 0x0a, 0x0a, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x20, 0x7b, 0x0a, 0x09, 0x6f, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, + 0x49, 0x6e, 0x66, 0x6f, 0x0a, 0x09, 0x64, 0x61, 0x74, 0x61, 0x20, 0x5b, + 0x5d, 0x62, 0x79, 0x74, 0x65, 0x0a, 0x7d, 0x0a, 0x0a, 0x74, 0x79, 0x70, + 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x20, 0x73, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, 0x7b, 0x0a, 0x09, 0x6e, 0x61, 0x6d, + 0x65, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x0a, + 0x09, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x74, + 0x36, 0x34, 0x0a, 0x09, 0x6d, 0x6f, 0x64, 0x65, 0x20, 0x20, 0x20, 0x20, + 0x6f, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x0a, + 0x09, 0x6d, 0x6f, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x20, 0x74, 0x69, 0x6d, + 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x0a, 0x09, 0x69, 0x73, 0x44, 0x69, + 0x72, 0x20, 0x20, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x0a, 0x0a, 0x09, 0x66, + 0x69, 0x6c, 0x65, 0x73, 0x20, 0x5b, 0x5d, 0x6f, 0x73, 0x2e, 0x46, 0x69, + 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x0a, 0x7d, 0x0a, 0x0a, 0x66, 0x75, + 0x6e, 0x63, 0x20, 0x28, 0x66, 0x20, 0x2a, 0x66, 0x69, 0x6c, 0x65, 0x49, + 0x6e, 0x66, 0x6f, 0x29, 0x20, 0x4e, 0x61, 0x6d, 0x65, 0x28, 0x29, 0x20, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x7b, 0x0a, 0x09, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x0a, + 0x7d, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x28, 0x66, 0x20, 0x2a, + 0x66, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x29, 0x20, 0x53, 0x69, + 0x7a, 0x65, 0x28, 0x29, 0x20, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x20, 0x7b, + 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x2e, 0x73, + 0x69, 0x7a, 0x65, 0x0a, 0x7d, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x20, + 0x28, 0x66, 0x20, 0x2a, 0x66, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, + 0x29, 0x20, 0x4d, 0x6f, 0x64, 0x65, 0x28, 0x29, 0x20, 0x6f, 0x73, 0x2e, + 0x46, 0x69, 0x6c, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x20, 0x7b, 0x0a, 0x09, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x2e, 0x6d, 0x6f, 0x64, + 0x65, 0x0a, 0x7d, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x28, 0x66, + 0x20, 0x2a, 0x66, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x29, 0x20, + 0x4d, 0x6f, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x28, 0x29, 0x20, 0x74, 0x69, + 0x6d, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x20, 0x7b, 0x0a, 0x09, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x2e, 0x6d, 0x6f, 0x64, 0x54, + 0x69, 0x6d, 0x65, 0x0a, 0x7d, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x20, + 0x28, 0x66, 0x20, 0x2a, 0x66, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, + 0x29, 0x20, 0x49, 0x73, 0x44, 0x69, 0x72, 0x28, 0x29, 0x20, 0x62, 0x6f, + 0x6f, 0x6c, 0x20, 0x7b, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, + 0x20, 0x66, 0x2e, 0x69, 0x73, 0x44, 0x69, 0x72, 0x0a, 0x7d, 0x0a, 0x0a, + 0x66, 0x75, 0x6e, 0x63, 0x20, 0x28, 0x66, 0x20, 0x2a, 0x66, 0x69, 0x6c, + 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x29, 0x20, 0x52, 0x65, 0x61, 0x64, 0x64, + 0x69, 0x72, 0x28, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x74, + 0x29, 0x20, 0x28, 0x5b, 0x5d, 0x6f, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, + 0x49, 0x6e, 0x66, 0x6f, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x29, + 0x20, 0x7b, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6d, + 0x61, 0x6b, 0x65, 0x28, 0x5b, 0x5d, 0x6f, 0x73, 0x2e, 0x46, 0x69, 0x6c, + 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2c, 0x20, 0x30, 0x29, 0x2c, 0x20, 0x6e, + 0x69, 0x6c, 0x0a, 0x7d, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x28, + 0x66, 0x20, 0x2a, 0x66, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x29, + 0x20, 0x53, 0x79, 0x73, 0x28, 0x29, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x66, 0x61, 0x63, 0x65, 0x7b, 0x7d, 0x20, 0x7b, 0x0a, 0x09, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x7d, 0x0a, 0x0a, + 0x66, 0x75, 0x6e, 0x63, 0x20, 0x6e, 0x65, 0x77, 0x48, 0x54, 0x54, 0x50, + 0x46, 0x69, 0x6c, 0x65, 0x28, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x66, 0x69, + 0x6c, 0x65, 0x2c, 0x20, 0x69, 0x73, 0x44, 0x69, 0x72, 0x20, 0x62, 0x6f, + 0x6f, 0x6c, 0x29, 0x20, 0x2a, 0x68, 0x74, 0x74, 0x70, 0x46, 0x69, 0x6c, + 0x65, 0x20, 0x7b, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, + 0x26, 0x68, 0x74, 0x74, 0x70, 0x46, 0x69, 0x6c, 0x65, 0x7b, 0x0a, 0x09, + 0x09, 0x66, 0x69, 0x6c, 0x65, 0x3a, 0x20, 0x20, 0x20, 0x66, 0x69, 0x6c, + 0x65, 0x2c, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x61, 0x64, 0x65, 0x72, 0x3a, + 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x2e, 0x4e, 0x65, 0x77, 0x52, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x28, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x64, 0x61, + 0x74, 0x61, 0x29, 0x2c, 0x0a, 0x09, 0x09, 0x69, 0x73, 0x44, 0x69, 0x72, + 0x3a, 0x20, 0x20, 0x69, 0x73, 0x44, 0x69, 0x72, 0x2c, 0x0a, 0x09, 0x7d, + 0x0a, 0x7d, 0x0a, 0x0a, 0x74, 0x79, 0x70, 0x65, 0x20, 0x68, 0x74, 0x74, + 0x70, 0x46, 0x69, 0x6c, 0x65, 0x20, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x20, 0x7b, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x0a, 0x0a, 0x09, 0x72, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x2a, 0x62, 0x79, 0x74, 0x65, 0x73, + 0x2e, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x0a, 0x09, 0x69, 0x73, 0x44, + 0x69, 0x72, 0x20, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x0a, 0x7d, 0x0a, 0x0a, + 0x66, 0x75, 0x6e, 0x63, 0x20, 0x28, 0x66, 0x20, 0x2a, 0x68, 0x74, 0x74, + 0x70, 0x46, 0x69, 0x6c, 0x65, 0x29, 0x20, 0x52, 0x65, 0x61, 0x64, 0x28, + 0x70, 0x20, 0x5b, 0x5d, 0x62, 0x79, 0x74, 0x65, 0x29, 0x20, 0x28, 0x6e, + 0x20, 0x69, 0x6e, 0x74, 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x66, 0x2e, 0x72, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, + 0x52, 0x65, 0x61, 0x64, 0x28, 0x70, 0x29, 0x0a, 0x7d, 0x0a, 0x0a, 0x66, + 0x75, 0x6e, 0x63, 0x20, 0x28, 0x66, 0x20, 0x2a, 0x68, 0x74, 0x74, 0x70, + 0x46, 0x69, 0x6c, 0x65, 0x29, 0x20, 0x53, 0x65, 0x65, 0x6b, 0x28, 0x6f, + 0x66, 0x66, 0x73, 0x65, 0x74, 0x20, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x2c, + 0x20, 0x77, 0x68, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x69, 0x6e, 0x74, 0x29, + 0x20, 0x28, 0x72, 0x65, 0x74, 0x20, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x2c, + 0x20, 0x65, 0x72, 0x72, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x29, 0x20, + 0x7b, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x2e, + 0x72, 0x65, 0x61, 0x64, 0x65, 0x72, 0x2e, 0x53, 0x65, 0x65, 0x6b, 0x28, + 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2c, 0x20, 0x77, 0x68, 0x65, 0x6e, + 0x63, 0x65, 0x29, 0x0a, 0x7d, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x20, + 0x28, 0x66, 0x20, 0x2a, 0x68, 0x74, 0x74, 0x70, 0x46, 0x69, 0x6c, 0x65, + 0x29, 0x20, 0x53, 0x74, 0x61, 0x74, 0x28, 0x29, 0x20, 0x28, 0x6f, 0x73, + 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2c, 0x20, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x20, 0x66, 0x2c, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x7d, + 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x28, 0x66, 0x20, 0x2a, 0x68, + 0x74, 0x74, 0x70, 0x46, 0x69, 0x6c, 0x65, 0x29, 0x20, 0x49, 0x73, 0x44, + 0x69, 0x72, 0x28, 0x29, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x20, 0x7b, 0x0a, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x2e, 0x69, 0x73, + 0x44, 0x69, 0x72, 0x0a, 0x7d, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x20, + 0x28, 0x66, 0x20, 0x2a, 0x68, 0x74, 0x74, 0x70, 0x46, 0x69, 0x6c, 0x65, + 0x29, 0x20, 0x52, 0x65, 0x61, 0x64, 0x64, 0x69, 0x72, 0x28, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x74, 0x29, 0x20, 0x28, 0x5b, 0x5d, + 0x6f, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2c, + 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6d, 0x61, 0x6b, 0x65, 0x28, 0x5b, + 0x5d, 0x6f, 0x73, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, + 0x2c, 0x20, 0x30, 0x29, 0x2c, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x7d, 0x0a, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x28, 0x66, 0x20, 0x2a, 0x68, 0x74, + 0x74, 0x70, 0x46, 0x69, 0x6c, 0x65, 0x29, 0x20, 0x43, 0x6c, 0x6f, 0x73, + 0x65, 0x28, 0x29, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x7b, 0x0a, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x69, 0x6c, 0x0a, + 0x7d, 0x0a, 0x0a, 0x2f, 0x2f, 0x20, 0x4e, 0x65, 0x77, 0x20, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x61, 0x6e, 0x20, 0x65, 0x6d, 0x62, + 0x65, 0x64, 0x64, 0x65, 0x64, 0x20, 0x68, 0x74, 0x74, 0x70, 0x2e, 0x46, + 0x69, 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x0a, 0x66, 0x75, + 0x6e, 0x63, 0x20, 0x4e, 0x65, 0x77, 0x28, 0x29, 0x20, 0x68, 0x74, 0x74, + 0x70, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x20, 0x7b, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x26, + 0x66, 0x69, 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x7b, 0x0a, + 0x09, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x3a, 0x20, 0x66, 0x69, 0x6c, + 0x65, 0x73, 0x2c, 0x0a, 0x09, 0x7d, 0x0a, 0x7d, 0x0a, 0x0a, 0x2f, 0x2f, + 0x20, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x20, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, + 0x20, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x70, 0x65, 0x63, + 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x70, 0x61, 0x74, 0x68, 0x0a, 0x66, + 0x75, 0x6e, 0x63, 0x20, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x28, 0x70, + 0x61, 0x74, 0x68, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x29, 0x20, + 0x28, 0x5b, 0x5d, 0x62, 0x79, 0x74, 0x65, 0x2c, 0x20, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x66, 0x2c, 0x20, 0x6f, 0x6b, + 0x20, 0x3a, 0x3d, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5b, 0x70, 0x61, + 0x74, 0x68, 0x5d, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x21, 0x6f, 0x6b, 0x20, + 0x7b, 0x0a, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, + 0x69, 0x6c, 0x2c, 0x20, 0x6f, 0x73, 0x2e, 0x45, 0x72, 0x72, 0x4e, 0x6f, + 0x74, 0x45, 0x78, 0x69, 0x73, 0x74, 0x0a, 0x09, 0x7d, 0x0a, 0x09, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x66, 0x2e, 0x64, 0x61, 0x74, 0x61, + 0x2c, 0x20, 0x6e, 0x69, 0x6c, 0x0a, 0x7d, 0x0a, 0x0a, 0x2f, 0x2f, 0x20, + 0x4d, 0x75, 0x73, 0x74, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x20, 0x72, + 0x65, 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, + 0x69, 0x6c, 0x65, 0x20, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, + 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x65, 0x64, 0x20, 0x70, 0x61, 0x74, + 0x68, 0x0a, 0x2f, 0x2f, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x70, 0x61, 0x6e, + 0x69, 0x63, 0x73, 0x20, 0x69, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, + 0x69, 0x6c, 0x65, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x66, + 0x6f, 0x75, 0x6e, 0x64, 0x2e, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x4d, + 0x75, 0x73, 0x74, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x28, 0x70, 0x61, + 0x74, 0x68, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x29, 0x20, 0x28, + 0x5b, 0x5d, 0x62, 0x79, 0x74, 0x65, 0x29, 0x20, 0x7b, 0x0a, 0x09, 0x64, + 0x2c, 0x20, 0x65, 0x72, 0x72, 0x20, 0x3a, 0x3d, 0x20, 0x4c, 0x6f, 0x6f, + 0x6b, 0x75, 0x70, 0x28, 0x70, 0x61, 0x74, 0x68, 0x29, 0x0a, 0x09, 0x69, + 0x66, 0x20, 0x65, 0x72, 0x72, 0x20, 0x21, 0x3d, 0x20, 0x6e, 0x69, 0x6c, + 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x70, 0x61, 0x6e, 0x69, 0x63, 0x28, 0x65, + 0x72, 0x72, 0x29, 0x0a, 0x09, 0x7d, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x64, 0x0a, 0x7d, 0x0a, 0x0a, 0x2f, 0x2f, 0x20, 0x49, + 0x6e, 0x64, 0x65, 0x78, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x6c, 0x6c, 0x20, + 0x66, 0x69, 0x6c, 0x65, 0x73, 0x0a, 0x76, 0x61, 0x72, 0x20, 0x66, 0x69, + 0x6c, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x70, 0x5b, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x5d, 0x66, 0x69, 0x6c, 0x65, 0x7b, 0x0a, 0x09, + 0x7b, 0x7b, 0x20, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x24, 0x69, 0x6e, + 0x64, 0x65, 0x78, 0x2c, 0x20, 0x24, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x3a, + 0x3d, 0x20, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x20, 0x2d, 0x7d, 0x7d, + 0x0a, 0x09, 0x7b, 0x7b, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x66, 0x20, + 0x22, 0x25, 0x71, 0x22, 0x20, 0x24, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x50, + 0x61, 0x74, 0x68, 0x20, 0x7d, 0x7d, 0x3a, 0x20, 0x7b, 0x0a, 0x09, 0x09, + 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x7b, 0x7b, + 0x20, 0x24, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x7d, 0x7d, 0x2c, 0x0a, + 0x09, 0x09, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x3a, 0x20, + 0x26, 0x66, 0x69, 0x6c, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x7b, 0x0a, 0x09, + 0x09, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x20, 0x20, 0x20, 0x7b, + 0x7b, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x66, 0x20, 0x22, 0x25, 0x71, + 0x22, 0x20, 0x24, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x4e, 0x61, 0x6d, 0x65, + 0x20, 0x7d, 0x7d, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x73, 0x69, 0x7a, 0x65, + 0x3a, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x7b, 0x20, 0x24, 0x66, 0x69, 0x6c, + 0x65, 0x2e, 0x53, 0x69, 0x7a, 0x65, 0x20, 0x7d, 0x7d, 0x2c, 0x0a, 0x09, + 0x09, 0x09, 0x6d, 0x6f, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x3a, 0x20, 0x74, + 0x69, 0x6d, 0x65, 0x2e, 0x55, 0x6e, 0x69, 0x78, 0x28, 0x7b, 0x7b, 0x20, + 0x24, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x20, 0x7d, + 0x7d, 0x2c, 0x20, 0x30, 0x29, 0x2c, 0x0a, 0x09, 0x09, 0x7d, 0x2c, 0x0a, + 0x09, 0x7d, 0x2c, 0x0a, 0x09, 0x7b, 0x7b, 0x20, 0x65, 0x6e, 0x64, 0x20, + 0x7d, 0x7d, 0x0a, 0x7d, 0x0a, 0x0a, 0x2f, 0x2f, 0x0a, 0x2f, 0x2f, 0x20, + 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x20, 0x66, 0x69, 0x6c, + 0x65, 0x73, 0x2e, 0x0a, 0x2f, 0x2f, 0x0a, 0x0a, 0x7b, 0x7b, 0x20, 0x72, + 0x61, 0x6e, 0x67, 0x65, 0x20, 0x24, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2c, + 0x20, 0x24, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x3a, 0x3d, 0x20, 0x2e, 0x46, + 0x69, 0x6c, 0x65, 0x73, 0x20, 0x7d, 0x7d, 0x0a, 0x2f, 0x2f, 0x20, 0x7b, + 0x7b, 0x20, 0x24, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x50, 0x61, 0x74, 0x68, + 0x20, 0x7d, 0x7d, 0x0a, 0x7b, 0x7b, 0x20, 0x69, 0x66, 0x20, 0x24, 0x66, + 0x69, 0x6c, 0x65, 0x2e, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x20, + 0x2d, 0x7d, 0x7d, 0x0a, 0x76, 0x61, 0x72, 0x20, 0x66, 0x69, 0x6c, 0x65, + 0x7b, 0x7b, 0x20, 0x24, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x7d, 0x7d, + 0x20, 0x3d, 0x20, 0x5b, 0x5d, 0x62, 0x79, 0x74, 0x65, 0x7b, 0x0a, 0x7b, + 0x7b, 0x20, 0x24, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x44, 0x61, 0x74, 0x61, + 0x20, 0x7c, 0x20, 0x68, 0x65, 0x78, 0x64, 0x75, 0x6d, 0x70, 0x20, 0x7d, + 0x7d, 0x0a, 0x7d, 0x0a, 0x7b, 0x7b, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, + 0x2d, 0x7d, 0x7d, 0x0a, 0x76, 0x61, 0x72, 0x20, 0x66, 0x69, 0x6c, 0x65, + 0x7b, 0x7b, 0x20, 0x24, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x7d, 0x7d, + 0x20, 0x3d, 0x20, 0x5b, 0x5d, 0x62, 0x79, 0x74, 0x65, 0x28, 0x60, 0x7b, + 0x7b, 0x20, 0x24, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x44, 0x61, 0x74, 0x61, + 0x20, 0x7d, 0x7d, 0x60, 0x29, 0x0a, 0x7b, 0x7b, 0x20, 0x65, 0x6e, 0x64, + 0x20, 0x7d, 0x7d, 0x0a, 0x7b, 0x7b, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x7d, + 0x7d, 0x0a, +} + +// files/httptest.tmpl +var httptest = []byte{ + 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x20, 0x7b, 0x7b, 0x20, 0x2e, + 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x20, 0x7d, 0x7d, 0x0a, 0x0a, + 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x28, 0x0a, 0x09, 0x22, 0x69, + 0x6f, 0x22, 0x0a, 0x09, 0x22, 0x6e, 0x65, 0x74, 0x2f, 0x68, 0x74, 0x74, + 0x70, 0x22, 0x0a, 0x09, 0x22, 0x6e, 0x65, 0x74, 0x2f, 0x68, 0x74, 0x74, + 0x70, 0x2f, 0x68, 0x74, 0x74, 0x70, 0x74, 0x65, 0x73, 0x74, 0x22, 0x0a, + 0x29, 0x0a, 0x0a, 0x2f, 0x2f, 0x20, 0x4e, 0x65, 0x77, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x73, 0x20, 0x61, + 0x20, 0x6e, 0x65, 0x77, 0x20, 0x6d, 0x6f, 0x63, 0x6b, 0x20, 0x68, 0x74, + 0x74, 0x70, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x75, 0x73, + 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x65, 0x73, 0x74, + 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x20, + 0x4e, 0x65, 0x77, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x28, 0x29, 0x20, + 0x2a, 0x68, 0x74, 0x74, 0x70, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x20, 0x7b, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, + 0x72, 0x6e, 0x20, 0x68, 0x74, 0x74, 0x70, 0x74, 0x65, 0x73, 0x74, 0x2e, + 0x4e, 0x65, 0x77, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x28, 0x0a, 0x09, + 0x09, 0x68, 0x74, 0x74, 0x70, 0x2e, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, + 0x72, 0x46, 0x75, 0x6e, 0x63, 0x28, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, + 0x29, 0x2c, 0x0a, 0x09, 0x29, 0x0a, 0x7d, 0x0a, 0x0a, 0x66, 0x75, 0x6e, + 0x63, 0x20, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x72, 0x28, 0x77, 0x20, 0x68, + 0x74, 0x74, 0x70, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x57, 0x72, 0x69, 0x74, 0x65, 0x72, 0x2c, 0x20, 0x72, 0x20, 0x2a, 0x68, + 0x74, 0x74, 0x70, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x29, + 0x20, 0x7b, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x65, 0x6e, 0x28, 0x72, + 0x2e, 0x55, 0x52, 0x4c, 0x2e, 0x52, 0x61, 0x77, 0x50, 0x61, 0x74, 0x68, + 0x29, 0x20, 0x21, 0x3d, 0x20, 0x30, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x72, + 0x2e, 0x55, 0x52, 0x4c, 0x2e, 0x50, 0x61, 0x74, 0x68, 0x20, 0x3d, 0x20, + 0x72, 0x2e, 0x55, 0x52, 0x4c, 0x2e, 0x52, 0x61, 0x77, 0x50, 0x61, 0x74, + 0x68, 0x0a, 0x09, 0x7d, 0x0a, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x65, 0x6e, + 0x28, 0x72, 0x2e, 0x55, 0x52, 0x4c, 0x2e, 0x52, 0x61, 0x77, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x29, 0x20, 0x21, 0x3d, 0x20, 0x30, 0x20, 0x7b, 0x0a, + 0x09, 0x09, 0x72, 0x2e, 0x55, 0x52, 0x4c, 0x2e, 0x50, 0x61, 0x74, 0x68, + 0x20, 0x3d, 0x20, 0x72, 0x2e, 0x55, 0x52, 0x4c, 0x2e, 0x50, 0x61, 0x74, + 0x68, 0x20, 0x2b, 0x20, 0x22, 0x3f, 0x22, 0x20, 0x2b, 0x20, 0x72, 0x2e, + 0x55, 0x52, 0x4c, 0x2e, 0x52, 0x61, 0x77, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x0a, 0x09, 0x7d, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x5f, 0x2c, 0x20, + 0x72, 0x6f, 0x75, 0x74, 0x65, 0x20, 0x3a, 0x3d, 0x20, 0x72, 0x61, 0x6e, + 0x67, 0x65, 0x20, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x20, 0x7b, 0x0a, + 0x09, 0x09, 0x69, 0x66, 0x20, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x4d, + 0x65, 0x74, 0x68, 0x6f, 0x64, 0x20, 0x3d, 0x3d, 0x20, 0x72, 0x2e, 0x4d, + 0x65, 0x74, 0x68, 0x6f, 0x64, 0x20, 0x26, 0x26, 0x20, 0x72, 0x6f, 0x75, + 0x74, 0x65, 0x2e, 0x50, 0x61, 0x74, 0x68, 0x20, 0x3d, 0x3d, 0x20, 0x72, + 0x2e, 0x55, 0x52, 0x4c, 0x2e, 0x50, 0x61, 0x74, 0x68, 0x20, 0x7b, 0x0a, + 0x09, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x6b, 0x2c, 0x20, 0x76, 0x20, + 0x3a, 0x3d, 0x20, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x72, 0x6f, 0x75, + 0x74, 0x65, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x7b, 0x0a, + 0x09, 0x09, 0x09, 0x09, 0x77, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x28, 0x29, 0x2e, 0x53, 0x65, 0x74, 0x28, 0x6b, 0x2c, 0x20, 0x76, 0x29, + 0x0a, 0x09, 0x09, 0x09, 0x7d, 0x0a, 0x09, 0x09, 0x09, 0x77, 0x2e, 0x57, + 0x72, 0x69, 0x74, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x28, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x29, + 0x0a, 0x09, 0x09, 0x09, 0x69, 0x6f, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x77, 0x2c, 0x20, 0x72, 0x6f, + 0x75, 0x74, 0x65, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x29, 0x0a, 0x09, 0x09, + 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x0a, 0x09, 0x09, 0x7d, 0x0a, + 0x09, 0x7d, 0x0a, 0x09, 0x77, 0x2e, 0x57, 0x72, 0x69, 0x74, 0x65, 0x48, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x28, 0x34, 0x30, 0x34, 0x29, 0x0a, 0x7d, + 0x0a, 0x0a, 0x76, 0x61, 0x72, 0x20, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x73, + 0x20, 0x3d, 0x20, 0x5b, 0x5d, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x20, + 0x7b, 0x0a, 0x09, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x20, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x0a, 0x09, 0x50, 0x61, 0x74, 0x68, 0x20, 0x20, + 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x0a, 0x09, 0x42, 0x6f, 0x64, + 0x79, 0x20, 0x20, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x0a, 0x09, + 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x69, 0x6e, 0x74, 0x0a, 0x09, + 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x6d, 0x61, 0x70, 0x5b, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5d, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x0a, 0x7d, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x7b, 0x20, 0x72, + 0x61, 0x6e, 0x67, 0x65, 0x20, 0x24, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2c, + 0x20, 0x24, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x20, 0x3a, 0x3d, 0x20, 0x2e, + 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, 0x20, 0x7d, 0x7d, 0x0a, 0x09, 0x2f, + 0x2f, 0x20, 0x7b, 0x7b, 0x20, 0x24, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, + 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x20, 0x7d, 0x7d, 0x20, 0x7b, 0x7b, + 0x20, 0x24, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x50, 0x61, 0x74, 0x68, + 0x20, 0x7d, 0x7d, 0x0a, 0x09, 0x7b, 0x0a, 0x09, 0x09, 0x4d, 0x65, 0x74, + 0x68, 0x6f, 0x64, 0x3a, 0x20, 0x7b, 0x7b, 0x20, 0x70, 0x72, 0x69, 0x6e, + 0x74, 0x66, 0x20, 0x22, 0x25, 0x71, 0x22, 0x20, 0x24, 0x72, 0x6f, 0x75, + 0x74, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x20, 0x7d, 0x7d, + 0x2c, 0x0a, 0x09, 0x09, 0x50, 0x61, 0x74, 0x68, 0x3a, 0x20, 0x20, 0x20, + 0x7b, 0x7b, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x66, 0x20, 0x22, 0x25, + 0x71, 0x22, 0x20, 0x24, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x50, 0x61, + 0x74, 0x68, 0x20, 0x7d, 0x7d, 0x2c, 0x0a, 0x09, 0x09, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x3a, 0x20, 0x7b, 0x7b, 0x20, 0x24, 0x72, 0x6f, 0x75, + 0x74, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x20, 0x7d, 0x7d, + 0x2c, 0x0a, 0x09, 0x09, 0x7b, 0x7b, 0x20, 0x69, 0x66, 0x20, 0x24, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x20, 0x2d, 0x7d, + 0x7d, 0x0a, 0x09, 0x09, 0x42, 0x6f, 0x64, 0x79, 0x3a, 0x20, 0x20, 0x20, + 0x7b, 0x7b, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x66, 0x20, 0x22, 0x25, + 0x71, 0x22, 0x20, 0x24, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x42, 0x6f, + 0x64, 0x79, 0x20, 0x7d, 0x7d, 0x2c, 0x0a, 0x09, 0x09, 0x7b, 0x7b, 0x20, + 0x65, 0x6e, 0x64, 0x20, 0x2d, 0x7d, 0x7d, 0x0a, 0x09, 0x09, 0x48, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x3a, 0x20, 0x6d, 0x61, 0x70, 0x5b, 0x73, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x5d, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x7b, + 0x0a, 0x09, 0x09, 0x09, 0x7b, 0x7b, 0x20, 0x72, 0x61, 0x6e, 0x67, 0x65, + 0x20, 0x24, 0x6b, 0x65, 0x79, 0x2c, 0x20, 0x24, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x20, 0x3a, 0x3d, 0x20, 0x24, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, + 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x2d, 0x7d, 0x7d, 0x0a, 0x09, + 0x09, 0x09, 0x7b, 0x7b, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x66, 0x20, + 0x22, 0x25, 0x71, 0x22, 0x20, 0x24, 0x6b, 0x65, 0x79, 0x20, 0x7d, 0x7d, + 0x20, 0x3a, 0x20, 0x7b, 0x7b, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x66, + 0x20, 0x22, 0x25, 0x71, 0x22, 0x20, 0x24, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x20, 0x7d, 0x7d, 0x2c, 0x0a, 0x09, 0x09, 0x09, 0x7b, 0x7b, 0x20, 0x65, + 0x6e, 0x64, 0x20, 0x7d, 0x7d, 0x0a, 0x09, 0x09, 0x7d, 0x2c, 0x0a, 0x09, + 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7b, 0x7b, 0x20, 0x65, 0x6e, + 0x64, 0x20, 0x7d, 0x7d, 0x0a, 0x7d, 0x0a, 0x0a, 0x7b, 0x7b, 0x2f, 0x2a, + 0x0a, 0x2f, 0x2f, 0x0a, 0x2f, 0x2f, 0x20, 0x68, 0x74, 0x74, 0x70, 0x20, + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x0a, 0x2f, 0x2f, + 0x0a, 0x0a, 0x7b, 0x7b, 0x20, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x24, + 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2c, 0x20, 0x24, 0x72, 0x6f, 0x75, 0x74, + 0x65, 0x20, 0x3a, 0x3d, 0x20, 0x2e, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x73, + 0x20, 0x7d, 0x7d, 0x0a, 0x7b, 0x7b, 0x20, 0x69, 0x66, 0x20, 0x24, 0x72, + 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x42, 0x6f, 0x64, 0x79, 0x20, 0x2d, 0x7d, + 0x7d, 0x0a, 0x2f, 0x2f, 0x20, 0x7b, 0x7b, 0x20, 0x24, 0x72, 0x6f, 0x75, + 0x74, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x20, 0x7d, 0x7d, + 0x20, 0x7b, 0x7b, 0x20, 0x24, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x50, + 0x61, 0x74, 0x68, 0x20, 0x7d, 0x7d, 0x0a, 0x76, 0x61, 0x72, 0x20, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x7b, 0x7b, 0x20, 0x24, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x20, 0x7d, 0x7d, 0x20, 0x3d, 0x20, 0x60, 0x7b, + 0x7b, 0x20, 0x24, 0x72, 0x6f, 0x75, 0x74, 0x65, 0x2e, 0x42, 0x6f, 0x64, + 0x79, 0x20, 0x7d, 0x7d, 0x60, 0x0a, 0x7b, 0x7b, 0x20, 0x65, 0x6e, 0x64, + 0x20, 0x7d, 0x7d, 0x0a, 0x7b, 0x7b, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x7d, + 0x7d, 0x0a, 0x2a, 0x2f, 0x7d, 0x7d, 0x0a, +} + +// files/i18n.tmpl +var i18n = []byte{ + 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x20, 0x7b, 0x7b, 0x20, 0x2e, + 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x20, 0x7d, 0x7d, 0x0a, 0x0a, + 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x22, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6e, 0x69, 0x63, 0x6b, 0x73, + 0x6e, 0x79, 0x64, 0x65, 0x72, 0x2f, 0x67, 0x6f, 0x2d, 0x69, 0x31, 0x38, + 0x6e, 0x2f, 0x69, 0x31, 0x38, 0x6e, 0x22, 0x0a, 0x0a, 0x2f, 0x2f, 0x20, + 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x65, 0x6d, 0x62, 0x65, + 0x64, 0x64, 0x65, 0x64, 0x20, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, + 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x0a, 0x76, 0x61, 0x72, + 0x20, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x20, 0x3d, 0x20, 0x5b, 0x5d, 0x73, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x7b, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, + 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x0a, 0x09, 0x64, 0x61, 0x74, + 0x61, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x0a, 0x7d, 0x20, 0x7b, + 0x0a, 0x09, 0x7b, 0x7b, 0x20, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x2e, + 0x46, 0x69, 0x6c, 0x65, 0x73, 0x20, 0x2d, 0x7d, 0x7d, 0x0a, 0x09, 0x7b, + 0x0a, 0x09, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x20, 0x7b, 0x7b, 0x20, + 0x70, 0x72, 0x69, 0x6e, 0x74, 0x66, 0x20, 0x22, 0x25, 0x71, 0x22, 0x20, + 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x20, 0x7d, 0x7d, 0x2c, 0x0a, 0x09, 0x09, + 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x7b, 0x7b, 0x20, 0x2e, 0x42, 0x61, + 0x73, 0x65, 0x20, 0x7c, 0x20, 0x63, 0x61, 0x6d, 0x65, 0x6c, 0x69, 0x7a, + 0x65, 0x20, 0x7d, 0x7d, 0x2c, 0x0a, 0x09, 0x7d, 0x2c, 0x0a, 0x09, 0x7b, + 0x7b, 0x2d, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x7d, 0x7d, 0x0a, 0x7d, 0x0a, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x69, 0x6e, 0x69, 0x74, 0x28, 0x29, + 0x20, 0x7b, 0x0a, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x5f, 0x2c, 0x20, 0x66, + 0x69, 0x6c, 0x65, 0x20, 0x3a, 0x3d, 0x20, 0x72, 0x61, 0x6e, 0x67, 0x65, + 0x20, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x69, + 0x31, 0x38, 0x6e, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x46, 0x69, 0x6c, 0x65, + 0x42, 0x79, 0x74, 0x65, 0x73, 0x28, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x6e, + 0x61, 0x6d, 0x65, 0x2c, 0x20, 0x5b, 0x5d, 0x62, 0x79, 0x74, 0x65, 0x28, + 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x29, 0x29, 0x0a, + 0x09, 0x7d, 0x0a, 0x7d, 0x0a, 0x0a, 0x2f, 0x2f, 0x0a, 0x2f, 0x2f, 0x20, + 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x20, 0x74, 0x65, 0x6d, + 0x70, 0x6c, 0x61, 0x74, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, + 0x0a, 0x2f, 0x2f, 0x0a, 0x0a, 0x7b, 0x7b, 0x20, 0x72, 0x61, 0x6e, 0x67, + 0x65, 0x20, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x20, 0x7d, 0x7d, 0x0a, + 0x2f, 0x2f, 0x20, 0x7b, 0x7b, 0x20, 0x2e, 0x50, 0x61, 0x74, 0x68, 0x20, + 0x7d, 0x7d, 0x0a, 0x76, 0x61, 0x72, 0x20, 0x7b, 0x7b, 0x20, 0x2e, 0x42, + 0x61, 0x73, 0x65, 0x20, 0x7c, 0x20, 0x63, 0x61, 0x6d, 0x65, 0x6c, 0x69, + 0x7a, 0x65, 0x20, 0x7d, 0x7d, 0x20, 0x3d, 0x20, 0x60, 0x7b, 0x7b, 0x20, + 0x2e, 0x44, 0x61, 0x74, 0x61, 0x20, 0x7d, 0x7d, 0x60, 0x0a, 0x7b, 0x7b, + 0x20, 0x65, 0x6e, 0x64, 0x20, 0x7d, 0x7d, 0x0a, +} + +// files/sql.tmpl +var sql = []byte{ + 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x20, 0x7b, 0x7b, 0x20, 0x2e, + 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x20, 0x7d, 0x7d, 0x0a, 0x0a, + 0x2f, 0x2f, 0x20, 0x4c, 0x6f, 0x6f, 0x6b, 0x75, 0x70, 0x20, 0x72, 0x65, + 0x74, 0x75, 0x72, 0x6e, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x61, + 0x6d, 0x65, 0x64, 0x20, 0x73, 0x74, 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x2e, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x4c, 0x6f, 0x6f, 0x6b, + 0x75, 0x70, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x29, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x7b, + 0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x69, 0x6e, 0x64, + 0x65, 0x78, 0x5b, 0x6e, 0x61, 0x6d, 0x65, 0x5d, 0x0a, 0x7d, 0x0a, 0x0a, + 0x76, 0x61, 0x72, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x3d, 0x20, + 0x6d, 0x61, 0x70, 0x5b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5d, 0x73, + 0x74, 0x72, 0x69, 0x6e, 0x67, 0x7b, 0x0a, 0x09, 0x7b, 0x7b, 0x20, 0x72, + 0x61, 0x6e, 0x67, 0x65, 0x20, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x20, 0x2d, 0x7d, 0x7d, 0x0a, 0x09, 0x7b, 0x7b, + 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x66, 0x20, 0x22, 0x25, 0x71, 0x22, + 0x20, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x20, 0x7d, 0x7d, 0x3a, 0x20, 0x7b, + 0x7b, 0x20, 0x63, 0x61, 0x6d, 0x65, 0x6c, 0x69, 0x7a, 0x65, 0x20, 0x2e, + 0x4e, 0x61, 0x6d, 0x65, 0x20, 0x7d, 0x7d, 0x2c, 0x0a, 0x09, 0x7b, 0x7b, + 0x20, 0x65, 0x6e, 0x64, 0x20, 0x2d, 0x7d, 0x7d, 0x0a, 0x7d, 0x0a, 0x0a, + 0x7b, 0x7b, 0x20, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x2e, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x7d, 0x7d, 0x0a, + 0x76, 0x61, 0x72, 0x20, 0x7b, 0x7b, 0x20, 0x63, 0x61, 0x6d, 0x65, 0x6c, + 0x69, 0x7a, 0x65, 0x20, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x20, 0x7d, 0x7d, + 0x20, 0x3d, 0x20, 0x60, 0x0a, 0x7b, 0x7b, 0x20, 0x2e, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x20, 0x7d, 0x7d, 0x0a, 0x60, 0x0a, 0x7b, 0x7b, 0x20, 0x65, + 0x6e, 0x64, 0x20, 0x7d, 0x7d, 0x0a, +} + +// files/tmpl.tmpl +var tmpl = []byte{ + 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x20, 0x7b, 0x7b, 0x20, 0x2e, + 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x20, 0x7d, 0x7d, 0x0a, 0x0a, + 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x20, 0x22, 0x7b, 0x7b, 0x20, 0x2e, + 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x7d, 0x7d, 0x2f, 0x74, 0x65, + 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x22, 0x0a, 0x0a, 0x7b, 0x7b, 0x2d, + 0x20, 0x24, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x20, 0x3a, 0x3d, + 0x20, 0x2e, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x20, 0x7d, 0x7d, 0x0a, + 0x0a, 0x2f, 0x2f, 0x20, 0x6c, 0x69, 0x73, 0x74, 0x20, 0x6f, 0x66, 0x20, + 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x20, 0x74, 0x65, 0x6d, + 0x70, 0x6c, 0x61, 0x74, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, + 0x0a, 0x76, 0x61, 0x72, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x20, 0x3d, + 0x20, 0x5b, 0x5d, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x7b, 0x0a, 0x09, + 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x0a, + 0x09, 0x64, 0x61, 0x74, 0x61, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, + 0x0a, 0x7d, 0x20, 0x7b, 0x0a, 0x09, 0x7b, 0x7b, 0x20, 0x72, 0x61, 0x6e, + 0x67, 0x65, 0x20, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x20, 0x2d, 0x7d, + 0x7d, 0x0a, 0x09, 0x7b, 0x0a, 0x09, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x3a, + 0x20, 0x7b, 0x7b, 0x20, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x66, 0x20, 0x22, + 0x25, 0x71, 0x22, 0x20, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x20, 0x7d, 0x7d, + 0x2c, 0x0a, 0x09, 0x09, 0x7b, 0x7b, 0x20, 0x69, 0x66, 0x20, 0x24, 0x65, + 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x20, 0x2d, 0x7d, 0x7d, 0x0a, 0x09, + 0x09, 0x64, 0x61, 0x74, 0x61, 0x3a, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x28, 0x7b, 0x7b, 0x20, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x20, 0x7c, + 0x20, 0x63, 0x61, 0x6d, 0x65, 0x6c, 0x69, 0x7a, 0x65, 0x20, 0x7d, 0x7d, + 0x29, 0x2c, 0x0a, 0x09, 0x09, 0x7b, 0x7b, 0x2d, 0x20, 0x65, 0x6c, 0x73, + 0x65, 0x20, 0x2d, 0x7d, 0x7d, 0x0a, 0x09, 0x09, 0x64, 0x61, 0x74, 0x61, + 0x3a, 0x20, 0x7b, 0x7b, 0x20, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x20, 0x7c, + 0x20, 0x63, 0x61, 0x6d, 0x65, 0x6c, 0x69, 0x7a, 0x65, 0x20, 0x7d, 0x7d, + 0x2c, 0x0a, 0x09, 0x09, 0x7b, 0x7b, 0x2d, 0x20, 0x65, 0x6e, 0x64, 0x20, + 0x7d, 0x7d, 0x0a, 0x09, 0x7d, 0x2c, 0x0a, 0x09, 0x7b, 0x7b, 0x2d, 0x20, + 0x65, 0x6e, 0x64, 0x20, 0x7d, 0x7d, 0x0a, 0x7d, 0x0a, 0x0a, 0x2f, 0x2f, + 0x20, 0x54, 0x20, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x20, + 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x2e, 0x0a, 0x76, + 0x61, 0x72, 0x20, 0x54, 0x20, 0x2a, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, + 0x74, 0x65, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x0a, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x69, 0x6e, 0x69, 0x74, 0x28, 0x29, + 0x20, 0x7b, 0x0a, 0x09, 0x54, 0x20, 0x3d, 0x20, 0x74, 0x65, 0x6d, 0x70, + 0x6c, 0x61, 0x74, 0x65, 0x2e, 0x4e, 0x65, 0x77, 0x28, 0x22, 0x5f, 0x22, + 0x29, 0x7b, 0x7b, 0x20, 0x69, 0x66, 0x20, 0x2e, 0x46, 0x75, 0x6e, 0x63, + 0x73, 0x20, 0x7d, 0x7d, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x73, 0x28, 0x7b, + 0x7b, 0x20, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x73, 0x20, 0x7d, 0x7d, 0x29, + 0x7b, 0x7b, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x7d, 0x7d, 0x0a, 0x09, 0x66, + 0x6f, 0x72, 0x20, 0x5f, 0x2c, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x3a, + 0x3d, 0x20, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x66, 0x69, 0x6c, 0x65, + 0x73, 0x20, 0x7b, 0x0a, 0x09, 0x09, 0x54, 0x20, 0x3d, 0x20, 0x74, 0x65, + 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x2e, 0x4d, 0x75, 0x73, 0x74, 0x28, + 0x0a, 0x09, 0x09, 0x09, 0x54, 0x2e, 0x4e, 0x65, 0x77, 0x28, 0x66, 0x69, + 0x6c, 0x65, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x2e, 0x50, 0x61, 0x72, + 0x73, 0x65, 0x28, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x64, 0x61, 0x74, 0x61, + 0x29, 0x2c, 0x0a, 0x09, 0x09, 0x29, 0x0a, 0x09, 0x7d, 0x0a, 0x7d, 0x0a, + 0x0a, 0x2f, 0x2f, 0x0a, 0x2f, 0x2f, 0x20, 0x65, 0x6d, 0x62, 0x65, 0x64, + 0x64, 0x65, 0x64, 0x20, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, + 0x20, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x2e, 0x0a, 0x2f, 0x2f, 0x0a, 0x0a, + 0x7b, 0x7b, 0x20, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x2e, 0x46, 0x69, + 0x6c, 0x65, 0x73, 0x20, 0x7d, 0x7d, 0x0a, 0x2f, 0x2f, 0x20, 0x7b, 0x7b, + 0x20, 0x2e, 0x50, 0x61, 0x74, 0x68, 0x20, 0x7d, 0x7d, 0x0a, 0x7b, 0x7b, + 0x20, 0x69, 0x66, 0x20, 0x24, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, + 0x20, 0x2d, 0x7d, 0x7d, 0x0a, 0x76, 0x61, 0x72, 0x20, 0x7b, 0x7b, 0x20, + 0x2e, 0x42, 0x61, 0x73, 0x65, 0x20, 0x7c, 0x20, 0x63, 0x61, 0x6d, 0x65, + 0x6c, 0x69, 0x7a, 0x65, 0x20, 0x7d, 0x7d, 0x20, 0x3d, 0x20, 0x5b, 0x5d, + 0x62, 0x79, 0x74, 0x65, 0x7b, 0x0a, 0x7b, 0x7b, 0x20, 0x2e, 0x44, 0x61, + 0x74, 0x61, 0x20, 0x7c, 0x20, 0x68, 0x65, 0x78, 0x64, 0x75, 0x6d, 0x70, + 0x20, 0x7d, 0x7d, 0x0a, 0x7d, 0x0a, 0x7b, 0x7b, 0x20, 0x65, 0x6c, 0x73, + 0x65, 0x20, 0x2d, 0x7d, 0x7d, 0x0a, 0x76, 0x61, 0x72, 0x20, 0x7b, 0x7b, + 0x20, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x20, 0x7c, 0x20, 0x63, 0x61, 0x6d, + 0x65, 0x6c, 0x69, 0x7a, 0x65, 0x20, 0x7d, 0x7d, 0x20, 0x3d, 0x20, 0x60, + 0x7b, 0x7b, 0x20, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x20, 0x7d, 0x7d, 0x60, + 0x0a, 0x7b, 0x7b, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x7d, 0x7d, 0x0a, 0x7b, + 0x7b, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x7d, 0x7d, 0x0a, +} diff --git a/vendor/github.com/woodpecker-ci/togo/action_ddl.go b/vendor/github.com/woodpecker-ci/togo/action_ddl.go new file mode 100644 index 000000000..d171a267c --- /dev/null +++ b/vendor/github.com/woodpecker-ci/togo/action_ddl.go @@ -0,0 +1,104 @@ +package main + +import ( + "os" + "path/filepath" + + "github.com/urfave/cli" + + "github.com/bradrydzewski/togo/parser" + "github.com/bradrydzewski/togo/template" +) + +type migration struct { + Name string + Statements []*parser.Statement +} + +type logger struct { + Enabled bool + Package string +} + +type migrationParams struct { + Package string + Dialect string + Migrations []migration + Logger logger +} + +var ddlCommand = cli.Command{ + Name: "ddl", + Usage: "embed ddl statements", + Action: ddlAction, + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "package", + Value: "ddl", + }, + cli.StringFlag{ + Name: "dialect", + Value: "sqlite3", + }, + cli.StringFlag{ + Name: "input", + Value: "files/*.sql", + }, + cli.StringFlag{ + Name: "output", + Value: "ddl_gen.go", + }, + cli.BoolFlag{ + Name: "log", + }, + cli.StringFlag{ + Name: "logger", + Value: "log", // log, logrus + }, + }, +} + +func ddlAction(c *cli.Context) error { + pattern := c.Args().First() + if pattern == "" { + pattern = c.String("input") + } + + matches, err := filepath.Glob(pattern) + if err != nil { + return err + } + + params := migrationParams{ + Package: c.String("package"), + Dialect: c.String("dialect"), + Logger: logger{ + Enabled: c.Bool("log"), + Package: c.String("logger"), + }, + } + + parse := parser.New() + for _, match := range matches { + statements, perr := parse.ParseFile(match) + if perr != nil { + return perr + } + _, filename := filepath.Split(match) + params.Migrations = append(params.Migrations, migration{ + Name: filename, + Statements: statements, + }) + } + + wr := os.Stdout + if output := c.String("output"); output != "" { + wr, err = os.Create(output) + if err != nil { + return err + } + defer wr.Close() + } + + return template.Execute(wr, "ddl.tmpl", params) +} diff --git a/vendor/github.com/woodpecker-ci/togo/action_http.go b/vendor/github.com/woodpecker-ci/togo/action_http.go new file mode 100644 index 000000000..40389ebf5 --- /dev/null +++ b/vendor/github.com/woodpecker-ci/togo/action_http.go @@ -0,0 +1,143 @@ +package main + +import ( + "io/ioutil" + "os" + "path/filepath" + "regexp" + "strings" + + "github.com/bmatcuk/doublestar" + "github.com/urfave/cli" + + "github.com/bradrydzewski/togo/template" +) + +type ( + httpParams struct { + Encode bool + Package string + Files []*httpFile + } + httpFile struct { + Base string + Name string + Path string + Ext string + Data string + Size int64 + Time int64 + Encoded bool + } +) + +var httpCommand = cli.Command{ + Name: "http", + Usage: "generate an http filesystem", + Action: httpAction, + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "package", + Value: "http", + }, + cli.StringFlag{ + Name: "input", + Value: "files/**", + }, + cli.StringFlag{ + Name: "output", + Value: "http_gen.go", + }, + cli.StringFlag{ + Name: "exclude", + }, + cli.StringFlag{ + Name: "trim-prefix", + Value: "files", + }, + cli.StringSliceFlag{ + Name: "plain-text", + Value: &cli.StringSlice{"html", "js", "css"}, + }, + }, +} + +func httpAction(c *cli.Context) error { + pattern := c.Args().First() + if pattern == "" { + pattern = c.String("input") + } + + matches, err := doublestar.Glob(pattern) + if err != nil { + return err + } + + params := httpParams{ + Encode: c.Bool("encode"), + Package: c.String("package"), + } + + var ( + prefix = c.String("trim-prefix") + exclude *regexp.Regexp + ) + + if s := c.String("exclude"); s != "" { + exclude = regexp.MustCompilePOSIX(s) + } + + for _, match := range matches { + stat, oserr := os.Stat(match) + if oserr != nil { + return oserr + } + if stat.IsDir() { + continue + } + if exclude != nil && exclude.MatchString(match) { + continue + } + + raw, ioerr := ioutil.ReadFile(match) + if ioerr != nil { + return ioerr + } + encoded := true + switch { + case strings.HasSuffix(match, ".min.js"): + case strings.HasSuffix(match, ".min.css"): + case strings.HasSuffix(match, ".css"): + encoded = false + case strings.HasSuffix(match, ".js"): + encoded = false + case strings.HasSuffix(match, ".html"): + encoded = false + } + data := string(raw) + if !encoded { + data = strings.Replace(data, "`", "`+\"`\"+`", -1) + } + params.Files = append(params.Files, &httpFile{ + Path: strings.TrimPrefix(match, prefix), + Name: filepath.Base(match), + Base: strings.TrimSuffix(filepath.Base(match), filepath.Ext(match)), + Ext: filepath.Ext(match), + Data: data, + Time: stat.ModTime().Unix(), + Size: stat.Size(), + Encoded: encoded, + }) + } + + wr := os.Stdout + if output := c.String("output"); output != "" { + wr, err = os.Create(output) + if err != nil { + return err + } + defer wr.Close() + } + + return template.Execute(wr, "http.tmpl", ¶ms) +} diff --git a/vendor/github.com/woodpecker-ci/togo/action_httptest.go b/vendor/github.com/woodpecker-ci/togo/action_httptest.go new file mode 100644 index 000000000..0e7b662a6 --- /dev/null +++ b/vendor/github.com/woodpecker-ci/togo/action_httptest.go @@ -0,0 +1,174 @@ +package main + +import ( + "bufio" + "bytes" + "fmt" + "io/ioutil" + "log" + "net/textproto" + "os" + "regexp" + "strconv" + "strings" + + "github.com/bmatcuk/doublestar" + "github.com/urfave/cli" + + "github.com/bradrydzewski/togo/template" +) + +type ( + httptestParams struct { + Package string + Routes []*httptestRoute + } + httptestRoute struct { + Source string + Method string + Path string + Body string + Status int + Header map[string]string + } +) + +var httptestCommand = cli.Command{ + Name: "httptest", + Usage: "generate httptest server", + Action: httptestAction, + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "package", + Value: "testdata", + }, + cli.StringFlag{ + Name: "input", + Value: "files/**", + }, + cli.StringFlag{ + Name: "output", + Value: "testdata_gen.go", + }, + cli.StringFlag{ + Name: "exclude", + }, + }, +} + +func httptestAction(c *cli.Context) error { + pattern := c.Args().First() + if pattern == "" { + pattern = c.String("input") + } + + matches, err := doublestar.Glob(pattern) + if err != nil { + return err + } + + var exclude *regexp.Regexp + if s := c.String("exclude"); s != "" { + exclude = regexp.MustCompilePOSIX(s) + } + + params := httptestParams{ + Package: c.String("package"), + } + + for _, match := range matches { + stat, oserr := os.Stat(match) + if oserr != nil { + return oserr + } + if stat.IsDir() { + continue + } + if exclude != nil && exclude.MatchString(match) { + continue + } + + log.Printf("parsing file %s", match) + + raw, ioerr := ioutil.ReadFile(match) + if ioerr != nil { + return ioerr + } + + route, parseErr := parseRoute(raw) + if parseErr != nil { + return parseErr + } + route.Source = strings.TrimPrefix(match, "files/") + + params.Routes = append(params.Routes, route) + } + + wr := os.Stdout + if output := c.String("output"); output != "" { + wr, err = os.Create(output) + if err != nil { + return err + } + defer wr.Close() + } + + return template.Execute(wr, "httptest.tmpl", ¶ms) +} + +func parseRoute(in []byte) (*httptestRoute, error) { + out := new(httptestRoute) + out.Header = map[string]string{} + + buf := bufio.NewReader(bytes.NewBuffer(in)) + r := textproto.NewReader(buf) + + // + // parses the method and path + // + + line, err := r.ReadLine() + if err != nil { + return nil, err + } + parts := strings.Split(line, " ") + if len(parts) != 2 { + return nil, fmt.Errorf("Invalid request line. Want .") + } + out.Method = parts[0] + out.Path = parts[1] + + // + // parses the mime headers + // + + header, err := r.ReadMIMEHeader() + if err != nil { + fmt.Println(err) + } + for k, v := range header { + out.Header[k] = strings.Join(v, "; ") + } + + // + // extracts the response status code + // + + out.Status, err = strconv.Atoi(header.Get("Status")) + if err != nil { + return nil, fmt.Errorf("Invalid Status code. %s", err) + } + delete(out.Header, "Status") + + // + // parse the remainder of the file as the body + // + + body, err := ioutil.ReadAll(buf) + if err != nil { + return nil, err + } + out.Body = string(body) + + return out, nil +} diff --git a/vendor/github.com/woodpecker-ci/togo/action_i18n.go b/vendor/github.com/woodpecker-ci/togo/action_i18n.go new file mode 100644 index 000000000..5c9eff7b2 --- /dev/null +++ b/vendor/github.com/woodpecker-ci/togo/action_i18n.go @@ -0,0 +1,90 @@ +package main + +import ( + "io/ioutil" + "os" + "path/filepath" + "strings" + + "github.com/urfave/cli" + + "github.com/bradrydzewski/togo/template" +) + +type ( + i18nParams struct { + Package string + Files []*i18nFile + } + i18nFile struct { + Base string + Name string + Path string + Ext string + Data string + } +) + +var i18nCommand = cli.Command{ + Name: "i18n", + Usage: "embed i18n files", + Action: i18nAction, + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "package", + Value: "i18n", + }, + cli.StringFlag{ + Name: "input", + Value: "files/*.all.json", + }, + cli.StringFlag{ + Name: "output", + Value: "i18n_gen.go", + }, + cli.BoolFlag{ + Name: "encode", + }, + }, +} + +func i18nAction(c *cli.Context) error { + pattern := c.Args().First() + if pattern == "" { + pattern = c.String("input") + } + + matches, err := filepath.Glob(pattern) + if err != nil { + return err + } + + params := i18nParams{ + Package: c.String("package"), + } + + for _, match := range matches { + raw, ioerr := ioutil.ReadFile(match) + if ioerr != nil { + return ioerr + } + params.Files = append(params.Files, &i18nFile{ + Path: match, + Name: filepath.Base(match), + Base: strings.TrimSuffix(filepath.Base(match), filepath.Ext(match)), + Ext: filepath.Ext(match), + Data: string(raw), + }) + } + + wr := os.Stdout + if output := c.String("output"); output != "" { + wr, err = os.Create(output) + if err != nil { + return err + } + defer wr.Close() + } + + return template.Execute(wr, "i18n.tmpl", params) +} diff --git a/vendor/github.com/woodpecker-ci/togo/action_sql.go b/vendor/github.com/woodpecker-ci/togo/action_sql.go new file mode 100644 index 000000000..b47135945 --- /dev/null +++ b/vendor/github.com/woodpecker-ci/togo/action_sql.go @@ -0,0 +1,78 @@ +package main + +import ( + "os" + "path/filepath" + + "github.com/urfave/cli" + + "github.com/bradrydzewski/togo/parser" + "github.com/bradrydzewski/togo/template" +) + +type sqlParams struct { + Package string + Dialect string + Statements []*parser.Statement +} + +var sqlCommand = cli.Command{ + Name: "sql", + Usage: "embed sql statements", + Action: sqlAction, + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "package", + Value: "sql", + }, + cli.StringFlag{ + Name: "dialect", + Value: "sqlite3", + }, + cli.StringFlag{ + Name: "input", + Value: "files/*.sql", + }, + cli.StringFlag{ + Name: "output", + Value: "sql_gen.go", + }, + }, +} + +func sqlAction(c *cli.Context) error { + pattern := c.Args().First() + if pattern == "" { + pattern = c.String("input") + } + + matches, err := filepath.Glob(pattern) + if err != nil { + return err + } + + params := sqlParams{ + Package: c.String("package"), + Dialect: c.String("dialect"), + } + + parse := parser.New() + for _, match := range matches { + statements, perr := parse.ParseFile(match) + if perr != nil { + return perr + } + params.Statements = append(params.Statements, statements...) + } + + wr := os.Stdout + if output := c.String("output"); output != "" { + wr, err = os.Create(output) + if err != nil { + return err + } + defer wr.Close() + } + + return template.Execute(wr, "sql.tmpl", params) +} diff --git a/vendor/github.com/woodpecker-ci/togo/action_tmpl.go b/vendor/github.com/woodpecker-ci/togo/action_tmpl.go new file mode 100644 index 000000000..d24525dd8 --- /dev/null +++ b/vendor/github.com/woodpecker-ci/togo/action_tmpl.go @@ -0,0 +1,103 @@ +package main + +import ( + "io/ioutil" + "os" + "path/filepath" + "strings" + + "github.com/urfave/cli" + + "github.com/bradrydzewski/togo/template" +) + +type ( + tmplParams struct { + Encode bool + Package string + Format string + Funcs string + Files []*tmplFile + } + tmplFile struct { + Base string + Name string + Path string + Ext string + Data string + } +) + +var tmplCommand = cli.Command{ + Name: "tmpl", + Usage: "embed template files", + Action: tmplAction, + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "package", + Value: "template", + }, + cli.StringFlag{ + Name: "func", + }, + cli.StringFlag{ + Name: "input", + Value: "files/*.tmpl", + }, + cli.StringFlag{ + Name: "output", + Value: "template_gen.go", + }, + cli.StringFlag{ + Name: "format", + Value: "text", + }, + cli.BoolFlag{ + Name: "encode", + }, + }, +} + +func tmplAction(c *cli.Context) error { + pattern := c.Args().First() + if pattern == "" { + pattern = c.String("input") + } + + matches, err := filepath.Glob(pattern) + if err != nil { + return err + } + + params := tmplParams{ + Encode: c.Bool("encode"), + Package: c.String("package"), + Format: c.String("format"), + Funcs: c.String("func"), + } + + for _, match := range matches { + raw, ioerr := ioutil.ReadFile(match) + if ioerr != nil { + return ioerr + } + params.Files = append(params.Files, &tmplFile{ + Path: match, + Name: filepath.Base(match), + Base: strings.TrimSuffix(filepath.Base(match), filepath.Ext(match)), + Ext: filepath.Ext(match), + Data: string(raw), + }) + } + + wr := os.Stdout + if output := c.String("output"); output != "" { + wr, err = os.Create(output) + if err != nil { + return err + } + defer wr.Close() + } + + return template.Execute(wr, "tmpl.tmpl", params) +} diff --git a/vendor/github.com/woodpecker-ci/togo/main.go b/vendor/github.com/woodpecker-ci/togo/main.go new file mode 100644 index 000000000..3fdc233f7 --- /dev/null +++ b/vendor/github.com/woodpecker-ci/togo/main.go @@ -0,0 +1,28 @@ +package main + +import ( + "fmt" + "os" + + "github.com/urfave/cli" +) + +func main() { + app := cli.NewApp() + app.Name = "togo" + app.Usage = "togo provides tools to convert files to go" + app.Version = "1.0.0" + app.Author = "bradrydzewski" + app.Commands = []cli.Command{ + ddlCommand, + sqlCommand, + httpCommand, + httptestCommand, + tmplCommand, + i18nCommand, + } + if err := app.Run(os.Args); err != nil { + fmt.Println(err) + os.Exit(1) + } +} diff --git a/vendor/modules.txt b/vendor/modules.txt index a733bd43d..f077a9eca 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -30,6 +30,13 @@ github.com/Microsoft/go-winio github.com/Microsoft/go-winio/pkg/guid # github.com/beorn7/perks v1.0.1 github.com/beorn7/perks/quantile +# github.com/bmatcuk/doublestar v1.3.4 +## explicit +github.com/bmatcuk/doublestar +# github.com/bradrydzewski/togo v0.0.0-20180401185031-50a0e4726e74 +## explicit +github.com/bradrydzewski/togo/parser +github.com/bradrydzewski/togo/template # github.com/cespare/xxhash/v2 v2.1.1 github.com/cespare/xxhash/v2 # github.com/cpuguy83/go-md2man/v2 v2.0.0 @@ -249,6 +256,9 @@ github.com/urfave/cli ## explicit github.com/woodpecker-ci/expr github.com/woodpecker-ci/expr/parse +# github.com/woodpecker-ci/togo v0.0.0-20180401185031-50a0e4726e74 +## explicit +github.com/woodpecker-ci/togo # golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 ## explicit golang.org/x/crypto/acme