From 991490c500ffe799e77a4f289d4171b03c36727d Mon Sep 17 00:00:00 2001 From: Dmitri Shuralyov Date: Sun, 15 Sep 2019 18:04:54 -0400 Subject: [PATCH 1/2] support being built and used with newer versions of Go This change removes the build-time check that GopherJS was built with Go version 1.12, and replaces it with a runtime check instead. Add and document a new GopherJS-specific environment variable: GOPHERJS_GOROOT - if set, GopherJS uses this value as the default GOROOT value, instead of using the system GOROOT as the default GOROOT value The main reason that GopherJS required Go 1.12 to be built in the past was as a way of ensuring that the Go 1.12 standard library code is available on disk, which GopherJS 1.12-2 needs to build Go code. Now that the Go distribution can provided to GopherJS with convenience via the GOPHERJS_GOROOT environment variable, we can allow GopherJS to be built with a newer version of Go, as long as a Go 1.12 distribution is provided via GOPHERJS_GOROOT. Update GopherJS installation instructions to support being installed with Go 1.12 and newer versions of Go. The Go distribution version check is added to build.NewSession. That check may fail, and so it was necessary to add an error return value to the signature of build.NewSession. The build API is deemed semi-internal, so a breaking API change is unfortunate but acceptable. Regenerate ./compiler/natives with: go generate ./... Fixes #941 --- README.md | 19 +++++++++++ build/build.go | 36 +++++++++++++++------ compiler/compiler.go | 1 - compiler/natives/fs_vfsdata.go | 6 ++-- compiler/natives/src/runtime/runtime.go | 8 +++-- compiler/version_check.go | 24 +++++++++++--- tests/run.go | 12 ++----- tool.go | 42 ++++++++++++++++++++----- 8 files changed, 111 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 64b2b22a4..ed923cffe 100644 --- a/README.md +++ b/README.md @@ -14,12 +14,22 @@ Give GopherJS a try on the [GopherJS Playground](http://gopherjs.github.io/playg Nearly everything, including Goroutines ([compatibility table](https://github.com/gopherjs/gopherjs/blob/master/doc/packages.md)). Performance is quite good in most cases, see [HTML5 game engine benchmark](https://ajhager.github.io/engi/demos/botmark.html). Cgo is not supported. ### Installation and Usage +GopherJS requires Go 1.12 or newer. + Get or update GopherJS and dependencies with: ``` go get -u github.com/gopherjs/gopherjs ``` +If your local Go distribution as reported by `go version` is newer than Go 1.12, then you need to set the `GOPHERJS_GOROOT` environment variable to a directory that contains a Go 1.12 distribution. For example: + +``` +go get golang.org/dl/go1.12.16 +go1.12.16 download +export GOPHERJS_GOROOT="$(go1.12.16 env GOROOT)" # Also add this line to your .profile or equivalent. +``` + Now you can use `gopherjs build [package]`, `gopherjs build [files]` or `gopherjs install [package]` which behave similar to the `go` tool. For `main` packages, these commands create a `.js` file and `.js.map` source map in the current directory or in `$GOPATH/bin`. The generated JavaScript file can be used as usual in a website. Use `gopherjs help [command]` to get a list of possible command line flags, e.g. for minification and automatically watching for changes. `gopherjs` uses your platform's default `GOOS` value when generating code. Supported `GOOS` values are: `linux`, `darwin`. If you're on a different platform (e.g., Windows or FreeBSD), you'll need to set the `GOOS` environment variable to a supported value. For example, `GOOS=linux gopherjs build [package]`. @@ -46,6 +56,15 @@ Refreshing in the browser will rebuild the served files if needed. Compilation e If you include an argument, it will be the root from which everything is served. For example, if you run `gopherjs serve github.com/user/project` then the generated JavaScript for the package github.com/user/project/mypkg will be served at http://localhost:8080/mypkg/mypkg.js. +#### Environment Variables + +There is one GopherJS-specific environment variable: + +``` +GOPHERJS_GOROOT - if set, GopherJS uses this value as the default GOROOT value, + instead of using the system GOROOT as the default GOROOT value +``` + ### Performance Tips - Use the `-m` command line flag to generate minified code. diff --git a/build/build.go b/build/build.go index 7ec14dafe..0a85d8a08 100644 --- a/build/build.go +++ b/build/build.go @@ -28,6 +28,19 @@ import ( "golang.org/x/tools/go/buildutil" ) +// DefaultGOROOT is the default GOROOT value for builds. +// +// It uses the GOPHERJS_GOROOT environment variable if it is set, +// or else the default GOROOT value of the system Go distrubtion. +var DefaultGOROOT = func() string { + if goroot, ok := os.LookupEnv("GOPHERJS_GOROOT"); ok { + // GopherJS-specific GOROOT value takes precedence. + return goroot + } + // The usual default GOROOT. + return build.Default.GOROOT +}() + type ImportCError struct { pkgPath string } @@ -42,9 +55,9 @@ func (e *ImportCError) Error() string { // Core GopherJS packages (i.e., "github.com/gopherjs/gopherjs/js", "github.com/gopherjs/gopherjs/nosync") // are loaded from gopherjspkg.FS virtual filesystem rather than GOPATH. func NewBuildContext(installSuffix string, buildTags []string) *build.Context { - gopherjsRoot := filepath.Join(build.Default.GOROOT, "src", "github.com", "gopherjs", "gopherjs") + gopherjsRoot := filepath.Join(DefaultGOROOT, "src", "github.com", "gopherjs", "gopherjs") return &build.Context{ - GOROOT: build.Default.GOROOT, + GOROOT: DefaultGOROOT, GOPATH: build.Default.GOPATH, GOOS: build.Default.GOOS, GOARCH: "js", @@ -92,7 +105,7 @@ func NewBuildContext(installSuffix string, buildTags []string) *build.Context { // For files in "$GOROOT/src/github.com/gopherjs/gopherjs" directory, // gopherjspkg.FS is consulted first. func statFile(path string) (os.FileInfo, error) { - gopherjsRoot := filepath.Join(build.Default.GOROOT, "src", "github.com", "gopherjs", "gopherjs") + gopherjsRoot := filepath.Join(DefaultGOROOT, "src", "github.com", "gopherjs", "gopherjs") if strings.HasPrefix(path, gopherjsRoot+string(filepath.Separator)) { path = filepath.ToSlash(path[len(gopherjsRoot):]) if fi, err := vfsutil.Stat(gopherjspkg.FS, path); err == nil { @@ -183,10 +196,10 @@ func importWithSrcDir(bctx build.Context, path string, srcDir string, mode build pkg.PkgObj = filepath.Join(pkg.BinDir, filepath.Base(pkg.ImportPath)+".js") } - if _, err := os.Stat(pkg.PkgObj); os.IsNotExist(err) && strings.HasPrefix(pkg.PkgObj, build.Default.GOROOT) { + if _, err := os.Stat(pkg.PkgObj); os.IsNotExist(err) && strings.HasPrefix(pkg.PkgObj, DefaultGOROOT) { // fall back to GOPATH firstGopathWorkspace := filepath.SplitList(build.Default.GOPATH)[0] // TODO: Need to check inside all GOPATH workspaces. - gopathPkgObj := filepath.Join(firstGopathWorkspace, pkg.PkgObj[len(build.Default.GOROOT):]) + gopathPkgObj := filepath.Join(firstGopathWorkspace, pkg.PkgObj[len(DefaultGOROOT):]) if _, err := os.Stat(gopathPkgObj); err == nil { pkg.PkgObj = gopathPkgObj } @@ -476,15 +489,20 @@ type Session struct { Watcher *fsnotify.Watcher } -func NewSession(options *Options) *Session { +func NewSession(options *Options) (*Session, error) { if options.GOROOT == "" { - options.GOROOT = build.Default.GOROOT + options.GOROOT = DefaultGOROOT } if options.GOPATH == "" { options.GOPATH = build.Default.GOPATH } options.Verbose = options.Verbose || options.Watch + // Go distribution version check. + if err := compiler.CheckGoVersion(options.GOROOT); err != nil { + return nil, err + } + s := &Session{ options: options, Archives: make(map[string]*compiler.Archive), @@ -501,10 +519,10 @@ func NewSession(options *Options) *Session { var err error s.Watcher, err = fsnotify.NewWatcher() if err != nil { - panic(err) + return nil, err } } - return s + return s, nil } // BuildContext returns the session's build context. diff --git a/compiler/compiler.go b/compiler/compiler.go index 36ec91a8e..81acc872d 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -17,7 +17,6 @@ import ( var sizes32 = &types.StdSizes{WordSize: 4, MaxAlign: 8} var reservedKeywords = make(map[string]bool) -var _ = ___GOPHERJS_REQUIRES_GO_VERSION_1_12___ // Compile error on other Go versions, because they're not supported. func init() { for _, keyword := range []string{"abstract", "arguments", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "debugger", "default", "delete", "do", "double", "else", "enum", "eval", "export", "extends", "false", "final", "finally", "float", "for", "function", "goto", "if", "implements", "import", "in", "instanceof", "int", "interface", "let", "long", "native", "new", "null", "package", "private", "protected", "public", "return", "short", "static", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "true", "try", "typeof", "undefined", "var", "void", "volatile", "while", "with", "yield"} { diff --git a/compiler/natives/fs_vfsdata.go b/compiler/natives/fs_vfsdata.go index 2c5a82439..0be04e5f4 100644 --- a/compiler/natives/fs_vfsdata.go +++ b/compiler/natives/fs_vfsdata.go @@ -443,10 +443,10 @@ var FS = func() http.FileSystem { }, "/src/runtime/runtime.go": &vfsgen۰CompressedFileInfo{ name: "runtime.go", - modTime: time.Date(2018, 8, 25, 22, 2, 53, 556076244, time.UTC), - uncompressedSize: 5788, + modTime: time.Date(2020, 2, 8, 19, 36, 47, 229763096, time.UTC), + uncompressedSize: 5926, - compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x58\xef\x72\xdb\xb8\x11\xff\x4c\x3e\xc5\x96\xd3\xde\x91\x8e\x22\xd9\xe9\x25\x9d\x66\xea\x0f\x89\xee\xec\xcb\x34\xb6\x3c\x96\xd3\xde\x4c\x9a\xb9\x81\xc0\xa5\x04\x0b\x04\x58\x00\xb4\xac\xf3\xe8\x01\xfa\x20\x7d\xb1\x3e\x49\x67\x01\xfe\x93\x2d\x5f\xda\x4e\xf9\x45\xe2\xe2\xb7\x8b\xc5\xfe\xc3\x2e\x27\x13\x78\xb1\xa8\x85\xcc\xe1\xd6\xc6\x71\xc5\xf8\x9a\x2d\x11\x4c\xad\x9c\x28\x31\x8e\x45\x59\x69\xe3\x20\x8d\xa3\xa4\xa1\x4d\x84\x72\x68\x14\x93\x13\xbb\xb5\x49\x1c\x47\xc9\x52\xb8\x55\xbd\x18\x73\x5d\x4e\x96\xba\x5a\xa1\xb9\xb5\xfd\x9f\x5b\x9b\xc4\x59\x1c\x73\xad\xac\x83\xf3\xd9\x6c\x0e\xa7\x60\xb7\x76\x4c\x7f\x3b\xea\xbb\xeb\xe9\x8f\x70\x0a\x09\x81\x03\x6d\xaa\xcb\x4a\x48\x34\x44\x6d\x65\x25\x71\x3c\x99\x40\xc1\xd6\x08\x85\x36\x80\xc6\x68\x33\x5e\xea\xd8\x6d\x2b\x04\x2c\x18\x47\xb0\xce\xd4\xdc\xc1\x43\x1c\xfd\xec\xa9\x47\xfe\x27\xde\x05\x4c\xa0\xf5\x18\xeb\x0c\xbd\x09\xb5\x8c\x77\x71\x5c\xd4\x8a\x43\xea\x1a\x9e\xac\x59\x49\xdb\x3f\xc4\x60\xd0\xd5\x46\x81\x1b\x5b\x67\xe2\xdd\x13\x8e\x6a\xbd\xac\x98\x5b\x1d\x62\x49\x92\x6e\x0b\xa1\x84\x4b\x33\x5a\xbb\xb5\x57\xeb\x25\xbc\x3d\x85\x5b\x3b\x3e\x97\x7a\xc1\xe4\xf8\x1c\x5d\x9a\xfc\xb6\x71\x83\x4d\xb2\x40\xf8\x9a\x85\x33\x92\xd5\x8a\x98\x7b\x11\xb7\x76\xb6\xb8\x45\xee\xae\x9c\x49\x46\xe0\x77\x0a\xb2\x02\xb9\x95\x5c\x39\x93\x64\x07\xd9\x7f\x20\xf3\x3e\xe1\xf6\xd4\xaf\x31\xbb\x95\xd1\x9b\xeb\x10\x2e\x81\x81\x64\x8c\x3f\x34\x81\x13\x34\x48\x3d\x8a\xd8\x27\x13\x60\x77\x5a\xe4\x90\x23\xcb\x81\xeb\x1c\x01\xa5\x28\x85\x62\x4e\x68\x15\x47\x77\xcc\x00\x06\x77\xc7\x11\xc2\x29\x7c\x73\xb3\xad\xf0\x9d\xb5\x68\x08\xe0\x77\x78\xd8\xc5\xd1\xcf\x70\x0a\xd8\x99\xf9\x7c\x76\x3d\x9b\xdd\xec\xf9\xa2\x32\x9a\xa3\xb5\x07\x2c\xde\xac\x90\x21\x45\x01\x2d\xee\xd4\xe3\x3e\xa9\x1c\x0b\xa1\x30\x27\x11\x9d\x3f\x27\x49\x1c\xed\xe2\x68\xa9\x8d\xd6\x8e\x24\x36\x4c\x41\x1e\xaa\xbb\xd6\x48\x41\x8f\x46\x72\x03\xff\xcd\xf3\x82\x03\x62\x3c\x6f\x82\xcf\x6f\x32\x99\xf8\x94\xf9\x1e\x0b\x56\x4b\x77\x1e\x64\x08\x0b\x4a\x6f\x60\xa9\x15\x8e\x80\x33\xf5\xad\x83\xda\x22\x08\x07\xcc\x42\xc1\xa4\x5c\x30\xbe\x06\xa6\xb6\xa5\x36\x38\xf6\x42\x6e\x66\xdf\xcf\xde\xc2\x1c\x11\x44\x01\x0c\x16\xe8\x1c\x1a\xb0\x5a\xd6\x64\x47\x2f\x11\x31\xc7\x7c\xdc\x87\xed\xa4\xb6\x66\x22\x35\x67\x72\xb2\xd4\x7d\x0c\xbf\x37\xc8\xd6\x95\x16\xaa\x8b\xe4\xf1\xf7\xb8\xa8\x97\x4b\x34\x69\xd6\xa1\xa6\x4c\x4a\x34\xa9\x5d\x8b\x0a\x84\x72\x19\xa4\x15\x87\x5a\x28\x57\x39\x33\x82\x42\x48\x6c\x9c\x33\x02\x29\x14\x12\x66\x04\x7a\x0d\x0b\xad\xa5\x17\x2b\x54\xa1\x0f\x78\xab\x0d\xc2\x4b\xdc\xa4\x8d\x95\xad\x63\x7c\x9d\x64\x63\xda\x32\x4d\x6c\x25\x85\x4b\x46\x90\xfc\x4d\x25\xd9\xf8\x83\xca\xf1\x3e\x68\xf1\x02\x5e\x05\x47\x78\xc9\xbf\xe2\xdf\xe3\x11\x24\xc9\x88\x7e\x0a\x26\x2d\x7a\x37\x54\xcc\x38\x1f\x3c\xc4\xdc\xee\x54\x2f\xc2\x11\x92\xd1\x90\x2c\x68\xcb\x59\x41\x2a\xa4\x5e\x03\x97\x66\x2f\x4e\x9e\x83\x64\x2d\xe4\x89\xfe\x6f\x29\x6e\x7a\x95\xbc\x06\xcd\x79\x8e\xb3\x2e\x48\xf6\x17\x4e\x1a\x61\x23\x70\xa6\xc6\x47\xce\xb0\x9d\x37\x46\x50\x71\xf8\xfc\xa5\x71\x47\x46\xa4\x41\xbd\x3a\x26\xbe\xc9\xa4\xe5\x3a\x33\xac\x44\x1b\x62\xce\x81\x28\x2b\x89\x25\x2a\x87\xb9\xaf\xc4\xa1\x80\x9f\xde\xda\x71\xdc\x45\xd9\x87\x16\x43\xb1\x56\x69\x6b\xc5\x42\xe2\x78\x4f\x95\x20\x34\xe5\xe1\x6d\xa8\xcb\x51\xb3\xdf\x03\x34\xea\x7c\x13\x08\x0f\x3b\xd8\xc5\xa1\x96\x37\x88\x50\xcc\x1f\xba\xf2\xcd\x45\xcb\x9c\xc1\x25\xde\x53\x78\xa6\x05\xbd\x07\x86\x11\x50\x36\xb4\x01\xd6\x4a\xdf\x93\x39\xb8\x1f\xae\xa6\x10\x9e\x46\xb1\x38\x3a\xa3\x4d\xe8\x39\xa2\x7f\xe1\xdd\xe7\x4e\x73\x8d\x44\x67\x14\xd4\xf4\xb4\x84\x8f\x14\xd8\xf4\x08\xe5\xe2\xe8\x07\xe5\xcc\x76\x28\xb1\xab\x56\x53\x9f\x48\xdd\xab\xc6\xfb\xfe\x96\xd8\xbf\x1c\x78\x6d\xa8\x04\xd4\x4e\x28\x4c\xb2\x50\x72\x09\x9d\x04\x87\xef\xd5\xe3\x10\x4e\xa1\x20\x27\x23\x50\x42\x66\x83\x02\x79\xf1\xee\xa7\xab\xeb\xd9\x74\x9e\xaa\x90\x9e\xfb\x21\x70\x32\xd0\xc6\xf2\x15\xe6\x41\x1d\x4e\x19\x50\xb2\x35\xa6\x7c\xc5\x54\xe7\x80\x43\xdb\x5a\x74\x37\xa2\x44\x5d\xbb\x83\x17\x00\xc9\x26\x99\xc0\xa5\xb6\x98\xf2\x0c\x76\xd9\x08\x8e\xb3\x38\xfa\xd3\x4b\xde\x6d\x7e\x59\x97\xd3\xab\x4f\xe9\xf3\xda\x5d\xd6\x65\x67\x8f\x27\xb0\xc7\xc6\x73\xda\x31\xd9\xc1\x6d\x9b\x78\x71\x1b\x02\x17\x58\xce\x1d\x73\x76\x10\x05\x93\x09\x9c\xa3\x42\xc3\x24\x58\xc7\x9c\xb0\x4e\x70\x3b\x8e\xa3\x77\x52\x6a\xde\xc7\xc7\x9b\xef\x60\x32\x81\xc5\xd6\xa1\x05\x46\x4b\x8c\xd2\x83\xa9\x1c\xac\x13\x52\x82\x50\x54\x9f\xe3\xe8\x86\x34\x08\xbc\xcf\xb3\xa5\x78\x87\x8a\x32\xa7\x30\x88\x79\x16\x47\xf3\xad\x05\x38\xbc\x99\x5e\x38\xe6\xcb\x57\x61\x74\x49\x17\x85\xc3\x12\x52\x5b\x97\xa0\x0b\xf8\xe9\xfe\x9e\x58\x17\x28\xf5\x26\x8b\xa3\x8f\x5a\xaf\xeb\xca\xee\x8b\x51\x75\xb9\x40\x43\x68\x5f\xd1\xd1\x80\x0c\xb0\x38\xba\xf0\x2a\x3d\x8b\x2f\xc3\x72\x1c\x9d\x19\x44\xfb\x58\xbd\x1e\x47\xa7\xb0\xb1\x37\xe5\x05\x13\xaa\x3d\x28\x25\xce\x0a\x59\xb5\x6f\xd7\x1f\x91\x55\x9d\x6d\xff\x1b\xcb\x12\x63\x67\xa7\xff\xc4\x4a\x81\xe5\x43\xde\xa4\xec\x63\x16\xa1\x40\xd0\x9a\xad\x98\xb2\x0d\x56\xd1\x1d\x7b\x18\xab\xb4\x7a\xd9\xe1\x03\xfc\x1a\x25\x32\x8b\xf9\x13\xb8\x69\x17\x9c\x06\xb7\x42\x98\xcd\x03\x43\xc8\x0c\x3b\x94\xef\x23\x76\x60\xcb\xde\x02\x3a\x80\x83\x5d\x3f\xea\xcd\x4b\x89\x77\x28\xa1\x10\xf7\x98\xbf\xb4\xe2\x97\xb6\x94\xd5\x06\x5b\x2e\x6d\xf6\x6d\x3d\x99\x44\xe1\x48\xc2\x36\x9a\xd5\xa4\x95\xd2\x9b\xb0\x48\xe6\xec\x96\x0e\x99\x70\x1c\x47\x73\xba\x7a\x1b\xc3\x3c\x3e\xa7\x97\xb6\xd8\x82\xbf\x9e\x7b\x25\x1a\xa6\xc6\x59\x81\x29\x8e\x2e\xe6\x15\x53\x4f\x04\x95\x64\xce\xfe\x24\xb6\xc1\x3d\xe6\x9d\x32\xbe\xc2\xc0\x3c\xe0\xe5\x44\xdd\x67\xf6\xc0\xc0\xdd\x32\xbf\xaf\xf9\xfa\x47\x66\x57\x44\xed\x99\x2b\xa3\x0b\x21\xa9\x75\x5c\xd4\x7c\x8d\x0e\x56\xcc\xae\xc0\xb1\x85\xc4\x38\x3a\x9f\xf6\x19\xd9\xb3\x9c\x4f\xa1\x44\xc7\x72\xe6\x58\x1c\xcd\xdc\x0a\xcd\x9e\x9a\x04\xd1\x44\x6d\xb3\xb4\xcf\x83\xc6\x8b\xe7\xcc\x2c\x68\xfe\xe2\x5a\x4a\xe4\x4f\xdc\x45\x37\xda\xf9\xf4\x69\x21\x50\x78\xef\x5a\x1e\x4a\xaa\x0d\xa5\xc5\x8a\x55\x15\x2a\xd8\xac\x50\x41\x9f\x53\xff\xfa\xc7\x3f\xc1\xad\x84\x05\x56\xea\x9a\xae\xa4\x8f\xcc\x1e\x94\x89\x2a\x07\x6a\xe0\x29\xe6\x24\xb3\x7b\xf2\x53\xc5\x94\xb6\xc8\xb5\xca\x2d\x58\xa1\x38\xc2\xc9\x1f\xff\x40\x95\xfb\x8a\xd5\x16\x7d\x89\xbb\xb4\xbd\x81\x3d\xf5\xb2\xb5\xd7\xe7\x57\xaf\xdf\x7c\xe9\x37\xe2\xc2\xf0\x5a\x32\x03\x8b\xba\x28\x42\x8c\x1b\xe4\xd4\x39\x9c\x4f\xa1\x22\x4e\xc8\x6b\x13\xac\x44\xf7\xb7\x75\xed\x3a\x73\xf0\x39\xa5\xf2\x3f\x7d\xf1\xea\xf5\xeb\xec\x77\x24\xb7\xd9\xec\x07\x95\xff\xaf\x9b\xb5\x07\xb7\x71\xe4\x65\xc3\xd0\x36\xbf\x7f\x45\xbe\x9f\x5e\x7d\x3a\x33\x2c\xd8\xa2\x90\x9a\x35\xc2\x8b\x96\xa6\x0b\x98\x5e\x7d\x0a\xe6\x6b\x53\xe0\x7c\x4a\xd7\x3f\x45\x4f\x2b\x92\xba\x90\x38\xf2\x7d\x73\xb7\x8b\xa7\xf9\x50\xb8\x42\x13\x92\x78\x50\x2c\x1f\xe5\x2e\xbc\x39\xa1\xec\xbc\xac\xcb\xb9\xf8\x05\xa7\x92\x59\x1b\x4a\x11\x95\x94\xa9\x9f\xa4\xc6\x71\xf4\x7e\x4b\xab\xf0\xf9\xcd\xc9\x97\xfe\x52\x8b\x3c\x6d\x70\xa8\xae\xd4\xb7\x3e\xeb\x6a\x7a\x4b\xd8\x75\x37\xee\x35\xb2\xbc\xbd\x28\xd3\x12\x8e\xda\xff\xc3\x0e\x66\x8e\xee\x4c\x28\x26\xc5\x2f\x68\xd2\xfb\x11\x50\xcb\xed\xd0\xd0\x94\xfe\xb0\x6b\x80\xa1\xe9\x22\x74\xaf\x98\xae\xd8\xdf\x6b\xec\xda\x0a\x32\x6b\xad\xf0\xbe\xd2\xc6\x77\x9b\x02\xa5\x2f\x9a\xb9\xb0\xa4\xef\x06\xb8\x56\x77\x68\xac\x4f\xa1\xae\x0b\xfc\x39\xf4\x67\x19\xf8\x7e\x2b\xcd\xda\x76\x0b\x7e\xf5\xe9\xfa\xc1\x63\xd8\x3d\x16\x44\x7d\x1d\xb5\x72\x83\x09\x86\x3a\xcb\x43\x23\xcc\xa0\xb1\xf4\x23\xc4\x53\x61\x97\xac\xc4\x7e\x30\xfd\xca\x33\x10\x06\xed\x01\x49\xcc\x99\x36\x57\xd3\x3d\x75\xbc\xf4\x41\xef\xa3\x84\x24\x93\xd0\xf8\x7c\x81\xe5\x95\x2f\x67\x78\xcd\x9c\xd7\x12\x4e\xe1\xf5\xc9\x2b\x38\x82\x93\xe3\x57\xdf\xf5\x3e\x7b\x2f\x35\x5f\x0f\xa0\xa9\x69\xf0\x8f\x7c\x7b\x51\x3b\xbc\x6f\x70\x6d\x2a\x0c\xb0\x4d\x13\xd6\x4f\x03\xea\x0e\xad\x13\x4b\x02\x50\xf5\x19\xc3\x87\x02\x84\xfb\xd6\x76\xa3\x01\x39\xb5\x9b\x2b\x46\xe4\x56\x2b\x72\x34\x90\x6b\xb2\x91\xd5\xa3\x50\x39\x37\xc2\x22\x18\x2c\xf5\x5d\x10\x04\x5c\x97\xc4\x31\xde\x9f\x5c\x82\x9a\x74\xc7\xa4\x8b\xba\x80\xcf\x5f\xe8\x3a\x1a\x51\x2a\x35\xbd\x7f\xa3\xe0\xa1\x6f\x01\xcf\x4f\x97\x7e\x72\xfc\xd5\xcf\x02\xc7\x7e\x50\x6c\x5e\xb8\xae\xb6\xb4\xfd\x08\xec\xde\xb4\x98\xf4\x84\xc1\x10\xd8\x8c\xaa\x7e\x50\xec\x47\xbb\xbe\x5d\xff\xa8\xf9\x7a\x36\xbf\x59\x19\x64\xbe\x13\x6f\xe9\x9f\x94\x7c\x66\xe5\x2f\x21\x2f\x0e\x7d\x8e\xb2\x5b\x3b\xbe\x59\x61\x83\x18\x5a\xcc\xb8\x1b\xc3\x38\x85\xa7\xff\xe0\xd2\x87\x9f\x12\xb2\x8d\xe4\xb9\xd3\x55\x8b\x6a\xa3\x74\xd7\x97\x86\x76\x29\x58\xdd\x8f\x91\x7f\xc5\xf0\xdd\x8e\x01\x5f\x6a\x40\x75\x27\x8c\x56\x7e\x3a\x74\x1a\x38\x73\x7c\x15\xb6\xb3\x63\xb8\x59\xa1\x41\x9a\x2a\x37\x08\x2b\x76\xb7\x1f\x18\xcd\xd5\xa5\x72\x60\x72\xc3\xb6\xb6\xcb\xd8\x7e\x56\x58\x6a\x6f\x5a\xef\xe2\x37\xdf\x3d\x1e\x69\x3d\xcc\x7f\x2b\x9c\x15\x29\x56\x70\xb4\x57\x95\x8e\xc2\x57\xc4\x07\x9a\xf5\x95\xe0\x69\xd2\x20\xdf\xfa\xb1\xd7\xd6\x55\x28\x43\x49\xef\x95\x3f\x23\x56\xef\xa4\xb8\xc3\x74\xbf\xbc\xb5\xeb\x7e\xf2\x4a\x6d\xe3\x81\xac\x17\xed\x8f\xdb\x78\xd9\x06\x37\x53\xb6\xac\xd0\x22\x30\xd3\x5f\x1b\x1e\xbd\x31\xac\x1a\xc3\xe5\xff\x61\xf4\x5e\xa2\x0b\xf3\x76\xc5\x0f\x94\xc5\xa7\x15\xb0\x10\x2a\xf7\x73\xda\xb0\xd0\x10\xe1\x83\x2a\x74\x8f\x6f\x29\x7e\x40\x0f\x8c\xb5\xe2\x8a\xea\x5c\xd1\x2d\x0e\x2a\xde\xa3\xa2\xe6\x2f\x82\x4e\x6a\x37\xd3\xff\x3b\x00\x00\xff\xff\xa9\x51\x33\x3f\x9c\x16\x00\x00"), + compressedContent: []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x58\xdd\x72\xdb\xba\xf1\xbf\x26\x9f\x62\xff\x9c\x7f\xcf\x21\x1d\x45\xb2\xd3\x93\x74\x9a\xd6\x17\x89\x4e\xec\xe4\x34\xb6\x3c\x96\xd3\x9e\x99\x34\x93\x81\xc0\xa5\x04\x0b\x04\x58\x00\x94\xac\x78\xf4\x00\x7d\x90\xbe\x58\x9f\xa4\xb3\x00\x3f\x24\x5b\x49\xda\x4e\x79\x23\x71\xf1\xdb\xc5\x62\x3f\xb1\x1c\x8d\xe0\xc9\xac\x16\x32\x87\x5b\x1b\xc7\x15\xe3\x4b\x36\x47\x30\xb5\x72\xa2\xc4\x38\x16\x65\xa5\x8d\x83\x34\x8e\x92\x86\x36\x12\xca\xa1\x51\x4c\x8e\xec\xc6\x26\x71\x1c\x25\x73\xe1\x16\xf5\x6c\xc8\x75\x39\x9a\xeb\x6a\x81\xe6\xd6\xf6\x7f\x6e\x6d\x12\x67\x71\xcc\xb5\xb2\x0e\xce\x27\x93\x29\x9c\x82\xdd\xd8\x21\xfd\xed\xa8\xaf\xae\xc7\x6f\xe1\x14\x12\x02\x07\xda\x58\x97\x95\x90\x68\x88\xda\xca\x4a\xe2\x78\x34\x82\x82\x2d\x11\x0a\x6d\x00\x8d\xd1\x66\x38\xd7\xb1\xdb\x54\x08\x58\x30\x8e\x60\x9d\xa9\xb9\x83\xfb\x38\xfa\xec\xa9\x47\xfe\x27\xde\x06\x4c\xa0\xf5\x18\xeb\x0c\xbd\x09\x35\x8f\xb7\x71\x5c\xd4\x8a\x43\xea\x1a\x9e\xac\x59\x49\xdb\x3f\xc4\x60\xd0\xd5\x46\x81\x1b\x5a\x67\xe2\xed\x23\x8e\x6a\x39\xaf\x98\x5b\x1c\x62\x49\x92\x6e\x0b\xa1\x84\x4b\x33\x5a\xbb\xb5\x57\xcb\x39\xbc\x3c\x85\x5b\x3b\x3c\x97\x7a\xc6\xe4\xf0\x1c\x5d\x9a\xfc\x7f\xe3\x06\x9b\x64\x81\xf0\x3d\x0b\x67\x24\xab\x15\x31\xf5\x22\x6e\xed\x64\x76\x8b\xdc\x5d\x39\x93\x0c\xc0\xef\x14\x64\x05\x72\x2b\xb9\x72\x26\xc9\x0e\xb2\xbf\x21\xf3\x3e\xe2\xf6\xd4\xef\x31\xbb\x85\xd1\xeb\xeb\x10\x2e\x81\x81\x64\x0c\xdf\x35\x81\x13\x34\x48\x3d\x8a\xd8\x47\x23\x60\x2b\x2d\x72\xc8\x91\xe5\xc0\x75\x8e\x80\x52\x94\x42\x31\x27\xb4\x8a\xa3\x15\x33\x80\xc1\xdd\x71\x84\x70\x0a\x3f\xdc\x6c\x2a\x7c\x65\x2d\x1a\x02\xf8\x1d\xee\xb7\x71\xf4\x19\x4e\x01\x3b\x33\x9f\x4f\xae\x27\x93\x9b\x3d\x5f\x54\x46\x73\xb4\xf6\x80\xc5\x9b\x15\x32\xa4\x28\xa0\xc5\x9d\x7a\xdc\x07\x95\x63\x21\x14\xe6\x24\xa2\xf3\xe7\x28\x89\xa3\xad\x47\xaf\x48\x5e\xc3\x12\xa4\xa1\x5a\xb5\x26\x3a\x9f\x5c\xbd\x7d\x73\xfd\xcb\xf4\x73\x50\x27\xc9\xfe\x00\x2b\xf8\xbf\x03\x72\x47\x23\x38\xf7\x1e\xfd\x65\xfa\xd4\x56\xc8\x45\x21\xda\x33\xc0\x8a\xc9\x1a\xc1\xb1\x25\x5a\xa8\x0c\x72\xcc\x51\x71\x1c\xf6\xda\xac\x86\xd3\x26\x58\xe3\x68\x0b\x28\x2d\xc2\xf7\x15\xfb\xb6\x3e\x87\x24\x7b\x57\x51\xf2\xfe\x8c\x05\xab\xa5\x3b\xd7\x46\x6b\x07\xc2\x82\xd2\x6b\x98\x6b\x85\x03\xe0\x4c\xfd\xe8\xa0\x26\x0d\x1c\x30\x0b\x05\x93\x72\xc6\xf8\x12\x98\xda\x94\xda\x90\xd6\xa3\x11\xdc\x4c\x7e\x9e\xbc\x84\x29\x7a\x3d\x19\xcc\xd0\x39\x34\x60\xb5\xac\xc9\xa3\x5e\x22\x62\x8e\xf9\xb0\x4f\xa0\x51\x6d\xcd\x48\x6a\xce\xe4\x68\xae\xfb\x6c\x7a\x6d\x90\x2d\x2b\x2d\x54\x97\x53\xc3\x9f\x71\x56\xcf\xe7\x68\xd2\xac\x43\x8d\x99\x94\x68\x52\xbb\x14\x15\x08\xe5\x32\x48\x2b\x0e\xb5\x50\xae\x72\x66\x00\x85\x90\xd8\x84\xc9\x00\xa4\x50\x48\x98\x01\xe8\x25\xcc\xb4\x96\x5e\xac\x50\x85\x3e\x10\x37\x6d\x3a\x5c\xe2\x3a\x6d\x0c\x6b\x1d\xe3\xcb\x24\x1b\xd2\x96\x69\x62\x2b\x29\x5c\x32\x80\xe4\xaf\x2a\xc9\x86\xef\x54\x8e\x77\x41\x8b\x27\xf0\x2c\x04\x9b\x97\xfc\x8d\x48\x3b\x1e\x40\x92\x0c\xe8\xa7\x60\xd2\xa2\x77\x43\xc5\x8c\xf3\x61\x4c\xcc\xed\x4e\xf5\x2c\x1c\x21\x19\xec\x92\x05\x6d\x39\x29\x48\x85\xd4\x6b\xe0\xd2\xec\xc9\xc9\xd7\x20\x59\x0b\x79\xa4\xff\x4b\xca\x8d\x5e\x25\xaf\x41\x73\x9e\xe3\xac\x0b\x92\xfd\x85\x93\x46\xd8\x00\x9c\xa9\xf1\x81\x33\x6c\xe7\x8d\x01\x54\x1c\x3e\x7e\x6a\xdc\x91\x11\x69\xa7\x72\x1e\x13\xdf\x68\xd4\x72\x9d\x19\x56\xa2\x0d\x31\xe7\x40\x94\x95\xc4\x12\x95\xc3\xdc\xf7\x84\xd0\x4a\x4e\x6f\xed\x30\xee\xa2\xec\x5d\x8b\xa1\x58\xab\xb4\xb5\x62\x26\x71\xb8\xa7\x4a\x10\x9a\xf2\xf0\xb6\xab\xcb\x51\xb3\xdf\x3d\x34\xea\xfc\x10\x08\xf7\x5b\xd8\xc6\xa1\xab\x34\x88\xd0\x56\xee\xbb\x46\xc2\x45\xcb\x9c\xc1\x25\xde\x51\x78\xa6\x05\xbd\x07\x86\x01\x50\x36\xb4\x01\xd6\x4a\xdf\x93\xb9\xd3\xa9\xae\xc6\x10\x9e\x46\xb1\x38\x3a\xa3\x4d\xe8\x39\xa2\x7f\xe1\xdd\xe7\x4e\xd3\xd0\xa2\x33\x0a\x6a\x7a\x5a\xc2\x7b\x0a\x6c\x7a\x84\x72\x71\xf4\x46\x39\xb3\xd9\x95\xd8\xd5\xcd\xb1\x4f\xa4\xee\x55\xe3\x5d\xdf\xaf\xf6\xdb\x14\xaf\x0d\x95\x80\xda\x09\x85\x49\x16\x8a\x3f\xa1\x93\xe0\xf0\xbd\xce\x10\xc2\x29\xb4\x86\x64\x00\x4a\xc8\x6c\xa7\x54\x5f\xbc\xfa\xf5\xea\x7a\x32\x9e\xa6\x2a\xa4\xe7\x7e\x08\x9c\xec\x68\x63\xf9\x02\xf3\xa0\x0e\xa7\x0c\x28\xd9\x12\x53\xbe\x60\xaa\x73\xc0\xa1\x6d\x2d\xba\x1b\x51\xa2\xae\xdd\xc1\x56\x44\xb2\x49\x26\x70\xa9\x2d\xa6\x3c\x83\x6d\x36\x80\xe3\x2c\x8e\xfe\xf8\x94\x77\x9b\x5f\xd6\xe5\xf8\xea\x43\xfa\x75\xed\x2e\xeb\xb2\xb3\xc7\x23\xd8\x43\xe3\x39\xed\x98\xec\xe0\xb6\x4d\xbc\xb8\x0d\x81\x0b\x2c\xa7\x8e\x39\xbb\x13\x05\xd4\x23\x50\xa1\x61\x12\xac\x63\x4e\x58\x27\xb8\x1d\xc6\xd1\x2b\x29\x35\xef\xe3\xe3\xc5\x4f\x30\x1a\xc1\x6c\xe3\xd0\x02\xa3\x25\x46\xe9\xc1\x54\x0e\xd6\x09\x29\x41\x28\xaa\xcf\x71\x74\x43\x1a\x04\xde\xaf\xb3\xa5\xb8\x42\x45\x99\x53\x18\xc4\x3c\x8b\xa3\xe9\xc6\x02\x1c\xde\x4c\xcf\x1c\xf3\xe5\xab\x30\xba\xa4\x46\xe1\xb0\x84\xd4\xd6\x25\xe8\x02\x7e\xbd\xbb\x23\xd6\x19\x4a\xbd\xce\xe2\xe8\xbd\xd6\xcb\xba\xb2\xfb\x62\x54\x5d\xce\xd0\x10\xda\x57\x74\x34\x20\x03\x2c\x8e\x2e\xbc\x4a\x5f\xc5\x97\x61\x39\x8e\xce\x0c\xa2\x7d\xa8\x5e\x8f\xa3\x53\xd8\xd8\x9b\xf2\x82\x09\xd5\x1e\x94\x12\x67\x81\xac\xda\xb7\xeb\x5b\x64\x55\x67\xdb\xff\xc4\xb2\xc4\xd8\xd9\xe9\xdf\xb1\x52\x60\x79\x97\x37\x29\xfb\x90\x45\x28\x10\xb4\x66\x2b\xa6\x6c\x83\x55\xd4\x63\x0f\x63\x95\x56\x4f\x3b\x7c\x80\x5f\xa3\x44\x66\x31\x7f\x04\x37\xed\x82\xd3\xe0\x16\x08\x93\x69\x60\x08\x99\x61\x77\xe5\xfb\x88\xdd\xb1\x65\x6f\x01\x1d\xc0\xc1\xae\xef\xf5\xfa\xa9\xc4\x15\x4a\x28\xc4\x1d\xe6\x4f\xad\xf8\xd2\x96\xb2\xda\x60\xcb\xa5\xcd\xbe\xad\x47\xa3\x28\x1c\x49\xd8\x46\xb3\x9a\xb4\x52\x7a\x1d\x16\xc9\x9c\xdd\xd2\x21\x13\x0e\xe3\x68\x4a\xad\xb7\x31\xcc\xc3\x73\x7a\x69\xb3\x0d\xf8\xf6\xdc\x2b\xd1\x30\x35\xce\x0a\x4c\x71\x74\x31\xad\x98\x7a\x24\xa8\x24\x73\xf6\x27\xb1\x0d\xee\x21\xef\x98\xf1\x05\x06\xe6\x1d\x5e\x4e\xd4\x7d\x66\x0f\x0c\xdc\x2d\xf3\xeb\x9a\x2f\xdf\x32\xbb\x20\x6a\xcf\x5c\x19\x5d\x08\x49\x97\xd8\x59\xcd\x97\xe8\x60\xc1\xec\x02\x1c\x9b\x49\x8c\xa3\xf3\x71\x9f\x91\x3d\xcb\xf9\x18\x4a\x74\x2c\x67\x8e\xc5\xd1\xc4\x2d\xd0\xec\xa9\x49\x10\x4d\xd4\x36\x4b\xfb\x3c\x68\xbc\x78\xce\xcc\x8c\x26\x41\xae\xa5\x44\xfe\xc8\x5d\xd4\xd1\xce\xc7\x8f\x0b\x81\xc2\x3b\xd7\xf2\x50\x52\xad\x29\x2d\x16\xac\xaa\x50\xc1\x7a\x81\x0a\xfa\x9c\xfa\xe7\xdf\xff\x01\x6e\x21\x2c\xb0\x52\xd7\xd4\x92\xde\x33\x7b\x50\x26\xaa\x1c\x68\x94\xa0\x98\x93\xcc\xee\xc9\x4f\x15\x53\xda\x22\xd7\x2a\xb7\x60\x85\xe2\x08\x27\xbf\xff\x1d\x55\xee\x2b\x56\x5b\xf4\x25\xee\xd2\xf6\x06\xf6\xd4\xcb\xd6\x5e\x1f\x9f\x3d\x7f\xf1\xa9\xdf\x88\x0b\xc3\x6b\xc9\x0c\xcc\xea\xa2\x08\x31\x4e\xb7\x6d\xe5\xc8\x9c\x15\x71\x42\x5e\x9b\x60\x25\xea\xdf\xd6\xb5\xeb\xcc\xc1\xc7\x94\xca\xff\xf8\xc9\xb3\xe7\xcf\xb3\xdf\x90\xdc\x66\xb3\x37\x2a\xff\x6f\x37\x6b\x0f\x6e\xe3\xc8\xcb\x86\x5d\xdb\xfc\xf6\x19\xf9\x7e\x7c\xf5\xe1\xcc\xb0\x60\x8b\x42\x6a\xd6\x08\x2f\x5a\x9a\x2e\x60\x7c\xf5\x21\x98\xaf\x4d\x81\xf3\x31\xb5\x7f\x8a\x9e\x56\x24\xdd\x42\xe2\xc8\xdf\x9b\xbb\x5d\x3c\xcd\x87\xc2\x15\x9a\x90\xc4\x3b\xc5\xf2\x41\xee\xc2\x8b\x13\xca\xce\xcb\xba\x9c\x8a\x2f\x38\x96\xcc\xda\x50\x8a\xa8\xa4\x8c\xfd\x4c\x37\x8c\xa3\xd7\x1b\x5a\x85\x8f\x2f\x4e\x3e\xf5\x4d\x2d\xf2\xb4\x9d\x43\x75\xa5\xbe\xf5\x59\x57\xd3\x5b\xc2\xb6\xeb\xb8\xd7\xc8\xf2\xb6\x51\xa6\x25\x1c\xb5\xff\x77\x6f\x30\x53\x74\x67\x42\x31\x29\xbe\xa0\x49\xef\x06\x40\x57\x6e\x87\xa6\x60\x1c\xef\xb7\x0d\x30\x5c\xba\x08\xdd\x2b\xa6\x2b\xf6\xb7\x1a\xbb\x6b\x05\x99\xb5\x56\x78\x57\x69\xe3\x6f\x9b\x02\xa5\x2f\x9a\xb9\xb0\xa4\xef\x1a\xb8\x56\x2b\x34\xd6\xa7\x50\x77\x0b\xfc\x1c\xee\x67\x19\xf8\xfb\x56\x9a\xb5\xd7\x2d\xf8\xe6\xd3\xdd\x07\x8f\x61\xfb\x50\x10\xdd\xeb\xe8\x2a\xb7\x33\xc1\xd0\xcd\xf2\xd0\x08\xb3\x73\xb1\xf4\x23\xc4\x63\x61\x97\xac\xc4\x7e\x44\xfe\xce\xb3\x23\x0c\xda\x03\x92\x98\x33\x6d\xae\xc6\x7b\xea\x78\xe9\x3b\x77\x1f\x25\x24\x99\x84\x06\xf9\x0b\x2c\xaf\x7c\x39\xc3\x6b\xe6\xbc\x96\x70\x0a\xcf\x4f\x9e\xc1\x11\x9c\x1c\x3f\xfb\xa9\xf7\xd9\x6b\xa9\xf9\x72\x07\x9a\x9a\x06\xff\xc0\xb7\x17\xb5\xc3\xbb\x06\xd7\xa6\xc2\x0e\xb6\xb9\x84\xf5\xd3\x80\x5a\xa1\x75\x62\x4e\x00\xaa\x3e\x43\x78\x57\x80\x70\x3f\xda\x6e\x34\x20\xa7\x76\x73\xc5\x80\xdc\x6a\x45\x8e\x06\x72\x4d\x36\xb2\x7a\x10\x2a\xe7\x5a\x58\x04\x83\xa5\x5e\x05\x41\xc0\x75\x49\x1c\xc3\xfd\xc9\x25\xa8\x49\x3d\x26\x9d\xd5\x05\x7c\xfc\x44\xed\x68\x40\xa9\xd4\xdc\xfd\x1b\x05\x0f\x7d\x95\xf8\xfa\x74\xe9\x27\xc7\x6f\x7e\xa0\x38\xf6\x83\x62\xf3\xc2\x75\xb5\xa1\xed\x07\x60\xf7\xa6\xc5\xa4\x27\xec\x0c\x81\xcd\xa8\xea\x07\xc5\x7e\xb4\xeb\xaf\xeb\xef\x35\x5f\x4e\xa6\x37\x0b\x83\xcc\xdf\xc4\x5b\xfa\x07\x25\xbf\xb2\xf2\xe7\x90\x17\x87\x3e\x8c\xd9\x8d\x1d\xde\x2c\xb0\x41\xec\x5a\xcc\xb8\x1b\xc3\x38\x85\xa7\xff\xf4\xd3\x87\x9f\x12\xb2\x8d\xe4\xa9\xd3\x55\x8b\x6a\xa3\x74\xdb\x97\x86\x76\x29\x58\xdd\x8f\x91\x7f\xc1\xf0\x05\x91\x01\x9f\x6b\x40\xb5\x12\x46\x2b\x3f\x1d\x3a\x0d\x9c\x39\xbe\x08\xdb\xd9\x21\xdc\x2c\xd0\x20\x4d\x95\x6b\x84\x05\x5b\xed\x07\x46\xd3\xba\x54\x0e\x4c\xae\xd9\xc6\x76\x19\xdb\xcf\x0a\x73\xed\x4d\xeb\x5d\xfc\xe2\xa7\x87\x23\xad\x87\xf9\xaf\x96\x93\x22\xc5\x0a\x8e\xf6\xaa\xd2\x51\xf8\x9e\x79\x4f\xb3\xbe\x12\x3c\x4d\x1a\xe4\x4b\x3f\xf6\xda\xba\x0a\x65\x28\xe9\xbd\xf2\x27\xc4\xea\x95\x14\x2b\x4c\xf7\xcb\x5b\xbb\xee\x27\xaf\xd4\x36\x1e\xc8\x7a\xd1\xfe\xb8\x8d\x97\x6d\x70\x33\x65\xcb\x02\x2d\x02\x33\x7d\xdb\xf0\xe8\xb5\x61\xd5\x10\x2e\xff\x07\xa3\xf7\x1c\x5d\x98\xb7\x2b\x7e\xa0\x2c\x3e\xae\x80\x85\x50\xb9\x9f\xd3\x76\x0b\x0d\x11\xde\xa9\x42\xf7\xf8\x96\xe2\x07\xf4\xc0\x58\x2b\xae\xa8\xce\x15\xdd\xe2\x4e\xc5\x7b\x50\xd4\x7c\x23\xe8\xa4\x76\x33\xfd\xbf\x02\x00\x00\xff\xff\x81\xb9\x90\xc5\x26\x17\x00\x00"), }, "/src/strings": &vfsgen۰DirInfo{ name: "strings", diff --git a/compiler/natives/src/runtime/runtime.go b/compiler/natives/src/runtime/runtime.go index 4e4fb62c6..3239b182f 100644 --- a/compiler/natives/src/runtime/runtime.go +++ b/compiler/natives/src/runtime/runtime.go @@ -43,9 +43,11 @@ func GOROOT() string { if process == js.Undefined { return "/" } - goroot := process.Get("env").Get("GOROOT") - if goroot != js.Undefined { - return goroot.String() + if v := process.Get("env").Get("GOPHERJS_GOROOT"); v != js.Undefined { + // GopherJS-specific GOROOT value takes precedence. + return v.String() + } else if v := process.Get("env").Get("GOROOT"); v != js.Undefined { + return v.String() } // sys.DefaultGoroot is now gone, can't use it as fallback anymore. // TODO: See if a better solution is needed. diff --git a/compiler/version_check.go b/compiler/version_check.go index 48bb27ae0..87b2892be 100644 --- a/compiler/version_check.go +++ b/compiler/version_check.go @@ -1,9 +1,25 @@ -// +build go1.12 -// +build !go1.13 - package compiler -const ___GOPHERJS_REQUIRES_GO_VERSION_1_12___ = true +import ( + "bytes" + "fmt" + "io/ioutil" + "path/filepath" +) // Version is the GopherJS compiler version string. const Version = "1.12-2" + +// CheckGoVersion checks the version of the Go distribution +// at goroot, and reports an error if it's not compatible +// with this version of the GopherJS compiler. +func CheckGoVersion(goroot string) error { + v, err := ioutil.ReadFile(filepath.Join(goroot, "VERSION")) + if err != nil { + return fmt.Errorf("GopherJS %s requires a Go 1.12.x distribution, but failed to read its VERSION file: %v", Version, err) + } + if !bytes.Equal(v, []byte("go1.12")) && !bytes.HasPrefix(v, []byte("go1.12.")) { + return fmt.Errorf("GopherJS %s requires a Go 1.12.x distribution, but found version %s", Version, v) + } + return nil +} diff --git a/tests/run.go b/tests/run.go index 9afef7fae..6968359b3 100644 --- a/tests/run.go +++ b/tests/run.go @@ -36,6 +36,8 @@ import ( "strings" "time" "unicode" + + gbuild "github.com/gopherjs/gopherjs/build" ) // ----------------------------------------------------------------------------- @@ -186,7 +188,7 @@ func main() { flag.Parse() // GOPHERJS. - err := os.Chdir(filepath.Join(runtime.GOROOT(), "test")) + err := os.Chdir(filepath.Join(gbuild.DefaultGOROOT, "test")) if err != nil { log.Fatalln(err) } @@ -311,14 +313,6 @@ func main() { } } -func toolPath(name string) string { - p := filepath.Join(os.Getenv("GOROOT"), "bin", "tool", name) - if _, err := os.Stat(p); err != nil { - log.Fatalf("didn't find binary at %s", p) - } - return p -} - func shardMatch(name string) bool { if *shards == 0 { return true diff --git a/tool.go b/tool.go index 4c580a139..ec5823d33 100644 --- a/tool.go +++ b/tool.go @@ -94,9 +94,13 @@ func main() { cmdBuild.Run = func(cmd *cobra.Command, args []string) { options.BuildTags = strings.Fields(tags) for { - s := gbuild.NewSession(options) + s, err := gbuild.NewSession(options) + if err != nil { + options.PrintError("%s\n", err) + os.Exit(1) + } - err := func() error { + err = func() error { // Handle "gopherjs build [files]" ad-hoc package mode. if len(args) > 0 && (strings.HasSuffix(args[0], ".go") || strings.HasSuffix(args[0], ".inc.js")) { for _, arg := range args { @@ -173,9 +177,13 @@ func main() { cmdInstall.Run = func(cmd *cobra.Command, args []string) { options.BuildTags = strings.Fields(tags) for { - s := gbuild.NewSession(options) + s, err := gbuild.NewSession(options) + if err != nil { + options.PrintError("%s\n", err) + os.Exit(1) + } - err := func() error { + err = func() error { // Expand import path patterns. patternContext := gbuild.NewBuildContext("", options.BuildTags) pkgs := (&gotool.Context{BuildContext: *patternContext}).ImportPaths(args) @@ -274,7 +282,10 @@ func main() { os.Remove(tempfile.Name()) os.Remove(tempfile.Name() + ".map") }() - s := gbuild.NewSession(options) + s, err := gbuild.NewSession(options) + if err != nil { + return err + } if err := s.BuildFiles(args[:lastSourceArg], tempfile.Name(), currentDirectory); err != nil { return err } @@ -330,7 +341,10 @@ func main() { fmt.Printf("? \t%s\t[no test files]\n", pkg.ImportPath) continue } - s := gbuild.NewSession(options) + s, err := gbuild.NewSession(options) + if err != nil { + return err + } tests := &testFuncs{BuildContext: s.BuildContext(), Package: pkg.Package} collectTests := func(testPkg *gbuild.PackageData, testPkgName string, needVar *bool) error { @@ -481,7 +495,7 @@ func main() { cmdServe.Flags().StringVarP(&addr, "http", "", ":8080", "HTTP bind address to serve") cmdServe.Run = func(cmd *cobra.Command, args []string) { options.BuildTags = strings.Fields(tags) - dirs := append(filepath.SplitList(build.Default.GOPATH), build.Default.GOROOT) + dirs := append(filepath.SplitList(build.Default.GOPATH), gbuild.DefaultGOROOT) var root string if len(args) > 1 { @@ -493,6 +507,13 @@ func main() { root = args[0] } + // Create a new session eagerly to check if it fails, and report the error right away. + // Otherwise users will see it only after trying to serve a package, which is a bad experience. + _, err := gbuild.NewSession(options) + if err != nil { + options.PrintError("%s\n", err) + os.Exit(1) + } sourceFiles := http.FileServer(serveCommandFileSystem{ serveRoot: root, options: options, @@ -573,8 +594,13 @@ func (fs serveCommandFileSystem) Open(requestName string) (http.File, error) { isIndex := file == "index.html" if isPkg || isMap || isIndex { + // Create a new session to pick up changes to source code on disk. + // TODO(dmitshur): might be possible to get a single session to detect changes to source code on disk + s, err := gbuild.NewSession(fs.options) + if err != nil { + return nil, err + } // If we're going to be serving our special files, make sure there's a Go command in this folder. - s := gbuild.NewSession(fs.options) pkg, err := gbuild.Import(path.Dir(name), 0, s.InstallSuffix(), fs.options.BuildTags) if err != nil || pkg.Name != "main" { isPkg = false From aeb9b12ccb46c3e234b2cb29446c56b653eb479b Mon Sep 17 00:00:00 2001 From: Dmitri Shuralyov Date: Sun, 9 Feb 2020 01:04:25 -0500 Subject: [PATCH 2/2] support go1.12 beta and release candidate versions --- compiler/version_check.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/version_check.go b/compiler/version_check.go index 87b2892be..7f5614ac0 100644 --- a/compiler/version_check.go +++ b/compiler/version_check.go @@ -18,7 +18,7 @@ func CheckGoVersion(goroot string) error { if err != nil { return fmt.Errorf("GopherJS %s requires a Go 1.12.x distribution, but failed to read its VERSION file: %v", Version, err) } - if !bytes.Equal(v, []byte("go1.12")) && !bytes.HasPrefix(v, []byte("go1.12.")) { + if !bytes.HasPrefix(v, []byte("go1.12")) { // TODO(dmitshur): Change this before Go 1.120 comes out. return fmt.Errorf("GopherJS %s requires a Go 1.12.x distribution, but found version %s", Version, v) } return nil