[gopls-release-branch.0.6] all: merge master into gopls-release-branch.0.6

b261fe96 go/tools: add vet check for direct comparion of reflect.Values
e78b40c7 internal/lsp: switch to 'go get -u ./...' for transitive upgrades
3ac76b8b gopls/internal/coverage: better error messages and output
c6024661 Revert "internal/lsp/cache: disable GOPACKAGESDRIVER"
35a91593 go/internal/gcimporter: ensure that imported floats are of float kind
5d334387 go/internal/gcimporter: merge go1.11 tests back into gcimporter_test.go
11c3f835 internal/lsp/source: fix Highlight for std and 3rd-party packages
8c34cc9c internal/lsp/cache: fix race condition in snapshot's initializedErr
0deaffd2 gopls/internal/regtest: re-enable the gc_details regtest for -short
af364066 internal/lsp/source: respond with the underlying type to Type Definition requests for composite types
682c7e60 godoc/static: link to golang.org for content moved out of Go root
ca627f83 internal/lsp/semantic: fix some type definitions
04595890 internal/lsp/protocol/typescript: small cleanups and add tsconfig.json
b0e994dc internal/jsonrpc2_v2: move the idle timeout handling out of the server
95535753 internal/lsp: remove unnecessary call to WorkspacePackages in mod tidy
769264cf internal/lsp/source: fix docs for fields of anonymous structs/interfaces
cb7d5993 internal/lsp/source: skip blank identifiers during the function extraction
94a19427 internal/lsp/completion: move postfix completions behind option
09058ab0 internal/lsp/source/completion: add postfix snippet completions
2c039f7f internal/event/label: prevent unsafe get of non-string
4c8e4a8b go/analysis/passes/inspect: fix typo in comment
63ea654b internal/lsp: hold the gc details lock when storing diagnostics
7f6d50ea internal/lsp/source: fix hover and completion with dot imports
b3556f0f internal/lsp: remove some unused parameters, mostly in the cache package
09a00c1a internal/lsp: fix support for SourceFixAll code actions
877f9c48 internal/jsonrpc2_v2: an updated jsonrpc2 library
52cb7724 gopls: upgrade mvdan.cc/gofumpt to v0.1.1
a1191f37 gopls: upgrade honnef.co/go/tools to v0.1.3
d8aeb16b internal/lsp: add defaultLibrary mod for basic types
aa0c7234 internal/lsp/cache: get control of reloadOrphanedFiles
d7a25ada gopls/integration: remove obsolete code
9bdb4197 gopls/internal: add coverage command to compute test coverage
d2e11a2b present: don't drop commands that immediately follow text
695b1675 cmd/present2md: allow comments to be retained in translated document
a14ff98a present: retain complete caption command when parsing captions
1aac171f Update emacs.md - add .dir-locals.el example
2c4a8865 internal/lsp: remove module diagnostics from code actions
9b614f5d internal/lsp/cache: tolerate analysis panics better
9e9211a9 gopls/internal/regtest: fix race when printing regtest state on falure
6d45e3d9 internal/lsp: add a temp workspace per folder, and a helper command
e409f121 internal/lsp: add snippet completion for t.Fatal errs
8e4f4c86 godoc: delete GoogleCN logic
44abc2a7 internal/lsp: only load by view when there are no go.mod files

Change-Id: Ie5d628f640a8edaeb41c4cdf30aafefbc892ec7c
diff --git a/cmd/godoc/main.go b/cmd/godoc/main.go
index 02f0eb6..8780f8b 100644
--- a/cmd/godoc/main.go
+++ b/cmd/godoc/main.go
@@ -192,8 +192,10 @@
 	}
 	if *templateDir != "" {
 		fs.Bind("/lib/godoc", vfs.OS(*templateDir), "/", vfs.BindBefore)
+		fs.Bind("/favicon.ico", vfs.OS(*templateDir), "/favicon.ico", vfs.BindReplace)
 	} else {
 		fs.Bind("/lib/godoc", mapfs.New(static.Files), "/", vfs.BindReplace)
+		fs.Bind("/favicon.ico", mapfs.New(static.Files), "/favicon.ico", vfs.BindReplace)
 	}
 
 	// Get the GOMOD value, use it to determine if godoc is being invoked in module mode.
diff --git a/cmd/present2md/main.go b/cmd/present2md/main.go
index 15ee3e6..64be64b 100644
--- a/cmd/present2md/main.go
+++ b/cmd/present2md/main.go
@@ -93,6 +93,11 @@
 		return fmt.Errorf("%v: already markdown", file)
 	}
 
+	// Convert all comments before parsing the document.
+	// The '//' comment is treated as normal text and so
+	// is passed through the translation unaltered.
+	data = bytes.Replace(data, []byte("\n#"), []byte("\n//"), -1)
+
 	doc, err := present.Parse(bytes.NewReader(data), file, 0)
 	if err != nil {
 		return err
diff --git a/go/analysis/passes/inspect/inspect.go b/go/analysis/passes/inspect/inspect.go
index 2856df1..4bb652a 100644
--- a/go/analysis/passes/inspect/inspect.go
+++ b/go/analysis/passes/inspect/inspect.go
@@ -3,8 +3,8 @@
 // license that can be found in the LICENSE file.
 
 // Package inspect defines an Analyzer that provides an AST inspector
-// (golang.org/x/tools/go/ast/inspect.Inspect) for the syntax trees of a
-// package. It is only a building block for other analyzers.
+// (golang.org/x/tools/go/ast/inspector.Inspector) for the syntax trees
+// of a package. It is only a building block for other analyzers.
 //
 // Example of use in another analysis:
 //
diff --git a/go/analysis/passes/reflectvaluecompare/reflectvaluecompare.go b/go/analysis/passes/reflectvaluecompare/reflectvaluecompare.go
new file mode 100644
index 0000000..ef21f0e
--- /dev/null
+++ b/go/analysis/passes/reflectvaluecompare/reflectvaluecompare.go
@@ -0,0 +1,99 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package reflectvaluecompare defines an Analyzer that checks for accidentally
+// using == or reflect.DeepEqual to compare reflect.Value values.
+// See issues 43993 and 18871.
+package reflectvaluecompare
+
+import (
+	"go/ast"
+	"go/token"
+	"go/types"
+
+	"golang.org/x/tools/go/analysis"
+	"golang.org/x/tools/go/analysis/passes/inspect"
+	"golang.org/x/tools/go/ast/inspector"
+	"golang.org/x/tools/go/types/typeutil"
+)
+
+const Doc = `check for comparing reflect.Value values with == or reflect.DeepEqual
+
+The reflectvaluecompare checker looks for expressions of the form:
+
+    v1 == v2
+    v1 != v2
+    reflect.DeepEqual(v1, v2)
+
+where v1 or v2 are reflect.Values. Comparing reflect.Values directly
+is almost certainly not correct, as it compares the reflect package's
+internal representation, not the underlying value.
+Likely what is intended is:
+
+    v1.Interface() == v2.Interface()
+    v1.Interface() != v2.Interface()
+    reflect.DeepEqual(v1.Interface(), v2.Interface())
+`
+
+var Analyzer = &analysis.Analyzer{
+	Name:     "reflectvaluecompare",
+	Doc:      Doc,
+	Requires: []*analysis.Analyzer{inspect.Analyzer},
+	Run:      run,
+}
+
+func run(pass *analysis.Pass) (interface{}, error) {
+	inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
+
+	nodeFilter := []ast.Node{
+		(*ast.BinaryExpr)(nil),
+		(*ast.CallExpr)(nil),
+	}
+	inspect.Preorder(nodeFilter, func(n ast.Node) {
+		switch n := n.(type) {
+		case *ast.BinaryExpr:
+			if n.Op != token.EQL && n.Op != token.NEQ {
+				return
+			}
+			if isReflectValue(pass, n.X) || isReflectValue(pass, n.Y) {
+				if n.Op == token.EQL {
+					pass.ReportRangef(n, "avoid using == with reflect.Value")
+				} else {
+					pass.ReportRangef(n, "avoid using != with reflect.Value")
+				}
+			}
+		case *ast.CallExpr:
+			fn, ok := typeutil.Callee(pass.TypesInfo, n).(*types.Func)
+			if !ok {
+				return
+			}
+			if fn.FullName() == "reflect.DeepEqual" && (isReflectValue(pass, n.Args[0]) || isReflectValue(pass, n.Args[1])) {
+				pass.ReportRangef(n, "avoid using reflect.DeepEqual with reflect.Value")
+			}
+		}
+	})
+	return nil, nil
+}
+
+// isReflectValue reports whether the type of e is reflect.Value.
+func isReflectValue(pass *analysis.Pass, e ast.Expr) bool {
+	tv, ok := pass.TypesInfo.Types[e]
+	if !ok { // no type info, something else is wrong
+		return false
+	}
+	// See if the type is reflect.Value
+	named, ok := tv.Type.(*types.Named)
+	if !ok {
+		return false
+	}
+	if obj := named.Obj(); obj == nil || obj.Pkg() == nil || obj.Pkg().Path() != "reflect" || obj.Name() != "Value" {
+		return false
+	}
+	if _, ok := e.(*ast.CompositeLit); ok {
+		// This is reflect.Value{}. Don't treat that as an error.
+		// Users should probably use x.IsValid() rather than x == reflect.Value{}, but the latter isn't wrong.
+		return false
+	}
+	return true
+}
diff --git a/go/analysis/passes/reflectvaluecompare/reflectvaluecompare_test.go b/go/analysis/passes/reflectvaluecompare/reflectvaluecompare_test.go
new file mode 100644
index 0000000..88fc8f2
--- /dev/null
+++ b/go/analysis/passes/reflectvaluecompare/reflectvaluecompare_test.go
@@ -0,0 +1,17 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package reflectvaluecompare_test
+
+import (
+	"testing"
+
+	"golang.org/x/tools/go/analysis/analysistest"
+	"golang.org/x/tools/go/analysis/passes/reflectvaluecompare"
+)
+
+func TestReflectValueCompare(t *testing.T) {
+	testdata := analysistest.TestData()
+	analysistest.Run(t, testdata, reflectvaluecompare.Analyzer, "a")
+}
diff --git a/go/analysis/passes/reflectvaluecompare/testdata/src/a/a.go b/go/analysis/passes/reflectvaluecompare/testdata/src/a/a.go
new file mode 100644
index 0000000..e069c6d
--- /dev/null
+++ b/go/analysis/passes/reflectvaluecompare/testdata/src/a/a.go
@@ -0,0 +1,51 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// This file contains tests for the reflectvaluecompare checker.
+
+package a
+
+import (
+	"reflect"
+)
+
+func f() {
+	var x, y reflect.Value
+	var a, b interface{}
+	_ = x == y // want `avoid using == with reflect.Value`
+	_ = x == a // want `avoid using == with reflect.Value`
+	_ = a == x // want `avoid using == with reflect.Value`
+	_ = a == b
+
+	// Comparing to reflect.Value{} is ok.
+	_ = a == reflect.Value{}
+	_ = reflect.Value{} == a
+	_ = reflect.Value{} == reflect.Value{}
+}
+func g() {
+	var x, y reflect.Value
+	var a, b interface{}
+	_ = x != y // want `avoid using != with reflect.Value`
+	_ = x != a // want `avoid using != with reflect.Value`
+	_ = a != x // want `avoid using != with reflect.Value`
+	_ = a != b
+
+	// Comparing to reflect.Value{} is ok.
+	_ = a != reflect.Value{}
+	_ = reflect.Value{} != a
+	_ = reflect.Value{} != reflect.Value{}
+}
+func h() {
+	var x, y reflect.Value
+	var a, b interface{}
+	reflect.DeepEqual(x, y) // want `avoid using reflect.DeepEqual with reflect.Value`
+	reflect.DeepEqual(x, a) // want `avoid using reflect.DeepEqual with reflect.Value`
+	reflect.DeepEqual(a, x) // want `avoid using reflect.DeepEqual with reflect.Value`
+	reflect.DeepEqual(a, b)
+
+	// Comparing to reflect.Value{} is ok.
+	reflect.DeepEqual(reflect.Value{}, a)
+	reflect.DeepEqual(a, reflect.Value{})
+	reflect.DeepEqual(reflect.Value{}, reflect.Value{})
+}
diff --git a/go/internal/gcimporter/gcimporter11_test.go b/go/internal/gcimporter/gcimporter11_test.go
deleted file mode 100644
index 3f2f0a0..0000000
--- a/go/internal/gcimporter/gcimporter11_test.go
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gcimporter
-
-import (
-	"go/types"
-	"runtime"
-	"strings"
-	"testing"
-
-	"golang.org/x/tools/internal/testenv"
-)
-
-var importedObjectTests = []struct {
-	name string
-	want string
-}{
-	// non-interfaces
-	{"crypto.Hash", "type Hash uint"},
-	{"go/ast.ObjKind", "type ObjKind int"},
-	{"go/types.Qualifier", "type Qualifier func(*Package) string"},
-	{"go/types.Comparable", "func Comparable(T Type) bool"},
-	{"math.Pi", "const Pi untyped float"},
-	{"math.Sin", "func Sin(x float64) float64"},
-	{"go/ast.NotNilFilter", "func NotNilFilter(_ string, v reflect.Value) bool"},
-	{"go/internal/gcimporter.FindPkg", "func FindPkg(path string, srcDir string) (filename string, id string)"},
-
-	// interfaces
-	{"context.Context", "type Context interface{Deadline() (deadline time.Time, ok bool); Done() <-chan struct{}; Err() error; Value(key interface{}) interface{}}"},
-	{"crypto.Decrypter", "type Decrypter interface{Decrypt(rand io.Reader, msg []byte, opts DecrypterOpts) (plaintext []byte, err error); Public() PublicKey}"},
-	{"encoding.BinaryMarshaler", "type BinaryMarshaler interface{MarshalBinary() (data []byte, err error)}"},
-	{"io.Reader", "type Reader interface{Read(p []byte) (n int, err error)}"},
-	{"io.ReadWriter", "type ReadWriter interface{Reader; Writer}"},
-	{"go/ast.Node", "type Node interface{End() go/token.Pos; Pos() go/token.Pos}"},
-	{"go/types.Type", "type Type interface{String() string; Underlying() Type}"},
-}
-
-func TestImportedTypes(t *testing.T) {
-	testenv.NeedsGo1Point(t, 11)
-	skipSpecialPlatforms(t)
-
-	// This package only handles gc export data.
-	if runtime.Compiler != "gc" {
-		t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
-	}
-
-	for _, test := range importedObjectTests {
-		s := strings.Split(test.name, ".")
-		if len(s) != 2 {
-			t.Fatal("inconsistent test data")
-		}
-		importPath := s[0]
-		objName := s[1]
-
-		pkg, err := Import(make(map[string]*types.Package), importPath, ".", nil)
-		if err != nil {
-			t.Error(err)
-			continue
-		}
-
-		obj := pkg.Scope().Lookup(objName)
-		if obj == nil {
-			t.Errorf("%s: object not found", test.name)
-			continue
-		}
-
-		got := types.ObjectString(obj, types.RelativeTo(pkg))
-		if got != test.want {
-			t.Errorf("%s: got %q; want %q", test.name, got, test.want)
-		}
-
-		if named, _ := obj.Type().(*types.Named); named != nil {
-			verifyInterfaceMethodRecvs(t, named, 0)
-		}
-	}
-}
-
-// verifyInterfaceMethodRecvs verifies that method receiver types
-// are named if the methods belong to a named interface type.
-func verifyInterfaceMethodRecvs(t *testing.T, named *types.Named, level int) {
-	// avoid endless recursion in case of an embedding bug that lead to a cycle
-	if level > 10 {
-		t.Errorf("%s: embeds itself", named)
-		return
-	}
-
-	iface, _ := named.Underlying().(*types.Interface)
-	if iface == nil {
-		return // not an interface
-	}
-
-	// check explicitly declared methods
-	for i := 0; i < iface.NumExplicitMethods(); i++ {
-		m := iface.ExplicitMethod(i)
-		recv := m.Type().(*types.Signature).Recv()
-		if recv == nil {
-			t.Errorf("%s: missing receiver type", m)
-			continue
-		}
-		if recv.Type() != named {
-			t.Errorf("%s: got recv type %s; want %s", m, recv.Type(), named)
-		}
-	}
-
-	// check embedded interfaces (if they are named, too)
-	for i := 0; i < iface.NumEmbeddeds(); i++ {
-		// embedding of interfaces cannot have cycles; recursion will terminate
-		if etype, _ := iface.EmbeddedType(i).(*types.Named); etype != nil {
-			verifyInterfaceMethodRecvs(t, etype, level+1)
-		}
-	}
-}
-func TestIssue25301(t *testing.T) {
-	testenv.NeedsGo1Point(t, 11)
-	skipSpecialPlatforms(t)
-
-	// This package only handles gc export data.
-	if runtime.Compiler != "gc" {
-		t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
-	}
-
-	// On windows, we have to set the -D option for the compiler to avoid having a drive
-	// letter and an illegal ':' in the import path - just skip it (see also issue #3483).
-	if runtime.GOOS == "windows" {
-		t.Skip("avoid dealing with relative paths/drive letters on windows")
-	}
-
-	compileAndImportPkg(t, "issue25301")
-}
diff --git a/go/internal/gcimporter/gcimporter_test.go b/go/internal/gcimporter/gcimporter_test.go
index 63daca9..cfafbbf 100644
--- a/go/internal/gcimporter/gcimporter_test.go
+++ b/go/internal/gcimporter/gcimporter_test.go
@@ -10,6 +10,7 @@
 import (
 	"bytes"
 	"fmt"
+	"go/constant"
 	"go/types"
 	"io/ioutil"
 	"os"
@@ -286,6 +287,139 @@
 	t.Logf("tested %d imports", nimports)
 }
 
+var importedObjectTests = []struct {
+	name string
+	want string
+}{
+	// non-interfaces
+	{"crypto.Hash", "type Hash uint"},
+	{"go/ast.ObjKind", "type ObjKind int"},
+	{"go/types.Qualifier", "type Qualifier func(*Package) string"},
+	{"go/types.Comparable", "func Comparable(T Type) bool"},
+	{"math.Pi", "const Pi untyped float"},
+	{"math.Sin", "func Sin(x float64) float64"},
+	{"go/ast.NotNilFilter", "func NotNilFilter(_ string, v reflect.Value) bool"},
+	{"go/internal/gcimporter.FindPkg", "func FindPkg(path string, srcDir string) (filename string, id string)"},
+
+	// interfaces
+	{"context.Context", "type Context interface{Deadline() (deadline time.Time, ok bool); Done() <-chan struct{}; Err() error; Value(key interface{}) interface{}}"},
+	{"crypto.Decrypter", "type Decrypter interface{Decrypt(rand io.Reader, msg []byte, opts DecrypterOpts) (plaintext []byte, err error); Public() PublicKey}"},
+	{"encoding.BinaryMarshaler", "type BinaryMarshaler interface{MarshalBinary() (data []byte, err error)}"},
+	{"io.Reader", "type Reader interface{Read(p []byte) (n int, err error)}"},
+	{"io.ReadWriter", "type ReadWriter interface{Reader; Writer}"},
+	{"go/ast.Node", "type Node interface{End() go/token.Pos; Pos() go/token.Pos}"},
+	{"go/types.Type", "type Type interface{String() string; Underlying() Type}"},
+}
+
+func TestImportedTypes(t *testing.T) {
+	testenv.NeedsGo1Point(t, 11)
+	skipSpecialPlatforms(t)
+
+	// This package only handles gc export data.
+	if runtime.Compiler != "gc" {
+		t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
+	}
+
+	for _, test := range importedObjectTests {
+		obj := importObject(t, test.name)
+		if obj == nil {
+			continue // error reported elsewhere
+		}
+		got := types.ObjectString(obj, types.RelativeTo(obj.Pkg()))
+		if got != test.want {
+			t.Errorf("%s: got %q; want %q", test.name, got, test.want)
+		}
+
+		if named, _ := obj.Type().(*types.Named); named != nil {
+			verifyInterfaceMethodRecvs(t, named, 0)
+		}
+	}
+}
+
+func TestImportedConsts(t *testing.T) {
+	testenv.NeedsGo1Point(t, 11)
+	skipSpecialPlatforms(t)
+
+	tests := []struct {
+		name string
+		want constant.Kind
+	}{
+		{"math.Pi", constant.Float},
+		{"math.MaxFloat64", constant.Float},
+		{"math.MaxInt64", constant.Int},
+	}
+
+	for _, test := range tests {
+		obj := importObject(t, test.name)
+		if got := obj.(*types.Const).Val().Kind(); got != test.want {
+			t.Errorf("%s: imported as constant.Kind(%v), want constant.Kind(%v)", test.name, got, test.want)
+		}
+	}
+}
+
+// importObject imports the object specified by a name of the form
+// <import path>.<object name>, e.g. go/types.Type.
+//
+// If any errors occur they are reported via t and the resulting object will
+// be nil.
+func importObject(t *testing.T, name string) types.Object {
+	s := strings.Split(name, ".")
+	if len(s) != 2 {
+		t.Fatal("inconsistent test data")
+	}
+	importPath := s[0]
+	objName := s[1]
+
+	pkg, err := Import(make(map[string]*types.Package), importPath, ".", nil)
+	if err != nil {
+		t.Error(err)
+		return nil
+	}
+
+	obj := pkg.Scope().Lookup(objName)
+	if obj == nil {
+		t.Errorf("%s: object not found", name)
+		return nil
+	}
+	return obj
+}
+
+// verifyInterfaceMethodRecvs verifies that method receiver types
+// are named if the methods belong to a named interface type.
+func verifyInterfaceMethodRecvs(t *testing.T, named *types.Named, level int) {
+	// avoid endless recursion in case of an embedding bug that lead to a cycle
+	if level > 10 {
+		t.Errorf("%s: embeds itself", named)
+		return
+	}
+
+	iface, _ := named.Underlying().(*types.Interface)
+	if iface == nil {
+		return // not an interface
+	}
+
+	// check explicitly declared methods
+	for i := 0; i < iface.NumExplicitMethods(); i++ {
+		m := iface.ExplicitMethod(i)
+		recv := m.Type().(*types.Signature).Recv()
+		if recv == nil {
+			t.Errorf("%s: missing receiver type", m)
+			continue
+		}
+		if recv.Type() != named {
+			t.Errorf("%s: got recv type %s; want %s", m, recv.Type(), named)
+		}
+	}
+
+	// check embedded interfaces (if they are named, too)
+	for i := 0; i < iface.NumEmbeddeds(); i++ {
+		// embedding of interfaces cannot have cycles; recursion will terminate
+		if etype, _ := iface.EmbeddedType(i).(*types.Named); etype != nil {
+			verifyInterfaceMethodRecvs(t, etype, level+1)
+		}
+	}
+}
+
 func TestIssue5815(t *testing.T) {
 	skipSpecialPlatforms(t)
 
@@ -501,6 +635,24 @@
 	}
 }
 
+func TestIssue25301(t *testing.T) {
+	testenv.NeedsGo1Point(t, 11)
+	skipSpecialPlatforms(t)
+
+	// This package only handles gc export data.
+	if runtime.Compiler != "gc" {
+		t.Skipf("gc-built packages not available (compiler = %s)", runtime.Compiler)
+	}
+
+	// On windows, we have to set the -D option for the compiler to avoid having a drive
+	// letter and an illegal ':' in the import path - just skip it (see also issue #3483).
+	if runtime.GOOS == "windows" {
+		t.Skip("avoid dealing with relative paths/drive letters on windows")
+	}
+
+	compileAndImportPkg(t, "issue25301")
+}
+
 func importPkg(t *testing.T, path, srcDir string) *types.Package {
 	pkg, err := Import(make(map[string]*types.Package), path, srcDir, nil)
 	if err != nil {
diff --git a/go/internal/gcimporter/iimport.go b/go/internal/gcimporter/iimport.go
index b236deb..8ed8bc6 100644
--- a/go/internal/gcimporter/iimport.go
+++ b/go/internal/gcimporter/iimport.go
@@ -473,6 +473,14 @@
 	switch {
 	case exp > 0:
 		x = constant.Shift(x, token.SHL, uint(exp))
+		// Ensure that the imported Kind is Float, else this constant may run into
+		// bitsize limits on overlarge integers. Eventually we can instead adopt
+		// the approach of CL 288632, but that CL relies on go/constant APIs that
+		// were introduced in go1.13.
+		//
+		// TODO(rFindley): sync the logic here with tip Go once we no longer
+		// support go1.12.
+		x = constant.ToFloat(x)
 	case exp < 0:
 		d := constant.Shift(constant.MakeInt64(1), token.SHL, uint(-exp))
 		x = constant.BinaryOp(x, token.QUO, d)
diff --git a/godoc/godoc.go b/godoc/godoc.go
index 6d4d115..a88aa12 100644
--- a/godoc/godoc.go
+++ b/godoc/godoc.go
@@ -398,9 +398,8 @@
 }
 
 type PageInfo struct {
-	Dirname  string // directory containing the package
-	Err      error  // error or nil
-	GoogleCN bool   // page is being served from golang.google.cn
+	Dirname string // directory containing the package
+	Err     error  // error or nil
 
 	Mode PageInfoMode // display metadata from query string
 
@@ -614,8 +613,7 @@
 
 		err := p.ExampleHTML.Execute(&buf, struct {
 			Name, Doc, Code, Play, Output string
-			GoogleCN                      bool
-		}{eg.Name, eg.Doc, code, play, out, info.GoogleCN})
+		}{eg.Name, eg.Doc, code, play, out})
 		if err != nil {
 			log.Print(err)
 		}
diff --git a/godoc/golangorgenv/golangorgenv.go b/godoc/golangorgenv/golangorgenv.go
deleted file mode 100644
index 0b96eec..0000000
--- a/godoc/golangorgenv/golangorgenv.go
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2018 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package golangorgenv provides environment information for programs running at
-// golang.org and its subdomains.
-package golangorgenv
-
-import (
-	"log"
-	"os"
-	"strconv"
-)
-
-var (
-	checkCountry = boolEnv("GOLANGORG_CHECK_COUNTRY")
-	enforceHosts = boolEnv("GOLANGORG_ENFORCE_HOSTS")
-)
-
-// CheckCountry reports whether country restrictions should be enforced.
-func CheckCountry() bool {
-	return checkCountry
-}
-
-// EnforceHosts reports whether host filtering should be enforced.
-func EnforceHosts() bool {
-	return enforceHosts
-}
-
-func boolEnv(key string) bool {
-	v := os.Getenv(key)
-	if v == "" {
-		// TODO(dmitshur): In the future, consider detecting if running in App Engine,
-		// and if so, making the environment variables mandatory rather than optional.
-		return false
-	}
-	b, err := strconv.ParseBool(v)
-	if err != nil {
-		log.Fatalf("environment variable %s (%q) must be a boolean", key, v)
-	}
-	return b
-}
diff --git a/godoc/page.go b/godoc/page.go
index daf4dc9..126790f 100644
--- a/godoc/page.go
+++ b/godoc/page.go
@@ -9,9 +9,6 @@
 	"os"
 	"path/filepath"
 	"runtime"
-	"strings"
-
-	"golang.org/x/tools/godoc/golangorgenv"
 )
 
 // Page describes the contents of the top-level godoc webpage.
@@ -22,7 +19,6 @@
 	SrcPath  string
 	Query    string
 	Body     []byte
-	GoogleCN bool // page is being served from golang.google.cn
 	TreeView bool // page needs to contain treeview related js and css
 
 	// filled in by ServePage
@@ -57,26 +53,6 @@
 		Title:           "File " + relpath,
 		Subtitle:        relpath,
 		Body:            applyTemplate(p.ErrorHTML, "errorHTML", err),
-		GoogleCN:        googleCN(r),
 		GoogleAnalytics: p.GoogleAnalytics,
 	})
 }
-
-// googleCN reports whether request r is considered
-// to be served from golang.google.cn.
-func googleCN(r *http.Request) bool {
-	if r.FormValue("googlecn") != "" {
-		return true
-	}
-	if strings.HasSuffix(r.Host, ".cn") {
-		return true
-	}
-	if !golangorgenv.CheckCountry() {
-		return false
-	}
-	switch r.Header.Get("X-Appengine-Country") {
-	case "", "ZZ", "CN":
-		return true
-	}
-	return false
-}
diff --git a/godoc/search.go b/godoc/search.go
index 0e7509a..33e4feb 100644
--- a/godoc/search.go
+++ b/godoc/search.go
@@ -122,7 +122,6 @@
 		Tabtitle: query,
 		Query:    query,
 		Body:     body.Bytes(),
-		GoogleCN: googleCN(r),
 	})
 }
 
diff --git a/godoc/server.go b/godoc/server.go
index 8c9b1b9..48e8d95 100644
--- a/godoc/server.go
+++ b/godoc/server.go
@@ -328,7 +328,6 @@
 		info.TypeInfoIndex[ti.Name] = i
 	}
 
-	info.GoogleCN = googleCN(r)
 	var body []byte
 	if info.Dirname == "/src" {
 		body = applyTemplate(h.p.PackageRootHTML, "packageRootHTML", info)
@@ -340,7 +339,6 @@
 		Tabtitle: tabtitle,
 		Subtitle: subtitle,
 		Body:     body,
-		GoogleCN: info.GoogleCN,
 		TreeView: hasTreeView,
 	})
 }
@@ -610,7 +608,6 @@
 		SrcPath:  relpath,
 		Tabtitle: relpath,
 		Body:     buf.Bytes(),
-		GoogleCN: googleCN(r),
 	})
 }
 
@@ -689,7 +686,6 @@
 		SrcPath:  relpath,
 		Tabtitle: relpath,
 		Body:     applyTemplate(p.DirlistHTML, "dirlistHTML", list),
-		GoogleCN: googleCN(r),
 	})
 }
 
@@ -726,7 +722,6 @@
 	page := Page{
 		Title:    meta.Title,
 		Subtitle: meta.Subtitle,
-		GoogleCN: googleCN(r),
 	}
 
 	// evaluate as template if indicated
diff --git a/godoc/static/analysis/help.html b/godoc/static/analysis/help.html
index 023c07d..dd1b606 100644
--- a/godoc/static/analysis/help.html
+++ b/godoc/static/analysis/help.html
@@ -62,7 +62,7 @@
   Clicking on the identifier that defines a named type causes a panel
   to appear, displaying information about the named type, including
   its size and alignment in bytes, its
-  <a href='http://golang.org/ref/spec#Method_sets'>method set</a>, and its
+  <a href='https://golang.org/ref/spec#Method_sets'>method set</a>, and its
   <i>implements</i> relation: the set of types T that are assignable to
   or from this type U where at least one of T or U is an interface.
 
diff --git a/godoc/static/example.html b/godoc/static/example.html
index 1e86b25..a7f6691 100644
--- a/godoc/static/example.html
+++ b/godoc/static/example.html
@@ -13,9 +13,7 @@
 				<div class="buttons">
 					<a class="run" title="Run this code [shift-enter]">Run</a>
 					<a class="fmt" title="Format this code">Format</a>
-					{{if not $.GoogleCN}}
 					<a class="share" title="Share this code">Share</a>
-					{{end}}
 				</div>
 			</div>
 		{{else}}
diff --git a/godoc/static/favicon.ico b/godoc/static/favicon.ico
new file mode 100644
index 0000000..8d22584
--- /dev/null
+++ b/godoc/static/favicon.ico
Binary files differ
diff --git a/godoc/static/gen.go b/godoc/static/gen.go
index 85c6714..bfbc5bd 100644
--- a/godoc/static/gen.go
+++ b/godoc/static/gen.go
@@ -35,6 +35,7 @@
 	"dirlist.html",
 	"error.html",
 	"example.html",
+	"favicon.ico",
 	"godoc.html",
 	"godocs.js",
 	"images/minus.gif",
diff --git a/godoc/static/godoc.html b/godoc/static/godoc.html
index 86cacb7..6204d33 100644
--- a/godoc/static/godoc.html
+++ b/godoc/static/godoc.html
@@ -39,7 +39,7 @@
 <form method="GET" action="/search">
 <div id="menu">
 {{if (and .Playground .Title)}}
-<a id="playgroundButton" href="http://play.golang.org/" title="Show Go Playground">Play</a>
+<a id="playgroundButton" href="https://play.golang.org/" title="Show Go Playground">Play</a>
 {{end}}
 <span class="search-box"><input type="search" id="search" name="q" placeholder="Search" aria-label="Search" required><button type="submit"><span><!-- magnifying glass: --><svg width="24" height="24" viewBox="0 0 24 24"><title>submit search</title><path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/><path d="M0 0h24v24H0z" fill="none"/></svg></span></button></span>
 </div>
@@ -60,9 +60,7 @@
 	<div class="buttons">
 		<a class="run" title="Run this code [shift-enter]">Run</a>
 		<a class="fmt" title="Format this code">Format</a>
-		{{if not $.GoogleCN}}
 		<a class="share" title="Share this code">Share</a>
-		{{end}}
 	</div>
 </div>
 {{end}}
@@ -100,8 +98,8 @@
 the content of this page is licensed under the
 Creative Commons Attribution 3.0 License,
 and code is licensed under a <a href="/LICENSE">BSD license</a>.<br>
-<a href="/doc/tos.html">Terms of Service</a> |
-<a href="http://www.google.com/intl/en/policies/privacy/">Privacy Policy</a>
+<a href="https://golang.org/doc/tos.html">Terms of Service</a> |
+<a href="https://www.google.com/intl/en/policies/privacy/">Privacy Policy</a>
 </div>
 
 </div><!-- .container -->
diff --git a/godoc/static/packageroot.html b/godoc/static/packageroot.html
index c246c79..6af463b 100644
--- a/godoc/static/packageroot.html
+++ b/godoc/static/packageroot.html
@@ -38,7 +38,7 @@
 			</div>
 			<div class="expanded">
 				<h2 class="toggleButton" title="Click to hide Standard library section">Standard library â–¾</h2>
-				<img alt="" class="gopher" src="/doc/gopher/pkg.png"/>
+				<img alt="" class="gopher" src="https://golang.org/doc/gopher/pkg.png"/>
 				<div class="pkg-dir">
 					<table>
 						<tr>
@@ -115,7 +115,7 @@
 	<h3 id="subrepo">Sub-repositories</h3>
 	<p>
 	These packages are part of the Go Project but outside the main Go tree.
-	They are developed under looser <a href="/doc/go1compat">compatibility requirements</a> than the Go core.
+	They are developed under looser <a href="https://golang.org/doc/go1compat">compatibility requirements</a> than the Go core.
 	Install them with "<a href="/cmd/go/#hdr-Download_and_install_packages_and_dependencies">go get</a>".
 	</p>
 	<ul>
diff --git a/godoc/static/static.go b/godoc/static/static.go
index 3dab9ea..35aece4 100644
--- a/godoc/static/static.go
+++ b/godoc/static/static.go
@@ -23,7 +23,7 @@
 
 	"analysis/error1.png": "\x89PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\x00\x04\xc1\x00\x00\x00\xbd\x08\x03\x00\x00\x00\x8d\xa5\x9a\x96\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x02\xfdPLTE\x00\x01\x00\x02\x05\x01\x0a\x03\x01\x05\x07\x03\x1e\x01\x00\x0b\x0d\x0a\x10\x12\x0f\x16\x17\x13y\x00\x01\x19\x1b\x18\x1b\x1b\x14\x83\x01\x00\x8c\x00\x00\x8c\x00\x04\x20\x1f\x19!#\x20#$\"%%\x1e$%#&'%'(&+)\x1e()'++$*,)/,!-/,02/63(241\x98\x1b\x1b786;8,\x82%#:;9><0>?=C@4@B@\xa0*,CEB\x9c.-KH<MH7\x00f\x00\x00g\x00\x00h\x00JKI\x00i\x01\x00j\x02MOL\x04l\x05TO>\x09n\x07PRP\xa9:<WRA\x0co\x09\x0fp\x0bTVT\x0cr\x17\x11t\x19^YG\xaaDCY[X,`\xae7]\xad\x15v\x1c\\^[\x19y\x1e;b\xac_a^faO>e\xaf*{!bda)}*Bh\xb2egdLj\xafpiR.\x81.Em\xb1ikh\xb3XX0\x8301\x841/\x858Jq\xb5mol;\x86:Vu\xb4>\x89={t\\tvs@\x8b?B\x8c@@\x8dG\\z\xbay{xJ\x8eI^~\xb8\x84|d\xbbkkL\x90K~\x7f}O\x93Mb\x83\xbdN\x95UW\x95V\x82\x84\x81\x8f\x85hm\x87\xbdZ\x98Y[\x9aZ\x87\x89\x86\xc0{|]\x9c\\\\\x9dcr\x8d\xc2\x96\x8cnd\x9dd\x8c\x8e\x8b{\x8f\xc0f\x9fg\x90\x92\x8f~\x93\xc4j\xa3jy\x96\xc5\x94\x96\x93s\xa4l\xa1\x96xq\xa5s\x81\x99\xc3\x97\x99\x96\x83\x9b\xc5\xa5\x9b}u\xaaw\x9a\x9c\x98\xc7\x91\x92\x9c\x9e\x9b~\xaby\x88\xa0\xca\x9e\xa0\x9d\x81\xad|\xab\xa0\x82\x8e\xa2\xc7\xa1\xa3\xa0\xa2\xa4\xa1\x81\xb1\x85\x92\xa5\xca\x8b\xb2\x88\xb4\xa7\x83\xa6\xa8\xa5\x8d\xb5\x8a\x97\xab\xd0\xa9\xab\xa8\x8e\xb6\x8c\x8d\xb8\x93\xab\xad\xaa\xb9\xad\x88\x9f\xae\xce\xae\xb0\xad\x96\xba\x96\x98\xbb\x98\xa3\xb2\xd2\xb0\xb2\xaf\xd9\xa8\xa6\x9b\xbe\x9a\xc2\xb5\x90\xb4\xb6\xb3\xa3\xbf\x9d\xac\xb7\xd2\xb6\xb8\xb5\xa2\xc0\xa4\xb7\xb9\xb6\xdb\xb0\xb3\xa5\xc4\xa7\xba\xbc\xb9\xb1\xbd\xd7\xa7\xc6\xa9\xbd\xbf\xbc\xa8\xc7\xab\xcc\xbf\x99\xaf\xc6\xab\xb8\xc0\xd5\xbf\xc1\xbe\xb2\xc9\xae\xd0\xc3\x9e\xc2\xc4\xc1\xbc\xc4\xd9\xe2\xbd\xbe\xc4\xc6\xc3\xb2\xcd\xb7\xbb\xcd\xb9\xc0\xc8\xdd\xbb\xca\xde\xc7\xc9\xc5\xd8\xc9\x9d\xbd\xcf\xbb\xc6\xca\xda\xc0\xcc\xda\xca\xcc\xc9\xbf\xd2\xbe\xd7\xcf\xa1\xcd\xcf\xcc\xc4\xd0\xde\xcb\xcf\xdf\xc8\xd3\xc1\xe0\xd1\xa5\xd0\xd2\xce\xc8\xd6\xc9\xea\xcc\xcb\xd1\xd3\xd0\xd2\xd3\xdd\xca\xd8\xcb\xd3\xd5\xd2\xdf\xd6\xa8\xcd\xd6\xde\xcc\xda\xce\xe6\xd6\xaa\xd6\xd8\xd5\xd4\xdb\xd0\xeb\xd4\xd2\xd2\xda\xe3\xd8\xd9\xe3\xea\xdb\xaf\xda\xdc\xd9\xd7\xde\xd3\xe1\xdb\xda\xd5\xdf\xda\xdc\xdd\xe7\xdc\xdf\xdb\xd7\xe1\xdc\xde\xe0\xdd\xdc\xe1\xe3\xf0\xe0\xb3\xe0\xe2\xdf\xe2\xe4\xe1\xee\xe1\xe2\xdf\xe5\xe7\xe4\xe6\xe3\xe8\xe5\xea\xe5\xe7\xe4\xf2\xe4\xe5\xe6\xe8\xe5\xe3\xe9\xeb\xe7\xe9\xe6\xe8\xea\xe7\xeb\xed\xea\xf6\xf0\xef\xf2\xf4\xf1\xfe\xf8\xf7\xf9\xfb\xf8\xfe\xff\xfc!l\x99S\x00\x00\x20\x00IDATx^\xed\x9d\x0fXT\xd7\x9d\xf7\xf7\xd9\xd9\xd8w\xd3$C\x03\x9b\x12-K^\xd6fm\xfb\xdc\xe1\x19\xa9\xbe+\x0c\x8d\x1d\x14\xd7?1+\xbeVQ\x8aV1\x1b1\x18\xe7a\x13\xa3\x82\xc6\x84L\x0a\x19%)\x20B\xe6\x89E\x1eY3*\xbe\">\x19Me\xc1\x96hqm\x12\xe8S\xa6\xd1\xb1\xb6\xda\xe4\xf2(\xac\xe4y\xaf\xe7\xed\xa6\xe5y\xcf9\xf7\xdf\xb9\xc3\xbd3(\x03\x97\xd1\xdf\xe7\xd1;\x87;\xbf\xf3\xbb\xe7\x9c\xb9\xf7;\xe7\xfc\xee\x99{\xfejh\x14\x20\x00\x00\x00\xf3\x18\x1a\xfa\xabH*\x15\x8eH\xee\x01\x00\x00\xc6\x10P0\x00\x00b\x17P0\x00\x00b\x17P0\x00\x00b\x17P0\x00\x00b\x17P0\x00\x00b\x173\x15,p\xa0\xaa\xa2\xfa\x18O\x92\xc2\x99\xba\x8a\xba\xceH\x19\x00\x00\x004\x98\xa8`A\xb7\xb7\xb3\xbb\xb3\xae\x0aK\x98\xe0\xf5\x9c\xee>Yq2R\x16\x00\x00\x00\x16\x13\x15\xac\xcb\xdd\x8d\xb7\xbc\x1bw\xbd\xceT\\#;*\xf8Hy\x00\x00\x00\x18LT0D\xf5*\xe8\x0e\x20\xe4=@wTB'\x0c\x00\x80;\xc1L\x05\xc3\xf4wW{\x05\x84\xea|\xf4/\xef\xfe\x08\xe6\x00\x00\x00,\xa6*X\xd0\xedv{HO\xecX\xe5\x00\xde\x0ex\xea\"\xe5\x00\x00\x00`0U\xc1P0\xd0^M\"\xf9\xbc\xc7\x1b\xec\x0fx\xdd\xd5\x912\x00\x00\x000\x98\xab`\x98\x81\xea&\xbc\xbd\xe6\xc5\xdd\xb1\x16\xaf7\x925\x00\x00\x00\x83\x89\x0a6\x20\xd0\x973n\xfa\xda\x7fM@\x95\xc7\xc2f\x00\x00\x00\xd0b\x9e\x82\x09\x95b\xf8\xfeL\x05V\xb0A\x92\xea\"\xb7%\x01\x00\x00F\x8cy\x0a\x86\xaa\xe8\x14\x0a:\x8a\xect\x07\x11\xe2\xab|\x91\xb2\x00\x00\x00\xb0\x98\xa8`]\xee\xa6\xce\xeeN\x1a\xc9\xefr\x9f\xec>S\xe9\x85\x09\xad\x00\x00\xdc\x11&*\x18\x0a4UW\xd4\xb5\x90y\x14\xe8t\xb5\xc7{Z\x88\x94\x01\x00\x00@\x83\x99\x0a\x06\x00\x000:@\xc1\x00\x00\x88]@\xc1\x00\x00\x88]@\xc1\x00\x00\x88]@\xc1\x00\x00\x88]@\xc1\x00\x00\x88]@\xc1\x00\x00\x88]@\xc1\x00\x00\x88]@\xc1\x00\x00\x88]@\xc1\x00\x00\x88]@\xc1\x00\x00\x88]@\xc1\x00\x00\x88]@\xc1\x00\x00\x88]bK\xc1\\.\xbd$\x00\x00\xf7+&+X\xbb[z4~\xc0\xeb9\x10\xf1\x09\xad\x1fs;u\x92\x84z\x8e\xe3\xcaQ9\xde\xd6\x0f\xcf\xa6\xd0k\xe3\x16\xe1\x17\x176K\xeb\x09c\xa7\xe5\xb8\xe3p\x98w\xef\xd0\xd9\xe8\xc0\x07\xab\xc1/5\x1c\xc7\xea\xf7\x8b\x1c\xd7\xa8\xfcq\xeeG\x8eY+[\x97|0,\xafH-k\x1b\x81\x17Gd{w\x8d\xfa\xd9\x8b\x0e\xfb\x8f\xa2\xf28%\xed\x81\xc3\x7fX\xe3\xc3D(\xc3\xfd\x83\xb9\x0a\xc6W\x1c\xab\xa4\x89\xee\x0a_\x97\xaf\xa2;\x82y\x91\xfd\x8aN\x92\xc0\xbf\xcb\xed\xbe\x8e\xae\xbf\xc5\xbd\x1b\xf6)\x89\x1d.;\xde^\xf2\xfbk9\xa3K|8\xcdi\xe1\xae\xe3;t\xa6\xd2z6\x92\xc5p.\xa5\xbd\xd5\x87_\xfa\xde\x9aq\x89\xd9{\xc5o+\x97\xd3gm\x05\x87\x1a\x9f3\x96\x9e>\xff\xf2r\xa4\x87NqX\xbfa\xb8\xabF\xcds\xd4\xba\xd2\xfa\"Y\x8d\x04\xed\x81\xc3\x7fXw\xd7\xea#\x81\xf5\x1b\xa9\x0c@41W\xc1\xbcM\xddT\xc1\x84*\xb2\xc6\xc7\xb1\xaa\xf0_\xca=\\\x89NR\xe4\x02w\x1co[\xb9\x0b(,\xe5v\xf1\xb5\xe3\x0e.6\x14\xa9\xabpG\xce\x14~P\x18\xc9B\x87%b\x17\xb3~\x89v\xb7]Q\x9a\xd5yd\xeb\x0a\xd3y*\xd0W%\xdd\xe2\xd8G\xa2`w\xd3\xa8}\xb8/)\xf4G\xb2\x1a)\xec\x81#|Xw\xd5\xea#@\xe37\xd2\x09\x03D\x11S\x15\xac\xdd\xc3\x07\xa8\x82uV\x90\xb3\x99\xaf\xe8\x0ck\xeeR\xfb].m\x17ll\x15,\x12w\xe7l\xd9\xdd\\K\x85e\xf4\xa5,$\xaf\xaa4s\xa9\xc19\xee\x102\xc2@\xc1t\x8b3f\x0a\xd6\xc3Es\xa0u\x07\x07\xbe\xabV\x1f\x01c\xe5\x17\x88\x84\x99\x0a\xc6Wt!Q\xc1\x9a\xf6\xd3\x1d\xfb\xc3.\xf5\xd1k\xdb\xaa\x93\x94`\x14\x8c/\xcc\xb4e\x15\x9c\xc3\x7f\xbe\xc4\xd9\xeaK\x16\xa4\xad\xa6C\xae+E\x99\xe9\x85\xaea\x17[\xe3\xca\xb4\x05%X?\xcf\xd98\xae\xac\xa7h\xae}\x8d\xe6\x1b\xb4/\x8d\x13\x87d\x82\xc3\xf6jVf\xeb\xd6Yy<\xf1[\xe3\xcaJ/\xe81p\xc6\xda2\x87`\x8as\x98\x13YF\xde\xf7\xaf\xce\xb29~\x94\x854\xa8\xb5`\xd9)^(\x85;Y\xbfXi\xb6\xba2\xc5\xe2\x14fR\x0do\xa6\xbbk\x97\xa5-\xa9\x153\xf6\x14:\xf01\x88\xecc\x05\xdb\x8a\x8fl\xff\x8c\xf1\xa0)\x0e\x83\xbdDn\xbeh6\xea\xa0C<\x9a\xd8\x8d\x96\x0bi\xf0\x01\xe8\xb7\x03[!\xf5\xc0\xca\x87E\x88\xd4\xea\x06\xce\xe4\xe20\xd945fZ]\xc9\xc6\xfa\xd5\x94A\xc7\x19\x10e\xccT0o\x13\x92\x14\xacN\\(\xf2X]8s\x97\xed\x92NR\xe2\x02\xd7<00\xd0L\x14\xac\x99s\xb56\x16p\x1d\x08}\xdch\xe3\x1c\xe553\xc8e\xdf3kA\xfd\xe1\xd5\\\xe8\xc5\xe6\xe2\xb66\xd78\x96\x09h\xa0\xb11k\xc1\x8c\xac\x92\"\xaeW\xe3\xf8\xac\xdf/\xf6DZgq%y\x9cc\xb7\xa3\x86\xfa\xcd\xda]\x9e\x95v\xc1\xc0\x19c\xcb\xece\x8a\xc3\x7f\xe0_\x90\xe7\xf7\xfb\x89\xe8\x9c\xe5\x8a\x1a\x8f\xd7;8\xed\xd8C\xad\x05K\xfd\x0fPG\xd6\x07hY=\xeb\x17+\x0d\xb7\xac\xb1q\x09)No\x16\xb7\xa6\xbccP,\x8e\xbd\xac\xb9\xcc^D\x92\xadi\xcb\xde:^No\x03`\x05\xbbR\xc4\xd5t\xb0\x1e\xd8\xe2\xb0\xd8\xb9E\x8d\x87\x1d\xa4\xf9\xa2\xda\xa8\xe7\xfc\x8d\\\xb9\xdfO\x15C)\xa4\x81\xad~;\xb0\x15b\x0e\xac|X\x91[\xdd\xc0\x99R\x1c&\x1b[c\xb6\xd5\x95l\x1a\xbfl\x19t\x9c\x01Q\xc6D\x05\xeb\xf4\xf0\xb2\x82U\x9e\xa4{NV\x861\xef\xb5\xbd\xa8\x93\x94\xb9\x20}\x0d\xe2\x8b\xb8\xbf\x91|C.y\x8e\xec\xb6\xa7c\xa9+r\xe0\xd4\xca\x05x\xaf\xb0$\xe4bk\xe6\xde\xa5\x7f\xd1/\xcde\x1c\xe93\x0d\xbf\x15\x20\x9d\x90\x99E\xd8\xfc\xb08\x8d\xc3>\x17\x9b\xf5e-7r\xc6\xd8\xb2\x87P\x8b\xc3\x8c;j\x1d\xe4r\xa8\x9d\xa5U0\xb6\x16*~\x07\xdai+A\x0e\x7f\x88\xdfE\x03X\x02\x16,\xc7\xc9\xbe\xdd\xcbm\\:\xd9y\x9cvK\x8fs\xcd\xf8\xad\xac5\xd8`\xb0\x91\x84\xce\xb1\x82\xd5\xd8\x9b\x893m\xe5uG\x91\x0e\xdcSs\x91\xf2F\xb9Q\x95Q$SH}[\xfdv`+\xa4\x1dEJ\x1fV\xc4Vg`\x9c\xb1\xc5a\xb2\xa9I\xc6\xaf\xa6\x0c\x1a\xbfR\x19\x0c\x9c\x01Q\xc5<\x05\xe3+:\x05A\xe8\xae\x14\xf0\x95['\x0e\x1f}\xe1\xfa`/\xd9zu\x922\x17p\xaf\xa2\xa3\xa3\x86\xc6\xc1>\xab]3w\x16G\x83\xddv\"7$N\xd3'N\xb3(\x0b\xb9\xd8\x0a\xe7\x0e\xe2B\x08Ytr\xc22\xfb0\xb7\x14Y\xc1\x1aq6\x1e\xed|\x9e\xec\xa2\xc3\xb8Z\x8e\x9e\xbd:\xce\x18[\xf6\x10Jq\x10s\xce_\xca\x9c\xfbR\xfd9a\x10iaj\xa1\xd2\xcb\xf5\xe7\x15\xad\xec'\xdd\x14\x8d\xdfW\xc9\x9bRq\xd0@\xeb\x1ar\xd5\xb8\x16\xd1\xbf\x16Q\x15U\x87a\x05\xe5e\x92|h+\xaf\xab`jy\xa3\xdb\xa8\x8a\x821\x854\xb0\xd5m\x07\xb6B\xba\x0a\x16\xb1\xd5\x19\x18glq\x98lj\x92\xf1\xab)\x83\x9e\x82\x198\x03\xa2\x8ay\x0av\xd1-\x13@M\xe2\xac02\xac4\xe2\x0a=\x07B\x93\x0aL\x1c\xac\xc3\x91\xb5\xf3\x90?O\xbc\xd8\xc8\xb9DN\x9c\xb3\x9c\x1f\xa1\xe1A\xe7%R\xd7\x8d~\xc5/\x1b\x16\x1f\x11\x91\x15\xec8\xea\xb0!I\xc1\xe8.?G\xef\xa1\xeb8cl\xd9C(\xc5A\xec9\xdfW_\xb8\x08\x0f9\x91\x06\xb6\x16*\x82\xfdB\xda\xb9\xb4\x0b6A\xc7/-N\x07\x1d\x9a\x09+\x0bp\x07\xa9\x80f)XN&\x90\x0d(.\x0a\x1c3\x16\x89\x87\xd6V\xde0\x92O\xcb\x1b\xe5FU\x14\x8c)\xa4\xbe\xad~;\xb0\x15\xd2U\xb0\xc8\xad\xae\xc28c\x8b\xc3dS\x93\x8c_M\x19\xf4\x14\xcc\xc0\x19\x10U\xccS0!Hh\xf7\x04\x83\x02\xeat\x93\xa1\x03\xef\x0es/r+\xd7\xa3\x93T`\x14l\xd1r2\xee(\xd4^l\x9fq\xb5\xe4\xef\xd0\xa0s\xd1\xdc\xb3\x14\x12\xd66\xbc\x9f\xc4(\x98]V0z'\xa1\x9e\xa3#\x1e\x1dg\x8c-{\x88a\xd7R}/\xd6\x01\xd2\x9f\xebk\xb4\xd7j\x0e\xca\xd6\x82a\xc1[\x99(\xabf\x01\x0a\xf1K\x83\xe2\xa48\x99/Q\xb32l\xe1\x9aK\x93s]\xa4]\x98>\x98\xe3B\xef,\x1a?\x1a^yR\x1c\x16\xb5\xbcQnT\xb5\x0f\xa6\x16R\xdfV\xbf\x1dZ#\xf5\xc1\"\xb6:\x03\xe3\x8c-\x8e\xae\x821~[\x87\xf5\xc1d\xbfr\x1fL\xdf\x19\x10U\xccS0\x91\x804\x1f\x8c\x0c#}a\xe6\x83E\xe8\x82\xb1\x0a\x96EN&a\x89\xf6bC\xcb\xb3\xf0\x10\xab\xc7\x1er\xb1\x1d\x17\x835e\xb4\x03t'\x0a\xe6\xc0\xd7\x15?\x97N\xbe\xd2s\xc6\xd8\xb2\x87`\xcf\xe3<\x9c\xf9\x0ay\xaf\x9c\x16\x1d\xe5ic{l-\x18\xd6\xac|\x0e\x15\xae\\\x8dB\xfcf\x91\x88\xcc\"\xec\xd1A\xaa\x89\x04R\x95fj\xd0H\x06\x94\xfd\x99y\x838\xbd\x95\xe8.\x99M\xd1l\xeb\x08\xf1\xa0\x16\x87E-o\x94\x1bUQ0\xa6\x90\xfa\xb6\xfa\xed\xc0VHW\xc1\"\xb6\xba\xbe3\xb68\xba\x0a\xc6\xf8\xd5\x94A\xe3W*\x83\x813\x84zw\x8f\xfc\xc7\x0b@\x04\xccU0!\xd0\xee\x09\\CtN\xfe\xc5\xb0s\xf2K\xd4~W\x89N\x17\x8c\x9d\x93_\xce\x15\xd6\xee^\xc69\xde\xea\xb8\xe2\xb7\xb9:\xd0Y\x97\xcd\x7f\x05]H\xcb*/K\xe7l\xef^\x10gq\xd7\xf8\xfd\xbd8\xe3N\xee\xf9\xc6Cd\x02\xa8\xd0A\xef'\xf5\x868\x1e\xfc\xc0\xef\xb7\xbb\xfc~\x1e]H\xaf\xe9o\xb4\x9d\xeb\x7f>\xef\x12\xa27\xff\xea\x17\xa4\xf7\x20}g\x1a[e/[\x1cr:\xd7\x1c\xcaK\xbbD\x14,\xad\xac\x19\x1b\xb4j\x0e\xac\xd6B\xb3{+\xb7\x1b\xbd\xc5\xd1\x8bF\xf1K\x8a\xb3\xa6\xa3u%)\x8e\x83\xcb,;\x8e\xfd\x92&*\xe2v6\xef\xe4\xc4{\x91\xf6E\xb5\xcd[\xb9z2'\xdf\xf5\xc1`\x7fAf\xebu\x8d\x07\xb58*ly\xa3\xda\xa8\xe2\xbd\xc8\x0e\xfa}\xa5\x14\xd2\xc0\xd6\xa0\x1d\x94\x0a\xb1\x07V?\xac\xc8\xad\xae\xefL-\x0e\x93M\xe3\x81i3&\x9b\xea\x97-\x83\x9e3b\\\xc0\xfd\x08\x01Q\xc2\\\x05\x0b\x900X\x15M\x1d\xa8\xf0\x86\xf9]\xe4\xf5\xb4\"\x9d\xa4\x0a\xfb\xbbH\xa1f\x81\xddQX\xbf\xc0\x96\xf7\"\xfe\xdbv\x81L\xd0\xc1\xfd\x9b\x9e\x82\xf4\xb9%\xef\xdap\xd2%\xc52\xe87\xfe\xf1<G\xfa\xcaf2\x09\x94R\x10\xe2\xf8\xacd[/88\xaeq\x06\x97\xd6Hc\x20\xf6\x12\xd7\xac\xcc\"r:\xea9\xd3\xda*\x87\xd0\x14\x07\x0dlM\xb7\xe7\x91\xcb\xb2qey\x96-3O+`L-4\xbb\x9b\xd3\xcea\xdd\x10;0\xb2_<\xd4*/\x9c!\x16gy}\xd9\xa24\x878SM\xa8Y\x92\xb6\xa4V\xec\xd7\xf6\x14f\xcdX~\x88\xfe.\x92\xe3\xce\xe2\x82qe\x1a\x0fjqT\xd8\xf2F\xb3Q\x07f\xd1\xbd6m!\x0d>\x00\x83vP*\xc4\x1eX\xf9\xb0\x88A\x84V\xd7w\xa6\x16\x87\xc9\xa6\xf5\xc0\xb4\x99\x9aM\xf5\xcb\x96A\xcf\x191\xaew\x84\xfb\xf5.pG\x98\xab`#\xe6U\xeec\x9d\xa4yH\xe3\x04\x00\x00\xcc%F\x14l\xa2=V\x07\x14\x0c\x00&\x041\xa2`\x13\x0dP0\x00\x98\x10\x80\x82\xdd\x05b`V\xe6\xcdo=\xc4\xf2\xad7\xc3\xe4\x04\x00\x20\xaa\x80\x82\xdd\x0540\xdb+\xa6\xff\xa8\xd5/\xaaa\x7f\x0c\x9b\x1b\x00\x80\xa8\x01\x0a6J\x86\x0b\x18\x96\xb0H\x99\x00\x00\x88\x0e\xa0`\xa3\xe3M\x1d\x01{\xe8!\x18H\x02\xc0\xf8\x00\x0a6:\xf4\xba`\xd0\x09\x03\x80\xf1\x02\x14lt\xe8\x0a\xd8C\x0fE\xca\x06\x00@T\x00\x05\x1b\x1d\xa0`\x00`&\xa0`\xa3\x03\x14\x0c\x00\xcc\x04\x14lt\x80\x82\x01\x80\x99\x80\x82\x8d\x0eP0\x000\x13P\xb0\xd1qo)\x98wf0\x92\xc9\xb8sm\xa67\x92\x09p\x1fc\xb2\x82\xb5\xbb\x95\xd3\xd3\x17~\xb1\xc8\x11\xe3\xb1Z\xad\xc5\xa8\x18o+\xc2X]\x8c\xb7N\xc3/\xb9\xd8,\xb1+\x8c]$\"+X\xbe5\xae\xda0{\x08\xbb\xacqU\x91ld\xc6\xa0\x9e\xdb\xb0\xc3\xc848\x9dG\xc2\x1a\x1ct:\x9d{\xd1^\xbc=\x18\xc6\xea\xd3l\xe7*\xfc\xf2\x0a6\x9b\xffi\x18;\xb4-n[\xb8\xb7\x81\xfb\x1bs\x15\x8c\xaf8&/O\x14t\x9f\x0ck:bx\x8fu[\x10\x05\xb7Y=\xc3W\x1dbh\xc9M\xc0\xdbn\x9fo\x97\xb5%\x9c]\x04\"+X\xc0\x17?\x12]\xa0\xf0G\xa7\xeb\xdb\xfaN\x0f\xdb\x15\xfdz\xee\x8a\xf3D\xb0\xa0\xdch[\xbfW\xf7\x8d\xb6\xf3\x92\xc1A\xe7\xde\xcf\xd1\xe7\xef8\x0f\xde\xd0\xb5\x13\xb9\xfd\xf3W\xb2\xf1\xcb\xef\xdb\xda\x1a\x9c?\x0fc\x87{\x86\x8f\x96\x86}\x1f\xb8\x9f1W\xc1\xbcM\xdd\x92\x82\x05\xaa\xa3\xa5`\xa8\xddz\x00o}\xd6\xf6\xf0f\xc5\x09\xe2kK\xc4+;\x1c\x91\x15\x0c\xa1\x84\x11+\x18B\xf3\xf4m\xa7/\x1e\xbe/\xda\xf5\xbc\x18\xbf!\xbc\x81\xc2f}\x05[\xbfEJ|\xe4<\x85\xb7m\xce\x8ft\xcd\x14\xf6f\x8b\xaf\xe7#(\x18\xda\x94\x10\xe6\xe9\xbd\xc0\xfd\x8d\xa9\x0a\xd6\xee\xe1\xc5\xe7\xe4#\x9f\xdbW\x11\xc3\x0a\xf6\xbf\x7f\xf7_\xff\xf5\xeb\x7f\xfc_x\xfb\xbb\xa7\xc6D\xc1R\xc7A\xc1r\x93\xc3v\xe6\x18\x0c\x14l\xed\x16)\x11m\x05\xe3\x93s\xc3\x1b\x00\xf7/f*\x18_\xd1%\xad\xf4\x81\xfayy\xd5[]\xaa\x95\x98O5\xe2\x17'\xc7\xa7\xcc;\x83\xf7\x9ey\xd4j\xdd\xd4\xb5tj\xe2\x9cA\xd6\x98\xb9\xb2U\xdb|k\xbc{\xdd\xb4\xc4\xd9\xf4\xcb<\xb04y\xca\xc2\xdcaWv\xe5\xcc\xc4i\xebx#\xbf\xdd\x93\xad\"\x93\xd9\x0e\x81\xa8`o\x92\xb6x\xea_\xc9\xf6_e\x05\x93\xbda\x05\xcb\xcfM\x9e2\x8fF\xa1\x8e\xceN\x89O\x9a\x93B\xb3\xeeJML\xdd%z\xe9Z\x98\x14\x9f<\x87<e\x1b+X>>\xc6cA\xc6\x83W:p*\xd2\x10\xe5z\x0eL\x96\xbb`m\x9bWd?\xb3y\xc5m\x9c\xbc\xdd\xb0~\xfe\xda\x86\xdbt\xf7\xa7[\x9e\xc9\xce\xd9\xfc{D\x15\xecu\xa7\xd3\x99\x8d\x07\x89\xb7\x0f\xae\x9f\xbf\xea\x8d[\x08\x9dp\x8a\xacG\x1a\x05\xbb\xb1%'{\xc5f\"e\xaf8\xb3\x0f\xbe\xb1j>u\x80~\xbf=\xe7\xe9-\xaf\x84*\x98\xe2\xec\xa3l\xa7s\xcf\xa7\xdbWdo\xfe\x82\xbe\xb1)\xb1\x1f\x01\x80\x1ef*\x18Y\x1e2\xa0,\xd3\x1dN\xc1\xf8\xa3\x937\x05Qp\xd3\x94\xa3<\xbe\x9es}\xd5\xf3\xe2\xf0\xe5\xd8_]\x95\xf2\xe4\xe4\x94uK\xad\x9aAF\xbb\xd5\xdb\xdf\xdf\xbf\x9f\\\xd9\xaamg\xd5\xa3\xd6\xa4\xe2\xd2\xc9\x0b\xb1A\xd7\xe4i\x1e\xeflk\xe8\x95\x9d\x1b\x97\xef-MJ\x15\x0c\xfc\x0exJE<\xecR\x85\xa2\x82=\xfc\xe6\xd0\x7f\xfc\xe3C\x0f\x7f\xeb\xd7C\xff\xf6\xb0\xa4`\x8a7\xac`\xd6\xd4\xaa\xaa\xd4D\\\x9e\x93\xd6\xa5\xd5M\xee$+Q\x8c\xdc\x84M\xdeM\x09K\x89\x13_b\xea\xb6\xa6b+\x89\xf6`\x05\x0b,\x8d+ma\xcb\xc3\x1f\xf3=\x99\xe1\xf3\x85\xde\xea\x88r=O[}\xe2\xfb\xbf\xfc\xfe\xf6#\xa7\x0e>\xe3$\xe2\xb1#{\xcf\xa9=\xd9\xdb\xc9\xee\xb6\xf9\xeb\xdf9\xb5\xd7\xd9\x80\xa8\x82\xfd~\xbb\xb3\x81\x84\xbdv8_?\xd5\x90\xb3\xf66\xba\xd1\xd6\xb6jc[[\xdbo\x10U\xb0[\xb7n\x9d\"\x0av\xc2\xb9\xa3\xed\xc8f'6\xfd\xe8H\xb63g\xef;\xf3\xb7`\x83O\xe7\xaf:xb\xb33T\xc1\x14g\xb7\x8e\x1cY\xb1j~\xce\x1b\xdb\xbf\x7f\x95\xbeq,R\xff\x11\xb8o1Q\xc1:I\x08zd\x0a\x86/;2\x8cZL\x06\x13|5\xe9\xd8\xa4.\xa4\xbbS\xad\xb3\xf9\xd0u\xea\xdb\xa5.K\xbb\xd66a\x0a\xbeN\x97&\xe1T\xc6T\xbcWH\x0d\xb9\xb2\xbdV\x0f\xfd\xab\xca\xc8o\xf0\xa2\x88f\xc2\x81\x14\xf7zj\xe8\xd7\x0f}\xeb[\x0f\xfd\xdf\xa1\x7f\x94\xe2`\xac\xb7\x84i\xb8\x07\xd1?u&\xeev%\x11\xed\xda5\x05\xeb\xda\x01\xda\x83:`\xdd\x8f\xdfJ\x99\x83Eq\xa0\x9a,\xda\x84\x15l[\x82wxytG\x91Q\xad\xa7\xd7zQ4l\xc8!\xda\xd5\xf04\xeey\x9d\xa2\x9d)\xba\xbd\xb5b3\xee\x1c\xdd>B\x82\xf3X\xc1\x1a\xb2O\x10\xdb\x13\xf4v\xe3y\xf1\xe6$3\x8a\x14\xc1\x0av\x8bd\xb8-\xbe\x93\xfd4\xee\x7fm\xcf\xc1\xa9\x8d\xab\x88\xaf\xb5!\x0a\xa6u\xe6\xdcx\x03\xdd\x96n\x05t[G|;\x17\xb8\xcf0O\xc1\xf8\x8aNA\x10\xba+\x05i\x91\xc8\xf0\x0a\xe6K\xe4\x11\x9fH{\x09\xc1]s\xa6N\x96\x86T\xa9:1\xdevkiKKK)\x8d\x0f1\xb6\x09D\xfeHP\x88\xb7\xba\xc9\xdf\x9bB\xae\xec\xc5S\x07\x061)\xb9\x06~/Ze\x86\x8f\"\x1f\xfa\xfb\xa1??\xf5\xe7\xa1\xa7\x86\xfe\xfc\xb0\xa4`\xac\xb7\x04:<s[\xaf\xa1\xee\xe4\xa9\xf9\xee3\x02\xe9\xc4\xe5N\xa3\xf9\xa7a\x83\xfd\xd63\x8a\xbfy\xc5\x9b\xac\xe2\x04\x13myt\x15,\xaa\xf5\xac\x93\x15\xecj\xce\x8a\xd7\x0f\xfe\xea6\x19:\xeeXK\xf7\xacz\x85\xc8\xd8\xafdK\xac`?qR\x01C\xdbW\xdc\xfe\x02\x93\xb3\x83\xfc\xc1(\xd8;\xe7\xcf\x9fo\xa0q\xb0\x1b\x0d\x9bW\xccwR?\xd9\xc4\x8a\x04\xbfn\x88\xd3,\xf6\x84(\x98\xd6Y\xf6U\xa4\xd0m\x1d\xf1$\x13\xe0>\xc3<\x05\xbb\xe8\x96\x11WY\x0b\xaf`\x83Iu\xa8.\x89\x88]Kr\xca\x86:_\x86\xa4`\xd3\x87\x9b2\xf1!\xd6\x96\xc6\xd3\xc9\x95}R\x1c.\x85F\xb8S%}Zh\xe4\xd7\xe7\x15\xf1\xb1;%\x05{\xe8\xbf\x87\xfech\xe8\xd7C\xbf\x93\xfe\xd4x\x13#\xf9>\xebi\xb2,\xf9\xe2i\xd6$2\xbfi\xe6<\x9a\x7f\x0e>P\xa9U\x8d\xf2\xccK\x9e<M\xee^\xb2\xe5\x09\x1f\xc9\x8fF=\xd58\xd9\x8d\x83[V9\x9fy\x07K\xd8\xc6\xcdt\xc7\xe6\xf5d\x16\xd8-\xc5ts\xce\xfcU[hpl\xad\xd4\xdb\xa2vz\x91\xfc\xf39+\xf6\x9ch\xdb(*\x18\xb9\x01@\x14\xec\xbc\xb3\x0d\xa1\xe1\x91|\xad\xb3\xf5H\xa5\xc5z\x0c\x01\x80\x1e\xe6)\x98\x10$\xb4{\x82A\xb1\x13\x16^\xc1P\xfeB\xb40\x9f$\xa6\xcd$\x83\x9e\x85\x92\x82-\x1cn\xc9\\\xd9\xac\xadre_\xb3\xd2\xf8yh\x84{\xe9\xd4\xd3\x94\xa0\x91_]d\x05\xfb\x0f\xb1=\xfe]V0\xd6[\xc2:bYa\xe5\xd1I\xd2\x1b\xe3\xab\x12q\x01r\xa7\xd2\xfcSqW\xa8\xc9\xaa\xce\xf6\x9a\x97\xd4~q2\x9d\xfe\xa4-\x0fQ\xb0\x90\x15\x81\xa3\\O^\xbeez~\x0f\x16\xa7\x1bG\xb2\x1bp\x1fL\x0c\xe7\xaf\xd8A\xfa`\xe7\x15\xd3\xcd9\x1f}:\x9f\x04\xc4p\xb7\xe9<\x85\x8e\xf6\xa8\x82\x1d\xbc\xaaQ\xb0U\xeb\x89\xf0m\xd1*\xd8\x1fi4\x0d\xed\x18\xd6\x07\x0bu&S\x1c?\xd2\xdb\xa4\xc0\xfd\x86y\x0a&2\xd28\x18jI\x08$\xd0K0\x85\\tB\xaa\xa4`\xe1\xfb&\xac\xadre\xa3\xe9)\xd7\x10\xeaz,\xe4\xca>\x20\xc6Z6\xd1\x09\xe0z~u\x91\x15\xec\xcd\xa1\xa1?\xffyh\xe8\xdfd\x05c\xbd%\xa4\x900\xd7\xb4\x0c|xZ4\x94\x91O\xc2Nd`TE\x86\x8c|r\x06\x19W\xe6\x13\xa1#\xb3)\xf6\xc7\x93\x12i\xca\x93\x813\x07\xa5`P\xf76q\xb8\x17\xedz.\x9e*~\x95\xec\xa5\xfa\x836\xd2\xa1#\x89I\x1d!;n\xe4l$j\xf6\xfa\x1bH\x9cMq*\x9b(\x9ah\x80\xf6\xd0\xe9\x15\x1b7\"\xf49\xd9\xc1(\xd8\x8a-\x88D\xbc\xb4\x0a\x86\xd6\xaf\xc0*\xf5\x9b\xec\x10\x05\xd38c\x15L\x986\x07\x01\x80.\xe6*\x98\x10h\xf7\x04H\x00\xbb?\x10\xf0\xf8\x02\xe1~\x94'$\xcfN\xa6WX\xb1u\xf1\xaem\xa9x(\xd62\xd8B\xef\xd1]\xd4\x1a\xb2s\xd5U\xdb\x80/>\xb7\x05\x9d\xce\x8d\xf7\x05P{bJ\xf1\xa6)q\x8fz:\xc5\xb9\xea\xa5>\x1f\xe9\xddl\xb0.\xae\xf6\xe6Z+\x91\xbe_}d\x05\xfb\xd7\xa1\xa1\xff\xf3\xefCCO\xc9\x0a\xa6z#\xf7\"\xe7\xb44\xcd\x9cr\x91\x94=\xb1\xd8[\x97K\x87wK\xe36x7\xc4\x89\xf7\"\x1f\x9b\xe6\xde\x9fo\xad\x20s\xf2s[\x06\xf89\xc9\xbe\xa0\xc6\x03V\xa4\xd2\xba\xd9\x89b\x1fl\x9e\x95^\xcfQ\xafgW\x9c8\xf5}\xafs\xfe\xde\x13'v\xd0\x91\xdev\xe7\x9e\x13{\x9c\xe2\xbd\xc8\xecU\x0d\xa7^w\x1e$s\xf2_\xf9\xf9\xed\x1b\x9bs\xda>\xc7r\xf3\xfd\xedG\xb0-\x95\x9e\xbd\xd9\x0d'6\xce\xbf\xaa\x99\x93\xbf\xd7\xb9\xa5a\xefZ<&\xfd\xf9\xd5\xb6l\x9c\xed\x97\xafd\xb7]E\x1f\xcd\xcf\xd9\xbb\xe7ig\xf6\xc1\x8f\xd0U2'\xbf\xa1\xad\x8dD\xbd\x14g_\xfc\x82\xde\xd8\x94\x7flT\xcatR\x01@\x83\xb9\x0a\x16\x20a0\xd2\x179)F\xc4\xc2\x8d\x15J\x13\xc4\x0bL(}2!i\xb1gj|\xc6\x998\x1a\xd0\x09\xf9~V\x7f/\xe8fl\xc9$\xab\xf8\xf6D\xbc\xc5\xfd\x9f\xaeyS\xa6\xae\xf3<\x8a\x93\xb9RP\x88vE\x0ed$M\xc9\xd8\x8f\x90\xbe_}d\x05\xfb\xfb\xff\xfa\xef\xa7\x9e\xfa\xef\xdf=\xac(\x98\xe2\x0d\x8f\xf1\x8a\x17ON^J\xa2}\x95\x19\xc5)\xf1\xc9\x194>%\xd0\xf9`b\xb7\xa7kq\xca\xe4\xe9u\xe4w\x91Vk\xdc\xc9*\xbc\xdd\xa4\xf1\x80\x06\xf2\xa7$fHq*O\x12\x8d\xd0G\xbf\x9e\x9b\x1e\xa3\xd1\xa6\x83\x1b\xf7\xae\xc8\xce\xd9HCU\xb7\x1b\xd6*\xf3\xc1~\xb3%g\xfe\xfa\x13\xf4w\x91N\xe7/\x8f\xe0\xcdO\xf0\xdeS\x1b\x9fyz#\xed\xb4\xa1[\xaf?\x9d\xbd\xf1\xbc\xf6w\x91\xb7\x1bVe\xe7l?\xb8*{#\xf9\x01d\xf6\xaf\xe6\xe3-\xee\xdc}\xba\xf9\xe9\x15{\x0ef\xe3\xe4\x0e)\xf8\xb5\x051\xce>b\x02b\x08\x1dM\\\x87\x00@\x1fs\x15,\xf6yH\x9fH\xd9&&\xeb\xe2'\xe2\xa4\x85\xaa\xf8\\\xcd\x8ce\x00`\x00\x05\x1b\x1d\xf7\x94\x82\xa1\xd2\x94\x09\xf8t\x9ddx4\x05`\x0c(\xd8\xe8\x10\x05\x8bi\x91\x98V0\x00\x885@\xc1F\x07(\x18\x00\x98\x09(\xd8\xe8\x18>\x80\xfc\xea\xc3\xa0`\x000^\x80\x82\x8d\x8ea+\xde>\xfc7\xff\xe3aX\xf1\x16\x00\xc6\x09P\xb0\xd1\xf1o\x0f\x85\xf0\xb0\x05K\xd8\x9b\x91\xb2\x01\x00\x10\x15@\xc1FIh'\xec\xab\x16\xcb\xdf\xfcO\xf8\x0d\x0c\x00\x8c\x0f\xa0`\xa3\xe4\x8f!\x12\xf6UK\xee_O\xe9\x04\x09\x03\x80q\x01\x14l\xd4\xbc\xa9\xd1\xb0\xafZ\xeaNZ\x92;\xe1\x99\xa2\x000\x1e\x80\x82E\x19\xdeR=t\xcc2\xb5\x0b$\x0c\x00\xc6\x01P\xb0(C\x14l\xe8\x80e\xdaE\xf6Y\xd4\x00\x00\x8c\x0d\xa0`Q\x86\xb7T\xfdeh\xa8\xce2\x1d$\x0c\x00\xc6\x1eP\xb0(\xc3[*\xb1\x82\x0dUZ2\xbaA\xc2\x00`\xac1Y\xc1\xda\xdd\xe2C\xe1y_u\x85\xf7\xcc\xbd\xf0\x08\x02\xde\xe2\xf9\x92H\xd8.\xcbl\x900\x00\x18k\xccU0\xbe\xe2\x18}\x80\x1f\xef\xf1\xb6w\x9f\xf4\xd4\xdd\x03\x12&+\xd8\xd06\xcbB\x900\x00\x18c\xccU0oS7U\xb0\xa6j\xf2\xa4\xbfkQ[\xb6\xdbDxK\xc5\x97\xa2\x84m\xb2,\x05\x09\x03\x80\xb1\xc5T\x05k\xf7\xf0\xe2s\xf2\xeb\xc4'\xeb\xf9\xbca\xcdc\x02\xde\xe2\xfe\x93\xa8`C\xeb,\xf9\x01\x900\x00\x18K\xccT0\xbe\xa2KZ\xe9#\x20>\x01\xfe\xd8D|D\xe8\x1d\xc2[v\xfd\xe9\xcb/\xc5\xd6\xc9\xb5\xac\x03\x09\x03\x80\xb1\xc4L\x05\xf36\xb1k\x15!$Ti\x96b\x8cM\xb0\x82\xfd?\xb9\x136\xb4\xd0\xb2!x\x0f\xc4\xf6\x00`\xc2b\xa2\x82uzx\xad\x82\x1d\xf3\\3\xb6\x8e\x15xK\xa9@:a\x7f9v\xf4\xe8Q\xdfc\x96b\x900\x00\x18;\xccS0\xbe\xa2S\x10\x84\xeeJA\x90v\xb4\xb8\xb5+\xba\xc6&X\xc1\x06i',\xc5\"R\xca\x0b\x08\x00\x80\xb1\xc1<\x05\xbb\xe8\x96!\xeb\x90\xa1A\x9f\xbb3R\x96X\x00+X?\xfaS\xc5\x97CM\x969\x9b\xb6m+u7\x05A\xc1\x00`\xac0O\xc1\x84\x20\xa1\xdd\x13\xa4W8\xef\xad\x0cD\xca\x11\x13\xf0\x96m\xfc`\xb1e\xdb_\x86\xe2\xa7\xec\xef\xbcx\xb1;8`\xb9\xe7\x88\xd4\x08\x000^\x98\xa7`\"R\x1c\xecZU\x1d\x8fE\xed\x1ex\xa0\x03Q\xb0u\x96I\x7f\xfb\xe5P\x95eW`\x00\x0f\x94\x91\xe5\xe6=\x06(\x180a0W\xc1\x84@\xbb'p\x0d\xa1\xee\x8a\xaa\xee@\x20po\xcc\xa6\xd8\x96k\x99\xb6\xc1\xb2\xeb/\x7f\xf9\xdb'\xdb\xe9\\\x0aP0\x00\x18+\xccU\xb0\x00\x09\x83U!\xb4_\x8a\x88\xdd\x133Z\x13-\xa9\x9e\x96i\xd6/\x87\xb6Y\xaa\xe9\x08\x19\x14\x0c\x00\xc6\x0as\x15\xec\x1e\x84\xb7X\xa6W\xb6_k\xb2x\xfe\xf2\xa5e\xe1E2\x95\x02\x14\x0c\x00\xc6\x0aP\xb0(\xc3[\xe6Uw\xf2\x02?\xcd\xfa'\xde\x92\xd1I\x86\x91a\x14L\xef\xad\x08\x82\x17E=\x8c\xecJ\xdf\x02\x14\x0c\x980\x80\x82E\x19~\xd3Q,`h\xe0\xc0\x03\x93,_)\xee\xba\xd7\x14\x8c\xee\x00\x05\x03&\x0c\xa0`Qf\xe0Z\xb0_\x9c\x1e2}v\xe9\xb1k\x11\xe2`\xa0`\x000*@\xc1\xa2\x8d\xf4\x1b\x03\x81\xbf\xd8\xdeu\x8d\xfe\xa2\xc8\"+\x01I\xbc\xf6\xb8e\xd2w?\xc1\x7f\xbc\xfc\xc8_?\xf2\x02\xd9\xff\xe3\xaf[\x1e\xf9\xe1\x1fH\xe2q\xcb\x83/S\xab\xf7\xbf3\xe9\x81\xef`#\xcb\xb3\x0fZ\x18\x03%\xcbM\xc6\x91b\xfb\xc2#\x96\xaf\xff\xf4\xe5G,O\xfc\x8cu*\xf1\xb3Ix\xf3]\xfc\x7f\xd2\x87\xea\x9b8\xcb_?\x82\x8fH|X\x1e\x7f\x0d'\xc8\x8e\x17nj\xcar\xf3\xa7_yA\xc9Bg\x83\x81\x82\x01\x13\x07P\xb0\xb1B\x18\x18\x18\x10\xc5L\xa3`_\xdbw\xf9\xc3\xefb)y\xfb\xc1}\x97\xf7\x11}\xfa\xe9\xdf\xfd\xf4\xf2\xfb\xdf\xfc!\xde\xf3\x95\xb7/\xbf\xffO\xd4\xea\xef\xf6]\xfe\xed?\x7f\x0f'\x9f\xf8\x905\x90\xb3P_\xb2#\xd5\xf6\xfd\xcb\xff\xf2\x00\xd9|\x93\xc9\xa3\xf4\xa2\xbe\xf6\xde\xcd\x9fY>\xbc\xf9\xde\xd7\x987-\xd4\xe1\xdb7o>\xfe\xec'\x7f\xf8\xe9\xb7\xb1N=\xb8\xef\xb7\xfb\x1e\xfc\xb1\xa6,x\x1f\x9b\x85\x1e;B\xd5\x01`\xdc\x00\x05\x1b{4\x0a\xf6\x1e~\xfdO\xdc!z\xe2\xc7\xa4\xa7\x83\xf7\xfc\x03\xd9\xf3\xe1#7o~\xe3\xb5\x9b\xb2\x15\xe1\xb7\x0fJ\xd6\x8a\x81\x92\x85Z\xc9\x8e\x14\xdb\xf7o\xde\xfc\x84n\x1e`\xf2(\x0a\xf6\xcf\xcf\xde|\xd6\xf2\xf2\xcd\x1f\xfe3\xf3\xa6\x85:|\xe2\xe6\xcd\x07>\x14\x8d\xbeAw|\x83-\xcb\x0b_\x7f\x9f-\x03(\x180\xb1\x00\x05\x1b{4\x0a&'&\x91\x91\xe4'$!\xfeP\x07\xef\xfcDV\x8d\x9b\x1f~{\x92\xb8\x8b\x8c\x03\x15\x03%\x8bd\x15b\xab\xece\x9d*\xbc\xfd\xcd\x9bO|\xef\xdb7\xbf\xf1v\xe8\x11?\xc1*\xf8/\x93\xbe\xf72\x11\xb1I\xf2\x0e\xa5,?\xfc\xc6oo\xb2e\x00\x05\x03&\x16\xa0`cOx\x05\xb3H\xfd\x1fq\x8f\xf8\xe6\x13\xff\xf2\xe1\x1f\xfe\xa0\xe8\x85\xc6`\x98\x82im\xe5\xc3\xc8y\x14.O\xfa\xf0\x81\x0f'}h\xb9\xcc\xbc\xa9(\xd8\xcd\xf7\x9e\xfd\xce\xa4g\x19\x05S\xca\xb2o\xd2\xdb\xf4U\xc9B7\x91j\x0c\x00\xe3\x05(\xd8\xd8C\xf4\xea?\x89L\xb0\x0a\xa6\x0c\x09\xbf\xf1\x82$\x0eO\xbc\xa6\x88\xc4\x03Xg\xf6\xc9\xd6\xaa\x81f\x14\xa9k+o\x94<*\xff\xf0\xbd\x7f\xa0\xff\x997\x95Q$\xe1g\x0f0\xa3H\xb5,\xef}\xe55M\x16\xba\x89Tc\x00\x18/@\xc1\xc6\x1e|\xd5\x7f\xf7\xbb\x1f^\xde\xf75V\xc1\x94\xb0\xfc\xbeI/\x7fry\xdf7q\xe2A%z\xfe\xf8\xb3\x97\xdfS\xac\x15\x03m$_\xdejl\xe5\x8d\x92G\xb2\xc3<ky\x96\xfeg\xdeT\"\xf9\xdf|\xfb\xf2\xe5\x17\x1e\xa7Q\xfb\xcb4\x92\xcf\x94\xe5\xfd\x07_`\xb2<\xf26(\x180\x91\x00\x05\x1b{\xb0\x0c|\xf2O\x93,_\x7f\x8dU\xb0\x9b/?(M\x8d\xd8\xf7\xc4\x03\x96'\xf6\xe1\xc4k_\x97g0\xbc\xf7\xb8\xe5\xc1\x17\x14k\xc5@\xc9\xc2*\x98\xc6V\xd9(y\x14\x05{\xcf\xf2\xfe\xcd\xf7i\xfc_y\x93L\xc0\xa0\xb3)\xde~\xc22\xe9\xdbd\x12\x06\xd9A\xbb[jYn\xfe\xec\x91g\xd5,\xaf=\x02\xb3)\x80\x89\x04(\xd8\xd8\xa3\x88\xc8\xbd\x02(\x180a\x88-\x05s\xb9\xf4\x92\x13\x1dP0\x00\x18+LV\xb0v\xe9\x81:\x81\x03U\x15\xd5\xc7\xf8\x08\xd6\x1fs;u\x92\x84fN\xc2\x11f]\x8d\xe3\x8e\xc3\xc6oF\x07\xf6\x10\xbd6n\x11M\x80\x82iy\x91\xe3\x1a\x99?\xc7\xe1c\x91\x089\xf0]0z\x0f\x91q\xe1\xd38\xad'\xbc\xcd\xf8\xb5\xd9\x84\xc7\\\x05\xe3+\x8e\xd1g\xb4\x06\xdd\xde\xce\xee\xce\xba\xaa\x08\x12Vd\xbf\xa2\x93$\xf4\x7f`s\xf91;\xb9\xeb\xc3\xb3\xc94\xa7\x8d\xf9\xd9\xa79D\x87\xcbN_A\xc1\xb4\\\xf1\xdb\xca\x99?\xc7\xe1c\x91\x089\xf0\x1d\xd0zV|\xbd{\x0f\x0c\xb23\x03.\xf9\xfd\xb5\xdc\x07aM\xc6\xb1\xcd&<\xe6*\x98\xb7\xa9\x9b*X\x17]\xa6\x88\x8f\xb0\xd6G\x0fW\xa2\x93\x94\xb0\xd33\xab\x91\xfb\x0c\x193\x0eKnh\x0eQ\x0e\x0a\xa6\x8f]#\x03\xe3\xf0\xb1\xc8\xd8\xefR\x7f~P(\xa7\xee\xd6\x03\x83\xea\xcc\x88\x8eH\x0a6\x9em6\xc11U\xc1\xda=\xbc\xf4\x9c|\xda\xf9\x0a\xba\xc3/\xf6\xe1R\xfb].m\x17\x0c\xc9gVO\xa8\xb0\x99\x8a\xac`\xf7\x1c\x11\xea\x1d\x91(\xc8\xc0\xddq\xb7\x07^\x16M\x05[\x16\x05\x05\x03d\xccT0\xbe\xa2\x8bY\xf1\xb6\xbf\xbb\xda\x1b\xf6\x9b\xa5\xd7\xb6U')\xa3\x9cY/q\xb6\xfa\x92\x05i\xab/\x91\x1e\x19\xc7\x95\xa3r\x8e\x04/\xfa\xd28)\x86q\xce\xc6qe=Es\xedk\xc8\xe1j\x97\xa5-\xa9\xd5fc\xc0{k\\Y\xe9\x05=F\xd9\xf4\x0f\x81\x87\x1bE\x99\xe9\x85\xd2(\xb2qe\xda\x82\x12\xba\x88\x89\x7fu\x96\xcd\xf1\xa3,\xcd!\x10_\x98i\xcb*8\x87\x8c\xca\xc0x\x18u\xdd\x04\x87\xed\xd5\xac\xcc\xd6\xad\xb3\xf2x\x03\xbf\x87\xa5\x80\xe22M\x01\xca\xe8\x01\xc81\xcbpS\x97\xa8\x85\xd4\xf1\xc0\xa2\xd6M\x83}\xab+\x936*St\xd6\x83\x9a\x8d\xa9\x10\x89u\xbe*\xd5\xd8\x00\xa5}_\"FJ\x20\xb2\xa7\xd0\x81w\x93\xef<\xb6\xe8\x0al!\xf5>!M\x93\xe8U^\xc3gE\x8e\xac\x92\x12\x07\x1d\xe6\xc9\x1f\x80\x913\xd6\x80\xb5\x0d\xaf`\xecy\xa6{F\xddW\x98\xa9`\xde&u\xcd\xee\xa0\xdb\xed\xf6\x84\x0f\x83\xb9l\x97t\x922\xf6\xb2\x81\x81B\xd2\x03\xfb\xb8\xd1\xc69\xcakf\xe0/\xba~\xff\xac\xb2\xeb\xe8z\xd9,?>\xcd\xce\xfa\xfd\xa2\xca\x0d46f-\x98\x91UR\xc4\xf5\x92\xce\\Ys\x99\xbdH\x93\x8d\x81\xec\xcd\xda]\x9e\x95v\xc1\x20\x9b\xfe!P\xcf\xac\x05\xf5\x87WsT\xc1\\\xdc\xd6\xe6\x1a\xc72,)g\xb9\xa2\xc6\xe3\xf5\x0eN+\xd4\xcd\x9c\xab\xb5\xb1\x80\xeb0*\x03\xe3a\xf4uk\x9d\xc5\x95\xe4q\x8e\xdd\x8e\x1a\x03\xbf\xfc\x07\xfe\x05y~\xbf_\x1bJ\xbe\xfe\xfcJ?\x8f\xdf[\xf9\xfcu\xdc\xd4\xdc\xa2\xc6\xc3\x8eB\xa3\x92\xb1\xa8u\xd3`\xe7\x9656.\xc1\x8d\xca\x14\x9d\xf5\xa0fc*\xd4\xffA\xd6\x8bW\xe4\x1a\xeb\xa2\xb6\xaf\x18\xaf\x92\x02\x91\xadi\xcb\xde:^\xce\xd5\x20M\xd1U\x98B\xea~B\x9a&\xd1\xab<\xcb\xe0\xa2\xcc\xda2{Z\xfd\xea\x1a\xe6\x030r\xc6\x18hl#\xf4\xc1\xd4\xf3L\xff\x8c\xba\xaf0Q\xc1:\x89b)}\xb0`\xa0\xbd:l$\xbf\xd7\xf6\xa2NR\xc1N\xbe\xd8\x0a\xc4d:\xd6\xb7\"\x07I\xba\xc8\xa9\xf6\xbc<\xf1B\xe9\xa7-\xe3H\x1f\x04\xff;\xce\x1dGd\xdb\xac\xcd\xc6\xfa\x9d\x8b\xcd\xfa\xb2\x96\x1bf\xd3=\xc4\xca\x05\xf8*\x13\x96\x90\x0b\xa8\x99{\x17\x91s\x12\x7fi\xd6:h\xcfh\x96\xf6|\xebo$W\xe4\x92]M\xa7\x00\x00\x00\x11\xe6IDAT\xe7hv\xbd20\x1eF_\xb7\xcc\"\xec\xef0\x9d\x8cb\xe0Ww\x94\xf3\xae\xd8\x9bYDm\x1d\x9f\xe1\xa3\x13[#\x0f\x0al\xdd\x18\xec\x8b\x06\xb08-X.\xfd%\x15]\xf5\xa0\xc9\xa6T\x08\x95\x93\x8eK\x91\xf14\x1a\xb6}\xa9S:\x8c\x1f\xc8Z\x83\x8f6\xd8\xd8\x87\xd8\xa230G\xd3\xff\x844\xa3H\xdd\xca\xab4r\xb83W\xcb\x11qf?\x00\x16\xc5\x19c\xa0\xb5\x8d<\x8a\x94\xda\xcc\xa8\xbc\xf7\x11\xe6)\x18_\xd1)\x08Bw\xa5\xa0\xb4\xfe@uS\x18\xfb\x97l\xbd:I\x05\xbb\xab\xa3c\x89\xa4`\xe4\x1c\x17cP\xad\xf6~\xd4\x9f\xe6\x97m\x94\xab\xdc.9pI\x17\xa6K\x9b\x8d\xc1Ngm\xd4r}F\xd9\xf4\x0e\xd1\xc7\xd5\x93\x972\xe2\xacp\xee\x20\xae\xa7\x90\x85m/e\xce}\xa9\xfe\x9c\x10:\xe1\xe3\xb3\xda5sgqKhv\xbd20\x1eF_\xb7\xccF|}\xf0h\xe7\xf3\x86~u\x15\xec\x1c7\xd0\xffn\x9f`?\xa7\xb15\xf2\xa0\xc2\xd4\x8d\xc1\xfe*\xd9\x8a\x8d\xca(\x98\xea\x81\xcd\xa6T\x08]\xc2\xc200\xa3\x15\x19\xc1\xb6\xaf\xaa`\xcd\x9c:\x8a\x8dTH\x83O\x88U0\xdd\xca\xab\xecLG\xe4F\xd3!\xa4\xfd\x00X\x14g\x8c\x81\xd6v\xc4\x0afT\xde\xfb\x08\xf3\x14\xec\xa2[&\x80\xa4G\x01\x9eq\x1b\x7f\x97\\\xb1\xbbt\x92*\xe4#mnU\x92\xd2i*8\x0e\xa1C\x0e\xd9\xabz\x95\xcbQ\x9e\x95\xa2\xe6\x15,\xd7fc\x10\xf3\xf8\xb9\xb3F\xd9\xf4\x0eq\x96\xa3\xc2B\x9d-\x91\x02\x1f\xe4+\xbe\xaf\xbep\x11\x1e\xc2!\x0d\x1d\x8e\xac\x9d\x87\xfcyK\x94\xec\xa1e`=\x8c\xban\x99\xc7Q\x87\x0dQ\x053\xf0\xab\xab`\x03\xb6s5\\Y\x0f7\xa0\xb15\xf2\xa0\xc0\xd6\x8d\x81mTF\xc1\x14\x0f\x9alJ\x85\x10ZS\x82\x8e\xa7\x87\xb9\\\x99\xf6U\x9d\xd5\xd0B\x8bD,\xa4\xee'4,\x92?\xac\xf2*5\xe4n\xf8q\xda\x07c?\x00\x16\xc5\x19c\xa0\xb5\x1d\xb1\x82\x19\x95\xf7>\xc2<\x05\x13\x82\x84vO0(\x08\x95>\xba\xebL\x85\xb1\x82m\xe5zt\x92*\xd2Gz\xee3\xedi\xba\xf59\xf4\x9c\x12\xf5W\xafr\xe5[p.}\x99\xebB\x06g7\xb2\xd3\xdc\xf5\x1co\x94M\xef\x10\x9fq\xb5\xd4\x8c8+\x9a{\x96\x82\x0bv\x96\xf4\xe7\xfa\x1a\xed\xb5\x88e\xd1r2\x88)4V0\xc6\xc3\xe8\xebF\x14\xcc.*\x98\x91_\xea\xa1\xbe\x17iX\xd4\x98\xb7r\xd1!\xdaSPm\x8d<\xa8\xb9\x98\xba1\xd8\xe9-c\xb1Q\xf5\x14L\x93\x8d\x11\xd4\xc3\x8e\xc1p\xbf\xc5`\xdb\x97:\xa3\x9d\xe0V\xb6\x0f\x16\xa1\x90\xfa\x9f\x10\xdb$\xfa\x95W\xe9\xe5\xd6\xf4\x9e[\xb0\x92\x9c\xc8\x9a\xb3\x84Aq\xc6\x18hmG\xac`F\xe5\xbd\x8f0O\xc1D\xc48X\xd5\x01\xb2\x0d7\x8a\x8c\xd4\x05\x93?\xd2\xcc\x9d\xda\xd3\xb4\xc3~\xc5\xae\xc4\x91\x87_\xe5\xcd4\x8a\xd1(\xc6\x8a\xf4\x15\xcc\x81Oo~n\x9ea6\xddC,\xcf\xea\xc3c\x09;qv\\\x0c\x94\x94\xe1\xef\xc9r\xee8I\xe6i\xa3xY\xc4\xab\xb0\xc4X\xc1\x18\x0f\xa3\xaf\x1b\xa3`F~\xf3pe\xaf\x84\xde\xf0{\xfe%\xdbq\xeeE\xea[\xb55\xf2\xa0\xc0\xd6\x8d\xc1\x9eE\"S\x8b\xf2\xa4\xbf\x86)\x98&\x1b\xa3`\x83\x8e\xc3\xe9\xf2\x20\xb2\xb7|\xd8-N\xb6}\xd3\xf0\x89\x20,'\xce\xfa3\xf3\x06\xf1\xcbV\"\xf6\x91\x0a\xa9\xff\x09\xb1M\xa2_y\x95\xb3\x9c\x83\xe3\xf2\xe8\\\x1f\xcdY\xa2\xe7\x8c1\xd0\xda2\x0a\xa6SM\x82\xd4fF\xe5\xbd\x8f0W\xc1\x84@\xbb'p\x8d\xcchm\xea\xec\xee\x0c\x17\xc9/Q\xfb]%:]0yN\xbe\x7fV\xc9\x15\xbf\xcd\xd5\x81\xce\xbal~r\x1a\x09\x99\xab3i\xc7n\xf0\x03\xbf\xdf\x8emx$t\xd0\xbbA\xbd4c\x11\xb7\xb3y'WDg[3\xd9T\xc8m\xb3\xfa\x05\xe9=\x06\xd9\xf4\x0f\x81.\xa4e\x95\x97\xa5s\xb6w\xf1hb'\xf7|\xe3!\x179C\xcb\xb9\xb4\xb2f\x9c\xd4Fr\xca\xb9\xc2\xda\xdd\xcb8\xc7[\x1dFeP<\x8c\xben\x17\xd2k\xfa\x1bm\xe7\xfa\x9f\xcf\xbbd\xe8\xb7\xdc^s(/-\xe4n\xef\xee\xb4Y\xc2\x02\xfb\xee\x90\x862\xf0\xa0\xa0\xd6M\xe3\xcc\xce\xad\xe9h]\x89\x1b\x95):\xebA\xcd\xa6\xa9\x10>\xde\xdct\xb9\x9b^\xc0\xa5\xf5!-l\xfb\xaet\xec\xde\xbd\\\xfc\x00Z\xed\x8bj\x9b\xb7r\xf5#(\xa4\xfe'\xa46\x89~\xe5Y\xce\xd9[\x9b\xfdW\xc4B\xb2g\x89\x8e3\x8d\x81\x9a\xa4s\xf2k\xe4:\xebT\x939\xcf\x8c\xca{\x1fa\xae\x82\x05H\x18\xac\x8a$\x9a\xaa+\xeaZ\xd4xE(\xd7\xd3\x8at\x92*\xca\xef\"\xb9\x9a\x17\xf1\xc6v\x81L\x99\xa1_L5\xf6\x1ajqVz\xbf\x1e\x9d\x13\x13b\xe0A\xa8Y\x92\xb6\xa4V\xa0\xbfxc\xb3)\xd8K\\\xb32\x8b\xae\x20\x83l\xfa\x87\xc0\xfd\xaf\x82\xf4\xb9%\xef\xda\xa8\xb3\xe3y\x8e\xf4\x95\xe4\xcb\xb5qey\x96-3/\xe4t\x13j\x16\xd8\x1d\x85\xf5\x0blyFeP<\x8c\xben\xb8\x83\xd08\x83Kk\x14\xc37\xfa~\x07\xb6\xa6\xdb\xf3B'@\x9c\x9dU\x86U\xac#\xd4\xd6\xa0d2j\xdd4\xce\x16\x95\x17\xce\xa0\x8d\xca\x14\x9d\xf5\xa0f\xd3T\x88\x84\xc8\x95\xfew}\xda\xb0I\x1al\xfb\xf6\xe4\xd9g\xac~U,NOa\xd6\x8c\xe5\x87FRH\xfdOHm\x12\xfd\xca\xb3|`#\xe5\xb5\xad<\x87B\xce\x92\xe1\xce4\x06j\xd2%5\x89\xd8\xf5\xd4\xa9&s\x9e\x19\x95\xf7>\xc2\\\x05\x1b1\xafr\x1f\xeb$\xc7\x03et\x06L\x00\xfa\xed\xea\xc5z\x88\x0b\xed\x9cL\x00\xae\xa7\xbdx]\x10\xfa\xce\x16\xa6G\xabp\x13\xb2\x9a\x13\x88\x18Q0\xf3\x1e\xab\x03\x0a6\x91hT\xee\xbd\x0a\xef\xce\x1a\xdf\x13ad\x1c\x92F\xb9\x82#4\xfauwL\xd0jN\x20bD\xc1\xcc\x03\x14l\xc2P\xde\x8a\xf2\xca\xe4?\xae8J\x8c\x83\x0e\xe6qV\xba\xf1y\x8e\xd3\x0d\xc0\xdf1\x13\xb4\x9a\x13\x08P\xb0\xb0\x88\x91[`\"\xd0\xcf-{)s\xa2\x8f\xa8\x04W\x9a\xab\xb1\xb5\x11o#Y\x02\xd1\x01\x14,,4r\xdb\x1b\xc9\x0a\x18\x17\xca\xd2\xf2\"<\xf8o\"pxu\xa6-sMt\xc6\x90@d@\xc1\x00\x00\x88]@\xc1\x00\x00\x88]@\xc1\x00\x00\x88]@\xc1\x00\x00\x88]@\xc1\x00\x00\x88]@\xc1\x00\x00\x88]@\xc1\x00\x00\x88]@\xc1\x00\x00\x88]bK\xc1\xcc\xfby$\x00\x00\x13\x11\x93\x15\xac\xdd\xed\xd5I\x1a\xf11\xb7S')3\xd2\x95\xd8k\x8d\x97\xebR\xd6\xe7\x02\x00\x20&0W\xc1\xf8\x8ac\x95\xc3\x93\x86\x14\xa9\xeb\xdc\x16\x0d[\xf2v\xc4+\xb1\xf7\xf9\x97\x1b\xfeZ[Z\x9f\x0b\x00\x80\xd8\xc0\\\x05\xf36uW\x0eO\x1a\xd1\xc3\x95\xe8$U\x86=J\xce\x88\x02\xe3\xe7M\x0c{\xca4\x00\x00\x13\x18S\x15\xac\xdd\xc3\xcb\xebE2IC\\j\xbf\xcb5\xbc\x0bv\x07\x80\x82\x01\xc0=\x82\x99\x0a\xc6Wt\xc9+\xde2ICzm[u\x92\x12\xba\xab\xd77\xe2}\xe5\xca:\xf5\xea\xb2\xeeX\xc1\xb6\xe2\x9dv\xb2\xca\x8c\xbar\xfc\x95\xa2\xcc\xf4B\x18E\x02@,a\xa6\x82y\x9b\x945\xbb\x99\xa4!.\xdb%\x9d\xa4\x8c\xde\xea\xf5\xfd\xfeYe\xd7\xe5u\xea\x99e\xdd\xb1\x82])\xe2j\xc8\x83\xbf\xd4\x95\xe3{f-\xa8?\xbc\x9a\x03\x05\x03\x80\x18\xc2D\x05\xeb\xf4\xf0\xb2l1ICzm/\xea$Y\x94U\xbb\x94\xd5\xeb\x91\x8b,\x97\xf0<\x99x\xc1.\xeb\x8e\x15\xac\xc6N\x9f\xe0\xc4\xac\x1c\xbfrA?Ys\x0b\x14\x0c\x00b\x08\xf3\x14\x8c\xaf\xe8\x14\x04\xa1\xbbR\x10\xd8\xa41/\xa9O\x1ad\x92,\x8a\x82\x11\xc5\x12\x03Z\xad\xf6~\xd4\x9fF\x16\xd0f\x97u/(/\xe3\xc4\x99\x17\xea\xca\xf1}t\x89!q\x8dT\x00\x00b\x04\xf3\x14\xec\xa2[&\xc0$\x0d\xcd#.y\xab\xb7r*\x12\x1c\x87\xd0!\xba:\x04\xbb\xac{\x81c\xc6\"q-+u\xe5\xf8\xb3\x1c\xd19\x88\xe4\x03@La\x9e\x82\x09AB\xbb'\x18\x14\x98\xa4\xa1\xf9Vu\x9d\xdb\xad:K\xde\x12t\x14\x0cm}\x0e=G\xa3\xfe\xec\xb2\xee\x05\x8e\x0b\xbd\xb3\xe8R\x8b\xea\xca\xf1\x9fq\xb5\xd4\x0c\x14\x0c\x00b\x08\xf3\x14L\x84\x09~\x85\x8d\x83\x8d\xa0\x0b\xa6\xab`\x1d\xf6+v\xbaT\x07\xbb\xac;\x99M\xd1l#\xbb\x99\x95\xe3\x97g\xf5!\xd4c\x97\x14\xacww\x0c<\x92\x1d\x00\xee{\xccU0!\xd0\xee\x09\\\x0bM\xeaQ\xa2\xf6\xbbJ\xf4\xba`\xfa\xab\xd7c\xb7\x99\xab3C\x96\x80\xef\xf3/w}0\xd8_\x90\xd9z\x9d]9\xfeBZVyY\xba\xb8N=Y\xec\xfdG\xc3\x0f\x02\x00\xc0\x04\xc3\\\x05\x0b\x90\xd8WUhR\x87\xebiE:I\x06\xfd\xd5\xeb15\xf6\x1a\xd1BY\xd6\xbd\x96\xd8\x9d%s\xc5\xc8\xe2\x83\xea\xca\xf1=\x05\xe9sK\xde\xb5\x89\xd9\xea\x1d\xf5:G\x01\x00`ba\xae\x82\x8d\x98W\xb9\x8fu\x92\x00\x00\xdc\xe7\xc4\x88\x82\xc1cu\x00\x00\xd0!F\x14\x0c\x00\x00@\x07P0\x00\x00b\x17P0\x00\x00b\x17P0\x00\x00b\x17P0\x00\x00b\x17P0\x00\x00b\x17P0\x00\x00b\x17P0\x00\x00b\x17P0\x00\x00b\x17P0\xf3\x18\xe8\xef\xef\x1fDh\x10\xbf\x0cD\xb2\x05\x00@\x0fP0\xd38\x16g\xb5Z\x13y>\x11\xbf\xc4\x1d\x8dd\x0d\x00\x80\x0e\xa0`c\x88wf\x10\xa1k3\x0d\xd6\"\xaf\xb6z[Z\xda\x11joi\xf1Z\xab\xf5m\x00\x00\x08\x8b\xc9\x0a\xd6\xee\xa6\x97w\xbf\x87>c\xda\x13\x8d\xc1\xd4~\xabDR\x18oMI\x06\xb2\x12\x9ek\xf9I\x89sF\xbc\xb0\xee6k1}\x89\xdb\xa6\xfbv\xb5\xb5[Nv\xdf\x81\x82\xdde\xd1G\xca\xa9\xef;Ern\x871\xca9a\xfc&\x00\x8c#\xe6*\x18_q\x8c>\x98\x95w\x9f\x09`\x82\x91\xecG\x02\x7f,>\xd7\x87\xd9`\x0d\xe3\xce\x9b8r\xc9`\x98\x9d\xec\xceM\xe4#YI\xec\x8a\xf3\x88\x09\xef\xa3\xa5z\xefGR0\xdf\xe9\xe1\xfb\xd0]\x17}\xa4\xdcj\xcb~\xa5\x0d\xb3\xc7\xf9\xb9\xb1\xd1\x89\xf9G\x8c\xdf\x04\x80q\xc4\\\x05\xf36uK\x0a\xa6\\\xccQ\x20\x81v}*\xc3)\x18\x1aqG\x8a\xe5\x9a\xb5\x14\x09#\x15\xb0\x8b\xf1\x1b\xe4\xe4\xa6\x04\xbd\xeaER\xb0\xe9\x8b\x87\xef#\xdcU\xd1\xef\x80\xec\xbdd{\xd0y#\x8cM\x98\xfe\x19\x00\x8c'\xa6*X\xbb\x87\x0f\x8c\x99\x82u\xad\x8bdw\xc7tY\xef`\x00\x97\x9b\xach\x1d\x9f\x9c\xabc\x10I\xc1R\x0d\x14l\xac\x11\x15\xec7o\x80J\x011\x80\x99\x0a\xc6Wt\xa1\x91)X\xb5\xd5j-F\xc5x[\x8d\xf8\xc5\xc9\xf1)\xf3\xce\xe0\xbdg\x1e\xb5Z7u-\x9d\x9a8gPc-*\x18&\xdf\x1a\xef^7-qvw\x88\x87D\xab5\x8e>\xd0Z\xebaWjb\xea.m6\x86\x81$1\xbc\xb6\x8e\x18\xc4U\xe2>\x96uZ\xa8m\xd7\xc2\xa4\xf8\xe49t\xc9\xb8\x81\xc9J\x17\x0cw\xc2\x12\xfb\xd10\xf4\x14\xec\xe8\xec\x94\xf8\xa49)\xb8w*\x05\xf3R\xb5\x85T\x8b\xae9ppiR\xca\xbauI\x9a\xf1e\xf7d\xc9\xc5dm=n7\xac\x9f\xbf\xb6\x81\xcaS\xdb\xe6\x15\xd9\xcfl^\x11\"U\xa2\x82a^qf\x1f|c\xd5\xfc\xcd\xbfG\xe8\x88\xd3\xe9\xdc\x8b\xf6\xe2\xed\x11tc>}\xc1|\x94\xedt\xee\xf9t\xfb\x8a\xec\xcd_0~\x99l\x000\xd6\x98\xa9`\xde&\xa4(XS\xb5\xbb\xea\xa8\xcee.\xc2\x1f\x9d\xbc)\x88\x82\x9b\xa6\x1c\xe5\xf1\xb5\x9d\xeb\xab\x9e\x17\xd7\x82P\x7fuU\xca\x93\x93S\xd6-\xb5j\xaf\xd1\x84M\xfd\xfd\x8bI\x0f\xac\xb3\xeaQkRq\xe9\xe4\x85Z\x0f\xe8\xa4\xcf'\xaa\x9c\xc6Cn\xc2&\xef\xa6\x84\xa5\x9al,g|U\xd6b\x9f\x0f\xebS\xc0\x17\x8f\xb3\xb7\xe4&\x84\xd8\xfa\x12S\xb75\x15[i\xd4\xeb\xb4\xd5\xa7f=fmA\xc3\xd0Q\xb0\x93\xd6\xa5\xd5M\xee$+\x96\xaac\xbe'3|>_gH!\x95\xa2\xb3\x07\x1e\x98\x96\xbc\xab8!\xb1b6\x1bo\x1b\xf0\x94\x8a\x84\xdc\x1f\xd9\x91\xbd\xe7\xd4\x9e\xec\xed8\xf5\xcb\xefo?r\xea\xe03\xce/4\xef\xa3\xec\x9f\xdc\xba\xb5\xe5\x0d\x9c\xf8\xe8H\xb63g\xef;\xf3\xb7\x20t\xa3m\xfeO>G\x9f\xef}\xba\x0d\x8f-\xcf\xb7\xb5\x89*w\xeb\xc8\x91\x15\xab\xe6\xe7\xbc\xb1\xfd\xfbW\x19\xbfL6\x00\x18kLT\xb0N\x0f\xaf*X\xe5\x99\xee\xce\xea*\xe3\xbb\x87\xb9dH\xb5\x98\x0c\xc6\xf8j2:K\x15\xe5%\xd5:\x1b\xff\x15\x12\x9aJ\x20=\x8fybr\x0a\xbe\xea\x97&i=\x10\x12\xe5~\x9a\xe2\xe1\x80\xf5\x00\"\xdb\xfd\xdal,\xea(\x92\xaaHq\x02\xd2\xd8\xf6\xa7\xcc\xc1\x15\x18\xa8\xa6+.y\xad\x17\xd5\x8c\xba\xa3D\x1d\x05\xdb\x95D\xfb\x82Sh\xa8\x8b\x19Ej\xaa)\x17]=p\x95\x15wIwY\xdb\x91\x86\xe0E\x11m8\xf0\x94\xf3\x94\xbcm\xc8!\xda\xd5\xf0th\x1f\x8c\xdc\x89\xdc,&\x9f\xc6\x1d\xa9\xed9$\xb9\x83h\xde\xf6\x1d\xb2\x8d\xdcO[\xeb\xdcx\x03\xdd\xbe\xa1\xf1\xcbf\x03\x80\xb1\xc5<\x05\xe3+:\x05A\xe8\xae\x14\xf0\xe5*\xb4\x93\xeeW\xbfG\xa7\xa7\"\xe1K\xe4\xf1\x10\x8avk\x82\xbb\xe6L\x9dL\x86W\x98T\xbd\x18yBnKK\xaa\xa4`D\xb1D\xa5a<\x20V\xc1d\x0f\xb9\xd3\xe8\xcb\xb4\\m6\x16}\x05Sl\xf7\x13!\x91\xa9\xd3*\x98\xce*L:\x0a\xd6\x9d<5\xdf}F\x10\x85\x9cU0\xb6\x9a\x8a\x82)\x07\xde0\x05\x0d\x0f\xd2]\x94g\x95h{\xa8;\xd6\xd2\x97U\xaf\x20t5g\xc5\xeb\x07\x7fu;4\xde\x95\xbd\xe3\xfc\xf9\xb5\x92\x82\x11\xc5\xda\x9bM\x92m\xd9\xb7\xd0\xad\xf9m\xb2\x8d\xa2`\xd9W\xc5\x04\xe3\x97\xcd\x06\x00c\x8by\x0av\xd1-\x13\x90w\x1d\xad3\xb4\x1eL\xaaCuI\xa4o\xd2\x92\x9c\xb2\xa1\xce\x97!)\xd8t\x1d[\"/\xfb\x9b\x94\xa4\xa44\xaa\x07\x82\xaa`\xb2\x87\x99\xa2\xe6\xcd\x99\xae\xcd\xc6\xa2\xaf`J\xb2\xd4\xca\x0c\x83[\xd8\x81c\x8b\xf5\x18\x1a\x86^\x1c\x8cw/\x9efM\x12\xe7\x8f\xb1\x0a\xc6VSQ0\xe6\xc0A\xd2{\x0c\xe9\x83\xf9\xbc\"\xcch\x16\xb3Q\xd4\xa6\xcd\xeb\xf1\xe6\xc6\xc1-\xab\x9c\xcf\xbc\xa3\x13\x07;\xd5\xa6$%)\xfa\xe2\xe9\x13\xe8\xc43\xb2\xa9\xaa`\xeb\xa5\x04\xeb\x97\xc9\x06\x00c\x8by\x0a&\x04\x09\xed\x9e`P@M\xa22\xf8\xc2\xdc\xea\xcb_\x88\x16\xe6\x93\xc4\xb4\x99d4\xb5PR\xb0\x90X\x15E\x8a\xe4\x9f\x09j\xa5H\xf1@P\x15L\xf6\x90;\x95\xbeL\xcdE#U\xb0M!\x0a\xd6defp\xf1\xca\xfd\x04\xf2v\xbc\xce\x1c\x0c\xbd8\x18\x89\xfe\xf3U\x89\xe4~\x82\xa8`\x15\xd4FS\xcd\xe1\x0a\xd6\x1d7\xa7\xfb\xcc\xd4\x99#\x9af\xb1\x83\x06\xeeo\xaf\xc0\xdd\xa4\xf3{p\xf2\xc6\x91\xec\x06\xad\x85\xa4N\x1f\xdd\xd0J\xd1\xeb[\xd0\x96\xd7Cl\xb0\x82m\x91\x12\x8c_P0`\xfc0O\xc1D\xc48\x98\x97v\xbe\xaey\x98QX(-\x09\x81\x04\xda\xabI!W\xb3\x90*)\x98\xde\x8c\x03I;\x927h\xa5H\xf1@P\x15L\xf6\xe0\xa5#\xbd**R\x11\x15,\x11\xfb\x16\xa6\x87(\x18\x9f\x9cA\xc6\x7f\xf9\xe24\x8e\xc5S\x15E\x11\xa6\xcdA\xc3\xd1Q\xb0b\x1a\x8bC\x19Th32\xf0\x88Y|CS\xcd\xe1\x0av\xda\x9ad\xb5f(]\xd9\xb0\x9c\xa2\xb7\x11\x8f\x90x\xd5^\x1a\xb4B\x1b_\xa1oto\x93\x86\xbd\x92:\xe5\xec\xd1J\xd1/\xb2\xaff\xffB\xf62\\\xc1\x18\xbf\xa0`\xc0\xf8a\xae\x82\x09\x81vO\xe0\x1a\xbez\xdc\x07\xba\xbaOVx\xc3\xf4\"\x84\xe4\xd9\xc9\xf4\xedb\xeb\xe2]\xdbR\xf1P\xabe\xb0\x85\xde\xafc\xe2M\x04yN\xbeo\xf2\xba\x80/>\xb7\x05\x9d\xce\x8d'7\x10U\x0f\x03->_B\xae\xef(\x8f4\x1e\x96\xc6m\xf0n\x88[Jo52\xd9\x14\xc4{\x91-\xd4\xc5\xcc\xa4m\xdbfZ\x1f\xf5tjl}\x8fMs\xef\xcf\xb7VP\xf3\xae8\xe5\xce`\xa9Uoz\xbd\xae\x82%\x16{\xebr\xc5\xdb\x98\xc5\x09\xa5u\xb3\x13\xbb5\x85T\x8b\xce\x1e\xf8tB\x93\xd7\x17\x18Q\x17\x0c\xa1\xed\xce='\xf68I\\~\xafs\xfe\xde\x13'v8\xc5\x11\xe3<+\x95YyN~\xdb\xfc7\xae\xe2\xe4\xcfo\xff\xf2\x95\xec6\x12\xeb\xba\x9d\xb3Y\xfc\xa1\xd1\xed\x9f\xb7Q\x9b\x1b\xe8\x8b_\xb4\xad\xda\xd8\xd6\xf6\xa9\xd6\xaf6\x1b\x00\x8c)\xe6*X\x80\x84\xc1H\xd7'\xd8T\xe5\xf1\xb6\x87\xbd\x06K\x13DE\x10J\x9fLHZ\xec\x99\x1a\x9fq&\x8e\x06\xaaC\xfa7\xca\xef\"\xad\xa5\xf9x\x13\xdfN\x9e\xfd\x90\xcfz8)\xe6\xb3\xba\x91\xc6\x83@\xe7\x83\x09d\xaa\x95&\x9b\xc4\xc0\x14j\xfbh'\xf9\xa3+#q\xf2\xec\x0d\xd8@k\xdb\xb58e\xf2t9\x98\xb7\xe91)\xf8u4Qwrm\xb5\xb5K~\xbaN\x97\xa4`\x95\x19\xc5)\xf1\xc9\x19b\xe4j\x20\x7fJb\x06\xee4\xb2\x85T\x8b\xce\x1e\xf8X<\xd9\x17\x9f\x11\x12\x08\xd3\xe7v\xc3Zi>\xd8\xc1\x8d{Wd\xe7l\x94\xa2\xf3\x9e$7y9\xe5\x94ix\x05o\xb2\x7fEf\x7f\xd1^Z\x834\xdc\xfc\xa5\xf4\xfeA\xf4\x91\x98\xd8\xac\xf5\x1b\x92\x0d\x00\xc6\x12s\x15\xec\xdef]<\xd5\xa5\xaa\xf8\\\xed\x8c[\x09:iUz\xba\x0e\x9d\xc3q\xb7\x04\x13\xf3\x83\x83\x83\xfc\xc9\x85SF\xfa\x8b'\x00\xb8W\x00\x05\x1bCJS\xc8\xd3u\x92\xf5\x1fM\x81\x06\xcf\xb4\xc8O\xd7i9\xa3\xabq#\xa4N\x9c?\x86\x84\xa4\xd1\xe8\x20\x00\xc4\"\xa0`\xb1\xcf\xe98q\xf8\xd8\x1e\x17\xe6N\x08\x00\xdc\x93\x80\x82\xc5>Bnb~\x95\xaf*?Q\xef\xf7\xe3\x00pO\x03\x0av/\xe0\x9d\x9d\x1c\x9f<\xe7\x0e\x1e\x9c\x01\x00\xf7\x08\xa0`\x00\x00\xc4.\xa0`\x00\x00\xc4.CC\xff\x1f\xf8\xaa\xf0z\xf7O\xc9\x8f\x00\x00\x00\x00IEND\xaeB`\x82",
 
-	"analysis/help.html": "<!--{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\"Title\":\x20\"Static\x20analysis\x20features\x20of\x20godoc\"\x0a}-->\x0a\x0a<style>\x0a\x20\x20span.err\x20{\x20'font-size:120%;\x20color:darkred;\x20background-color:\x20yellow;\x20}\x0a\x20\x20img.ss\x20{\x20margin-left:\x201in;\x20}\x20/*\x20screenshot\x20*/\x0a\x20\x20img.dotted\x20{\x20border:\x20thin\x20dotted;\x20}\x0a</style>\x0a\x0a<!--\x20Images\x20were\x20grabbed\x20from\x20Chrome/Linux\x20at\x20150%\x20zoom,\x20and\x20are\x0a\x20\x20\x20\x20\x20displayed\x20at\x2066%\x20of\x20natural\x20size.\x20\x20This\x20allows\x20users\x20to\x20zoom\x20a\x0a\x20\x20\x20\x20\x20little\x20before\x20seeing\x20pixels.\x20-->\x0a\x0a<p>\x0a\x20\x20When\x20invoked\x20with\x20the\x20<code>-analysis</code>\x20flag,\x20godoc\x20performs\x0a\x20\x20static\x20analysis\x20on\x20the\x20Go\x20packages\x20it\x20indexes\x20and\x20displays\x20the\x0a\x20\x20results\x20in\x20the\x20source\x20and\x20package\x20views.\x20\x20This\x20document\x20provides\x20a\x0a\x20\x20brief\x20tour\x20of\x20these\x20features.\x0a</p>\x0a\x0a<h2>Type\x20analysis\x20features</h2>\x0a<p>\x0a\x20\x20<code>godoc\x20-analysis=type</code>\x20performs\x20static\x20checking\x20similar\x0a\x20\x20to\x20that\x20done\x20by\x20a\x20compiler:\x20it\x20detects\x20ill-formed\x20programs,\x20resolves\x0a\x20\x20each\x20identifier\x20to\x20the\x20entity\x20it\x20denotes,\x20computes\x20the\x20type\x20of\x20each\x0a\x20\x20expression\x20and\x20the\x20method\x20set\x20of\x20each\x20type,\x20and\x20determines\x20which\x0a\x20\x20types\x20are\x20assignable\x20to\x20each\x20interface\x20type.\x0a\x0a\x20\x20<b>Type\x20analysis</b>\x20is\x20relatively\x20quick,\x20requiring\x20about\x2010\x20seconds\x20for\x0a\x20\x20the\x20&gt;200\x20packages\x20of\x20the\x20standard\x20library,\x20for\x20example.\x0a</p>\x0a\x0a<h3>Compiler\x20errors</h3>\x0a<p>\x0a\x20\x20If\x20any\x20source\x20file\x20contains\x20a\x20compilation\x20error,\x20the\x20source\x20view\x0a\x20\x20will\x20highlight\x20the\x20errant\x20location\x20in\x20red.\x20\x20Hovering\x20over\x20it\x0a\x20\x20displays\x20the\x20error\x20message.\x0a</p>\x0a<img\x20class=\"ss\"\x20width='811'\x20src='error1.png'><br/>\x0a\x0a<h3>Identifier\x20resolution</h3>\x0a<p>\x0a\x20\x20In\x20the\x20source\x20view,\x20every\x20referring\x20identifier\x20is\x20annotated\x20with\x0a\x20\x20information\x20about\x20the\x20language\x20entity\x20it\x20refers\x20to:\x20a\x20package,\x0a\x20\x20constant,\x20variable,\x20type,\x20function\x20or\x20statement\x20label.\x0a\x0a\x20\x20Hovering\x20over\x20the\x20identifier\x20reveals\x20the\x20entity's\x20kind\x20and\x20type\x0a\x20\x20(e.g.\x20<code>var\x20x\x20int</code>\x20or\x20<code>func\x20f\x0a\x20\x20func(int)\x20string</code>).\x0a</p>\x0a<img\x20class=\"ss\"\x20width='652'\x20src='ident-field.png'><br/>\x0a<br/>\x0a<img\x20class=\"ss\"\x20width='652'\x20src='ident-func.png'>\x0a<p>\x0a\x20\x20Clicking\x20the\x20link\x20takes\x20you\x20to\x20the\x20entity's\x20definition.\x0a</p>\x0a<img\x20class=\"ss\"\x20width='652'\x20src='ident-def.png'><br/>\x0a\x0a<h3>Type\x20information:\x20size/alignment,\x20method\x20set,\x20interfaces</h3>\x0a<p>\x0a\x20\x20Clicking\x20on\x20the\x20identifier\x20that\x20defines\x20a\x20named\x20type\x20causes\x20a\x20panel\x0a\x20\x20to\x20appear,\x20displaying\x20information\x20about\x20the\x20named\x20type,\x20including\x0a\x20\x20its\x20size\x20and\x20alignment\x20in\x20bytes,\x20its\x0a\x20\x20<a\x20href='http://golang.org/ref/spec#Method_sets'>method\x20set</a>,\x20and\x20its\x0a\x20\x20<i>implements</i>\x20relation:\x20the\x20set\x20of\x20types\x20T\x20that\x20are\x20assignable\x20to\x0a\x20\x20or\x20from\x20this\x20type\x20U\x20where\x20at\x20least\x20one\x20of\x20T\x20or\x20U\x20is\x20an\x20interface.\x0a\x0a\x20\x20This\x20example\x20shows\x20information\x20about\x20<code>net/rpc.methodType</code>.\x0a</p>\x0a<img\x20class=\"ss\"\x20width='470'\x20src='typeinfo-src.png'>\x0a<p>\x0a\x20\x20The\x20method\x20set\x20includes\x20not\x20only\x20the\x20declared\x20methods\x20of\x20the\x20type,\x0a\x20\x20but\x20also\x20any\x20methods\x20\"promoted\"\x20from\x20anonymous\x20fields\x20of\x20structs,\x0a\x20\x20such\x20as\x20<code>sync.Mutex</code>\x20in\x20this\x20example.\x0a\x0a\x20\x20In\x20addition,\x20the\x20receiver\x20type\x20is\x20displayed\x20as\x20<code>*T</code>\x20or\x0a\x20\x20<code>T</code>\x20depending\x20on\x20whether\x20it\x20requires\x20the\x20address\x20or\x20just\x0a\x20\x20a\x20copy\x20of\x20the\x20receiver\x20value.\x0a</p>\x0a<p>\x0a\x20\x20The\x20method\x20set\x20and\x20<i>implements</i>\x20relation\x20are\x20also\x20available\x0a\x20\x20via\x20the\x20package\x20view.\x0a</p>\x0a<img\x20class=\"ss\x20dotted\"\x20width='716'\x20src='typeinfo-pkg.png'>\x0a\x0a<h2>Pointer\x20analysis\x20features</h2>\x0a<p>\x0a\x20\x20<code>godoc\x20-analysis=pointer</code>\x20additionally\x20performs\x20a\x20precise\x0a\x20\x20whole-program\x20<b>pointer\x20analysis</b>.\x20\x20In\x20other\x20words,\x20it\x0a\x20\x20approximates\x20the\x20set\x20of\x20memory\x20locations\x20to\x20which\x20each\x0a\x20\x20reference&mdash;not\x20just\x20vars\x20of\x20kind\x20<code>*T</code>,\x20but\x20also\x0a\x20\x20<code>[]T</code>,\x20<code>func</code>,\x20<code>map</code>,\x0a\x20\x20<code>chan</code>,\x20and\x20<code>interface</code>&mdash;may\x20refer.\x20\x20This\x0a\x20\x20information\x20reveals\x20the\x20possible\x20destinations\x20of\x20each\x20dynamic\x20call\x0a\x20\x20(via\x20a\x20<code>func</code>\x20variable\x20or\x20interface\x20method),\x20and\x20the\x0a\x20\x20relationship\x20between\x20send\x20and\x20receive\x20operations\x20on\x20the\x20same\x0a\x20\x20channel.\x0a</p>\x0a<p>\x0a\x20\x20Compared\x20to\x20type\x20analysis,\x20pointer\x20analysis\x20requires\x20more\x20time\x20and\x0a\x20\x20memory,\x20and\x20is\x20impractical\x20for\x20code\x20bases\x20exceeding\x20a\x20million\x20lines.\x0a</p>\x0a\x0a<h3>Call\x20graph\x20navigation</h3>\x0a<p>\x0a\x20\x20When\x20pointer\x20analysis\x20is\x20complete,\x20the\x20source\x20view\x20annotates\x20the\x0a\x20\x20code\x20with\x20<b>callers</b>\x20and\x20<b>callees</b>\x20information:\x20callers\x0a\x20\x20information\x20is\x20associated\x20with\x20the\x20<code>func</code>\x20keyword\x20that\x0a\x20\x20declares\x20a\x20function,\x20and\x20callees\x20information\x20is\x20associated\x20with\x20the\x0a\x20\x20open\x20paren\x20'<span\x20style=\"color:\x20dark-blue\"><code>(</code></span>'\x20of\x0a\x20\x20a\x20function\x20call.\x0a</p>\x0a<p>\x0a\x20\x20In\x20this\x20example,\x20hovering\x20over\x20the\x20declaration\x20of\x20the\x0a\x20\x20<code>rot13</code>\x20function\x20(defined\x20in\x20strings/strings_test.go)\x0a\x20\x20reveals\x20that\x20it\x20is\x20called\x20in\x20exactly\x20one\x20place.\x0a</p>\x0a<img\x20class=\"ss\"\x20width='612'\x20src='callers1.png'>\x0a<p>\x0a\x20\x20Clicking\x20the\x20link\x20navigates\x20to\x20the\x20sole\x20caller.\x20\x20(If\x20there\x20were\x0a\x20\x20multiple\x20callers,\x20a\x20list\x20of\x20choices\x20would\x20be\x20displayed\x20first.)\x0a</p>\x0a<img\x20class=\"ss\"\x20width='680'\x20src='callers2.png'>\x0a<p>\x0a\x20\x20Notice\x20that\x20hovering\x20over\x20this\x20call\x20reveals\x20that\x20there\x20are\x2019\x0a\x20\x20possible\x20callees\x20at\x20this\x20site,\x20of\x20which\x20our\x20<code>rot13</code>\x0a\x20\x20function\x20was\x20just\x20one:\x20this\x20is\x20a\x20dynamic\x20call\x20through\x20a\x20variable\x20of\x0a\x20\x20type\x20<code>func(rune)\x20rune</code>.\x0a\x0a\x20\x20Clicking\x20on\x20the\x20call\x20brings\x20up\x20the\x20list\x20of\x20all\x2019\x20potential\x20callees,\x0a\x20\x20shown\x20truncated.\x20\x20Many\x20of\x20them\x20are\x20anonymous\x20functions.\x0a</p>\x0a<img\x20class=\"ss\"\x20width='564'\x20src='call3.png'>\x0a<p>\x0a\x20\x20Pointer\x20analysis\x20gives\x20a\x20very\x20precise\x20approximation\x20of\x20the\x20call\x0a\x20\x20graph\x20compared\x20to\x20type-based\x20techniques.\x0a\x0a\x20\x20As\x20a\x20case\x20in\x20point,\x20the\x20next\x20example\x20shows\x20the\x20dynamic\x20call\x20inside\x0a\x20\x20the\x20<code>testing</code>\x20package\x20responsible\x20for\x20calling\x20all\x0a\x20\x20user-defined\x20functions\x20named\x20<code>Example<i>XYZ</i></code>.\x0a</p>\x0a<img\x20class=\"ss\"\x20width='361'\x20src='call-eg.png'>\x0a<p>\x0a\x20\x20Recall\x20that\x20all\x20such\x20functions\x20have\x20type\x20<code>func()</code>,\x0a\x20\x20i.e.\x20no\x20arguments\x20and\x20no\x20results.\x20\x20A\x20type-based\x20approximation\x20could\x0a\x20\x20only\x20conclude\x20that\x20this\x20call\x20might\x20dispatch\x20to\x20any\x20function\x20matching\x0a\x20\x20that\x20type&mdash;and\x20these\x20are\x20very\x20numerous\x20in\x20most\x0a\x20\x20programs&mdash;but\x20pointer\x20analysis\x20can\x20track\x20the\x20flow\x20of\x20specific\x0a\x20\x20<code>func</code>\x20values\x20through\x20the\x20testing\x20package.\x0a\x0a\x20\x20As\x20an\x20indication\x20of\x20its\x20precision,\x20the\x20result\x20contains\x20only\x0a\x20\x20functions\x20whose\x20name\x20starts\x20with\x20<code>Example</code>.\x0a</p>\x0a\x0a<h3>Intra-package\x20call\x20graph</h3>\x0a<p>\x0a\x20\x20The\x20same\x20call\x20graph\x20information\x20is\x20presented\x20in\x20a\x20very\x20different\x20way\x0a\x20\x20in\x20the\x20package\x20view.\x20\x20For\x20each\x20package,\x20an\x20interactive\x20tree\x20view\x0a\x20\x20allows\x20exploration\x20of\x20the\x20call\x20graph\x20as\x20it\x20relates\x20to\x20just\x20that\x0a\x20\x20package;\x20all\x20functions\x20from\x20other\x20packages\x20are\x20elided.\x0a\x0a\x20\x20The\x20roots\x20of\x20the\x20tree\x20are\x20the\x20external\x20entry\x20points\x20of\x20the\x20package:\x0a\x20\x20not\x20only\x20its\x20exported\x20functions,\x20but\x20also\x20any\x20unexported\x20or\x0a\x20\x20anonymous\x20functions\x20that\x20are\x20called\x20(dynamically)\x20from\x20outside\x20the\x0a\x20\x20package.\x0a</p>\x0a<p>\x0a\x20\x20This\x20example\x20shows\x20the\x20entry\x20points\x20of\x20the\x0a\x20\x20<code>path/filepath</code>\x20package,\x20with\x20the\x20call\x20graph\x20for\x0a\x20\x20<code>Glob</code>\x20expanded\x20several\x20levels\x0a</p>\x0a<img\x20class=\"ss\x20dotted\"\x20width='501'\x20src='ipcg-pkg.png'>\x0a<p>\x0a\x20\x20Notice\x20that\x20the\x20nodes\x20for\x20Glob\x20and\x20Join\x20appear\x20multiple\x20times:\x20the\x0a\x20\x20tree\x20is\x20a\x20partial\x20unrolling\x20of\x20a\x20cyclic\x20graph;\x20the\x20full\x20unrolling\x0a\x20\x20is\x20in\x20general\x20infinite.\x0a</p>\x0a<p>\x0a\x20\x20For\x20each\x20function\x20documented\x20in\x20the\x20package\x20view,\x20another\x0a\x20\x20interactive\x20tree\x20view\x20allows\x20exploration\x20of\x20the\x20same\x20graph\x20starting\x0a\x20\x20at\x20that\x20function.\x0a\x0a\x20\x20This\x20is\x20a\x20portion\x20of\x20the\x20internal\x20graph\x20of\x0a\x20\x20<code>net/http.ListenAndServe</code>.\x0a</p>\x0a<img\x20class=\"ss\x20dotted\"\x20width='455'\x20src='ipcg-func.png'>\x0a\x0a<h3>Channel\x20peers\x20(send\x20\xe2\x86\x94\x20receive)</h3>\x0a<p>\x0a\x20\x20Because\x20concurrent\x20Go\x20programs\x20use\x20channels\x20to\x20pass\x20not\x20just\x20values\x0a\x20\x20but\x20also\x20control\x20between\x20different\x20goroutines,\x20it\x20is\x20natural\x20when\x0a\x20\x20reading\x20Go\x20code\x20to\x20want\x20to\x20navigate\x20from\x20a\x20channel\x20send\x20to\x20the\x0a\x20\x20corresponding\x20receive\x20so\x20as\x20to\x20understand\x20the\x20sequence\x20of\x20events.\x0a</p>\x0a<p>\x0a\x20\x20Godoc\x20annotates\x20every\x20channel\x20operation&mdash;make,\x20send,\x20range,\x0a\x20\x20receive,\x20close&mdash;with\x20a\x20link\x20to\x20a\x20panel\x20displaying\x20information\x0a\x20\x20about\x20other\x20operations\x20that\x20might\x20alias\x20the\x20same\x20channel.\x0a</p>\x0a<p>\x0a\x20\x20This\x20example,\x20from\x20the\x20tests\x20of\x20<code>net/http</code>,\x20shows\x20a\x20send\x0a\x20\x20operation\x20on\x20a\x20<code>chan\x20bool</code>.\x0a</p>\x0a<img\x20class=\"ss\"\x20width='811'\x20src='chan1.png'>\x0a<p>\x0a\x20\x20Clicking\x20on\x20the\x20<code>&lt;-</code>\x20send\x20operator\x20reveals\x20that\x20this\x0a\x20\x20channel\x20is\x20made\x20at\x20a\x20unique\x20location\x20(line\x20332)\x20and\x20that\x20there\x20are\x0a\x20\x20three\x20receive\x20operations\x20that\x20might\x20read\x20this\x20value.\x0a\x0a\x20\x20It\x20hardly\x20needs\x20pointing\x20out\x20that\x20some\x20channel\x20element\x20types\x20are\x0a\x20\x20very\x20widely\x20used\x20(e.g.\x20struct{},\x20bool,\x20int,\x20interface{})\x20and\x20that\x20a\x0a\x20\x20typical\x20Go\x20program\x20might\x20contain\x20dozens\x20of\x20receive\x20operations\x20on\x20a\x0a\x20\x20value\x20of\x20type\x20<code>chan\x20bool</code>;\x20yet\x20the\x20pointer\x20analysis\x20is\x0a\x20\x20able\x20to\x20distinguish\x20operations\x20on\x20channels\x20at\x20a\x20much\x20finer\x20precision\x0a\x20\x20than\x20based\x20on\x20their\x20type\x20alone.\x0a</p>\x0a<p>\x0a\x20\x20Notice\x20also\x20that\x20the\x20send\x20occurs\x20in\x20a\x20different\x20(anonymous)\x20function\x0a\x20\x20from\x20the\x20outer\x20one\x20containing\x20the\x20<code>make</code>\x20and\x20the\x20receive\x0a\x20\x20operations.\x0a</p>\x0a<p>\x0a\x20\x20Here's\x20another\x20example\x20of\x20send\x20on\x20a\x20different\x20<code>chan\x0a\x20\x20bool</code>,\x20also\x20in\x20package\x20<code>net/http</code>:\x0a</p>\x0a<img\x20class=\"ss\"\x20width='774'\x20src='chan2a.png'>\x0a<p>\x0a\x20\x20The\x20analysis\x20finds\x20just\x20one\x20receive\x20operation\x20that\x20might\x20receive\x0a\x20\x20from\x20this\x20channel,\x20in\x20the\x20test\x20for\x20this\x20feature.\x0a</p>\x0a<img\x20class=\"ss\"\x20width='737'\x20src='chan2b.png'>\x0a\x0a<h2>Known\x20issues</h2>\x0a<p>\x0a\x20\x20All\x20analysis\x20results\x20pertain\x20to\x20exactly\x0a\x20\x20one\x20configuration\x20(e.g.\x20amd64\x20linux).\x20\x20Files\x20that\x20are\x20conditionally\x0a\x20\x20compiled\x20based\x20on\x20different\x20platforms\x20or\x20build\x20tags\x20are\x20not\x20visible\x0a\x20\x20to\x20the\x20analysis.\x0a</p>\x0a<p>\x0a\x20\x20Files\x20that\x20<code>import\x20\"C\"</code>\x20require\x0a\x20\x20preprocessing\x20by\x20the\x20cgo\x20tool.\x20\x20The\x20file\x20offsets\x20after\x20preprocessing\x0a\x20\x20do\x20not\x20align\x20with\x20the\x20unpreprocessed\x20file,\x20so\x20markup\x20is\x20misaligned.\x0a</p>\x0a<p>\x0a\x20\x20Files\x20are\x20not\x20periodically\x20re-analyzed.\x0a\x20\x20If\x20the\x20files\x20change\x20underneath\x20the\x20running\x20server,\x20the\x20displayed\x0a\x20\x20markup\x20is\x20misaligned.\x0a</p>\x0a<p>\x0a\x20\x20Additional\x20issues\x20are\x20listed\x20at\x0a\x20\x20<a\x20href='https://go.googlesource.com/tools/+/master/godoc/analysis/README'>tools/godoc/analysis/README</a>.\x0a</p>\x0a",
+	"analysis/help.html": "<!--{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\"Title\":\x20\"Static\x20analysis\x20features\x20of\x20godoc\"\x0a}-->\x0a\x0a<style>\x0a\x20\x20span.err\x20{\x20'font-size:120%;\x20color:darkred;\x20background-color:\x20yellow;\x20}\x0a\x20\x20img.ss\x20{\x20margin-left:\x201in;\x20}\x20/*\x20screenshot\x20*/\x0a\x20\x20img.dotted\x20{\x20border:\x20thin\x20dotted;\x20}\x0a</style>\x0a\x0a<!--\x20Images\x20were\x20grabbed\x20from\x20Chrome/Linux\x20at\x20150%\x20zoom,\x20and\x20are\x0a\x20\x20\x20\x20\x20displayed\x20at\x2066%\x20of\x20natural\x20size.\x20\x20This\x20allows\x20users\x20to\x20zoom\x20a\x0a\x20\x20\x20\x20\x20little\x20before\x20seeing\x20pixels.\x20-->\x0a\x0a<p>\x0a\x20\x20When\x20invoked\x20with\x20the\x20<code>-analysis</code>\x20flag,\x20godoc\x20performs\x0a\x20\x20static\x20analysis\x20on\x20the\x20Go\x20packages\x20it\x20indexes\x20and\x20displays\x20the\x0a\x20\x20results\x20in\x20the\x20source\x20and\x20package\x20views.\x20\x20This\x20document\x20provides\x20a\x0a\x20\x20brief\x20tour\x20of\x20these\x20features.\x0a</p>\x0a\x0a<h2>Type\x20analysis\x20features</h2>\x0a<p>\x0a\x20\x20<code>godoc\x20-analysis=type</code>\x20performs\x20static\x20checking\x20similar\x0a\x20\x20to\x20that\x20done\x20by\x20a\x20compiler:\x20it\x20detects\x20ill-formed\x20programs,\x20resolves\x0a\x20\x20each\x20identifier\x20to\x20the\x20entity\x20it\x20denotes,\x20computes\x20the\x20type\x20of\x20each\x0a\x20\x20expression\x20and\x20the\x20method\x20set\x20of\x20each\x20type,\x20and\x20determines\x20which\x0a\x20\x20types\x20are\x20assignable\x20to\x20each\x20interface\x20type.\x0a\x0a\x20\x20<b>Type\x20analysis</b>\x20is\x20relatively\x20quick,\x20requiring\x20about\x2010\x20seconds\x20for\x0a\x20\x20the\x20&gt;200\x20packages\x20of\x20the\x20standard\x20library,\x20for\x20example.\x0a</p>\x0a\x0a<h3>Compiler\x20errors</h3>\x0a<p>\x0a\x20\x20If\x20any\x20source\x20file\x20contains\x20a\x20compilation\x20error,\x20the\x20source\x20view\x0a\x20\x20will\x20highlight\x20the\x20errant\x20location\x20in\x20red.\x20\x20Hovering\x20over\x20it\x0a\x20\x20displays\x20the\x20error\x20message.\x0a</p>\x0a<img\x20class=\"ss\"\x20width='811'\x20src='error1.png'><br/>\x0a\x0a<h3>Identifier\x20resolution</h3>\x0a<p>\x0a\x20\x20In\x20the\x20source\x20view,\x20every\x20referring\x20identifier\x20is\x20annotated\x20with\x0a\x20\x20information\x20about\x20the\x20language\x20entity\x20it\x20refers\x20to:\x20a\x20package,\x0a\x20\x20constant,\x20variable,\x20type,\x20function\x20or\x20statement\x20label.\x0a\x0a\x20\x20Hovering\x20over\x20the\x20identifier\x20reveals\x20the\x20entity's\x20kind\x20and\x20type\x0a\x20\x20(e.g.\x20<code>var\x20x\x20int</code>\x20or\x20<code>func\x20f\x0a\x20\x20func(int)\x20string</code>).\x0a</p>\x0a<img\x20class=\"ss\"\x20width='652'\x20src='ident-field.png'><br/>\x0a<br/>\x0a<img\x20class=\"ss\"\x20width='652'\x20src='ident-func.png'>\x0a<p>\x0a\x20\x20Clicking\x20the\x20link\x20takes\x20you\x20to\x20the\x20entity's\x20definition.\x0a</p>\x0a<img\x20class=\"ss\"\x20width='652'\x20src='ident-def.png'><br/>\x0a\x0a<h3>Type\x20information:\x20size/alignment,\x20method\x20set,\x20interfaces</h3>\x0a<p>\x0a\x20\x20Clicking\x20on\x20the\x20identifier\x20that\x20defines\x20a\x20named\x20type\x20causes\x20a\x20panel\x0a\x20\x20to\x20appear,\x20displaying\x20information\x20about\x20the\x20named\x20type,\x20including\x0a\x20\x20its\x20size\x20and\x20alignment\x20in\x20bytes,\x20its\x0a\x20\x20<a\x20href='https://golang.org/ref/spec#Method_sets'>method\x20set</a>,\x20and\x20its\x0a\x20\x20<i>implements</i>\x20relation:\x20the\x20set\x20of\x20types\x20T\x20that\x20are\x20assignable\x20to\x0a\x20\x20or\x20from\x20this\x20type\x20U\x20where\x20at\x20least\x20one\x20of\x20T\x20or\x20U\x20is\x20an\x20interface.\x0a\x0a\x20\x20This\x20example\x20shows\x20information\x20about\x20<code>net/rpc.methodType</code>.\x0a</p>\x0a<img\x20class=\"ss\"\x20width='470'\x20src='typeinfo-src.png'>\x0a<p>\x0a\x20\x20The\x20method\x20set\x20includes\x20not\x20only\x20the\x20declared\x20methods\x20of\x20the\x20type,\x0a\x20\x20but\x20also\x20any\x20methods\x20\"promoted\"\x20from\x20anonymous\x20fields\x20of\x20structs,\x0a\x20\x20such\x20as\x20<code>sync.Mutex</code>\x20in\x20this\x20example.\x0a\x0a\x20\x20In\x20addition,\x20the\x20receiver\x20type\x20is\x20displayed\x20as\x20<code>*T</code>\x20or\x0a\x20\x20<code>T</code>\x20depending\x20on\x20whether\x20it\x20requires\x20the\x20address\x20or\x20just\x0a\x20\x20a\x20copy\x20of\x20the\x20receiver\x20value.\x0a</p>\x0a<p>\x0a\x20\x20The\x20method\x20set\x20and\x20<i>implements</i>\x20relation\x20are\x20also\x20available\x0a\x20\x20via\x20the\x20package\x20view.\x0a</p>\x0a<img\x20class=\"ss\x20dotted\"\x20width='716'\x20src='typeinfo-pkg.png'>\x0a\x0a<h2>Pointer\x20analysis\x20features</h2>\x0a<p>\x0a\x20\x20<code>godoc\x20-analysis=pointer</code>\x20additionally\x20performs\x20a\x20precise\x0a\x20\x20whole-program\x20<b>pointer\x20analysis</b>.\x20\x20In\x20other\x20words,\x20it\x0a\x20\x20approximates\x20the\x20set\x20of\x20memory\x20locations\x20to\x20which\x20each\x0a\x20\x20reference&mdash;not\x20just\x20vars\x20of\x20kind\x20<code>*T</code>,\x20but\x20also\x0a\x20\x20<code>[]T</code>,\x20<code>func</code>,\x20<code>map</code>,\x0a\x20\x20<code>chan</code>,\x20and\x20<code>interface</code>&mdash;may\x20refer.\x20\x20This\x0a\x20\x20information\x20reveals\x20the\x20possible\x20destinations\x20of\x20each\x20dynamic\x20call\x0a\x20\x20(via\x20a\x20<code>func</code>\x20variable\x20or\x20interface\x20method),\x20and\x20the\x0a\x20\x20relationship\x20between\x20send\x20and\x20receive\x20operations\x20on\x20the\x20same\x0a\x20\x20channel.\x0a</p>\x0a<p>\x0a\x20\x20Compared\x20to\x20type\x20analysis,\x20pointer\x20analysis\x20requires\x20more\x20time\x20and\x0a\x20\x20memory,\x20and\x20is\x20impractical\x20for\x20code\x20bases\x20exceeding\x20a\x20million\x20lines.\x0a</p>\x0a\x0a<h3>Call\x20graph\x20navigation</h3>\x0a<p>\x0a\x20\x20When\x20pointer\x20analysis\x20is\x20complete,\x20the\x20source\x20view\x20annotates\x20the\x0a\x20\x20code\x20with\x20<b>callers</b>\x20and\x20<b>callees</b>\x20information:\x20callers\x0a\x20\x20information\x20is\x20associated\x20with\x20the\x20<code>func</code>\x20keyword\x20that\x0a\x20\x20declares\x20a\x20function,\x20and\x20callees\x20information\x20is\x20associated\x20with\x20the\x0a\x20\x20open\x20paren\x20'<span\x20style=\"color:\x20dark-blue\"><code>(</code></span>'\x20of\x0a\x20\x20a\x20function\x20call.\x0a</p>\x0a<p>\x0a\x20\x20In\x20this\x20example,\x20hovering\x20over\x20the\x20declaration\x20of\x20the\x0a\x20\x20<code>rot13</code>\x20function\x20(defined\x20in\x20strings/strings_test.go)\x0a\x20\x20reveals\x20that\x20it\x20is\x20called\x20in\x20exactly\x20one\x20place.\x0a</p>\x0a<img\x20class=\"ss\"\x20width='612'\x20src='callers1.png'>\x0a<p>\x0a\x20\x20Clicking\x20the\x20link\x20navigates\x20to\x20the\x20sole\x20caller.\x20\x20(If\x20there\x20were\x0a\x20\x20multiple\x20callers,\x20a\x20list\x20of\x20choices\x20would\x20be\x20displayed\x20first.)\x0a</p>\x0a<img\x20class=\"ss\"\x20width='680'\x20src='callers2.png'>\x0a<p>\x0a\x20\x20Notice\x20that\x20hovering\x20over\x20this\x20call\x20reveals\x20that\x20there\x20are\x2019\x0a\x20\x20possible\x20callees\x20at\x20this\x20site,\x20of\x20which\x20our\x20<code>rot13</code>\x0a\x20\x20function\x20was\x20just\x20one:\x20this\x20is\x20a\x20dynamic\x20call\x20through\x20a\x20variable\x20of\x0a\x20\x20type\x20<code>func(rune)\x20rune</code>.\x0a\x0a\x20\x20Clicking\x20on\x20the\x20call\x20brings\x20up\x20the\x20list\x20of\x20all\x2019\x20potential\x20callees,\x0a\x20\x20shown\x20truncated.\x20\x20Many\x20of\x20them\x20are\x20anonymous\x20functions.\x0a</p>\x0a<img\x20class=\"ss\"\x20width='564'\x20src='call3.png'>\x0a<p>\x0a\x20\x20Pointer\x20analysis\x20gives\x20a\x20very\x20precise\x20approximation\x20of\x20the\x20call\x0a\x20\x20graph\x20compared\x20to\x20type-based\x20techniques.\x0a\x0a\x20\x20As\x20a\x20case\x20in\x20point,\x20the\x20next\x20example\x20shows\x20the\x20dynamic\x20call\x20inside\x0a\x20\x20the\x20<code>testing</code>\x20package\x20responsible\x20for\x20calling\x20all\x0a\x20\x20user-defined\x20functions\x20named\x20<code>Example<i>XYZ</i></code>.\x0a</p>\x0a<img\x20class=\"ss\"\x20width='361'\x20src='call-eg.png'>\x0a<p>\x0a\x20\x20Recall\x20that\x20all\x20such\x20functions\x20have\x20type\x20<code>func()</code>,\x0a\x20\x20i.e.\x20no\x20arguments\x20and\x20no\x20results.\x20\x20A\x20type-based\x20approximation\x20could\x0a\x20\x20only\x20conclude\x20that\x20this\x20call\x20might\x20dispatch\x20to\x20any\x20function\x20matching\x0a\x20\x20that\x20type&mdash;and\x20these\x20are\x20very\x20numerous\x20in\x20most\x0a\x20\x20programs&mdash;but\x20pointer\x20analysis\x20can\x20track\x20the\x20flow\x20of\x20specific\x0a\x20\x20<code>func</code>\x20values\x20through\x20the\x20testing\x20package.\x0a\x0a\x20\x20As\x20an\x20indication\x20of\x20its\x20precision,\x20the\x20result\x20contains\x20only\x0a\x20\x20functions\x20whose\x20name\x20starts\x20with\x20<code>Example</code>.\x0a</p>\x0a\x0a<h3>Intra-package\x20call\x20graph</h3>\x0a<p>\x0a\x20\x20The\x20same\x20call\x20graph\x20information\x20is\x20presented\x20in\x20a\x20very\x20different\x20way\x0a\x20\x20in\x20the\x20package\x20view.\x20\x20For\x20each\x20package,\x20an\x20interactive\x20tree\x20view\x0a\x20\x20allows\x20exploration\x20of\x20the\x20call\x20graph\x20as\x20it\x20relates\x20to\x20just\x20that\x0a\x20\x20package;\x20all\x20functions\x20from\x20other\x20packages\x20are\x20elided.\x0a\x0a\x20\x20The\x20roots\x20of\x20the\x20tree\x20are\x20the\x20external\x20entry\x20points\x20of\x20the\x20package:\x0a\x20\x20not\x20only\x20its\x20exported\x20functions,\x20but\x20also\x20any\x20unexported\x20or\x0a\x20\x20anonymous\x20functions\x20that\x20are\x20called\x20(dynamically)\x20from\x20outside\x20the\x0a\x20\x20package.\x0a</p>\x0a<p>\x0a\x20\x20This\x20example\x20shows\x20the\x20entry\x20points\x20of\x20the\x0a\x20\x20<code>path/filepath</code>\x20package,\x20with\x20the\x20call\x20graph\x20for\x0a\x20\x20<code>Glob</code>\x20expanded\x20several\x20levels\x0a</p>\x0a<img\x20class=\"ss\x20dotted\"\x20width='501'\x20src='ipcg-pkg.png'>\x0a<p>\x0a\x20\x20Notice\x20that\x20the\x20nodes\x20for\x20Glob\x20and\x20Join\x20appear\x20multiple\x20times:\x20the\x0a\x20\x20tree\x20is\x20a\x20partial\x20unrolling\x20of\x20a\x20cyclic\x20graph;\x20the\x20full\x20unrolling\x0a\x20\x20is\x20in\x20general\x20infinite.\x0a</p>\x0a<p>\x0a\x20\x20For\x20each\x20function\x20documented\x20in\x20the\x20package\x20view,\x20another\x0a\x20\x20interactive\x20tree\x20view\x20allows\x20exploration\x20of\x20the\x20same\x20graph\x20starting\x0a\x20\x20at\x20that\x20function.\x0a\x0a\x20\x20This\x20is\x20a\x20portion\x20of\x20the\x20internal\x20graph\x20of\x0a\x20\x20<code>net/http.ListenAndServe</code>.\x0a</p>\x0a<img\x20class=\"ss\x20dotted\"\x20width='455'\x20src='ipcg-func.png'>\x0a\x0a<h3>Channel\x20peers\x20(send\x20\xe2\x86\x94\x20receive)</h3>\x0a<p>\x0a\x20\x20Because\x20concurrent\x20Go\x20programs\x20use\x20channels\x20to\x20pass\x20not\x20just\x20values\x0a\x20\x20but\x20also\x20control\x20between\x20different\x20goroutines,\x20it\x20is\x20natural\x20when\x0a\x20\x20reading\x20Go\x20code\x20to\x20want\x20to\x20navigate\x20from\x20a\x20channel\x20send\x20to\x20the\x0a\x20\x20corresponding\x20receive\x20so\x20as\x20to\x20understand\x20the\x20sequence\x20of\x20events.\x0a</p>\x0a<p>\x0a\x20\x20Godoc\x20annotates\x20every\x20channel\x20operation&mdash;make,\x20send,\x20range,\x0a\x20\x20receive,\x20close&mdash;with\x20a\x20link\x20to\x20a\x20panel\x20displaying\x20information\x0a\x20\x20about\x20other\x20operations\x20that\x20might\x20alias\x20the\x20same\x20channel.\x0a</p>\x0a<p>\x0a\x20\x20This\x20example,\x20from\x20the\x20tests\x20of\x20<code>net/http</code>,\x20shows\x20a\x20send\x0a\x20\x20operation\x20on\x20a\x20<code>chan\x20bool</code>.\x0a</p>\x0a<img\x20class=\"ss\"\x20width='811'\x20src='chan1.png'>\x0a<p>\x0a\x20\x20Clicking\x20on\x20the\x20<code>&lt;-</code>\x20send\x20operator\x20reveals\x20that\x20this\x0a\x20\x20channel\x20is\x20made\x20at\x20a\x20unique\x20location\x20(line\x20332)\x20and\x20that\x20there\x20are\x0a\x20\x20three\x20receive\x20operations\x20that\x20might\x20read\x20this\x20value.\x0a\x0a\x20\x20It\x20hardly\x20needs\x20pointing\x20out\x20that\x20some\x20channel\x20element\x20types\x20are\x0a\x20\x20very\x20widely\x20used\x20(e.g.\x20struct{},\x20bool,\x20int,\x20interface{})\x20and\x20that\x20a\x0a\x20\x20typical\x20Go\x20program\x20might\x20contain\x20dozens\x20of\x20receive\x20operations\x20on\x20a\x0a\x20\x20value\x20of\x20type\x20<code>chan\x20bool</code>;\x20yet\x20the\x20pointer\x20analysis\x20is\x0a\x20\x20able\x20to\x20distinguish\x20operations\x20on\x20channels\x20at\x20a\x20much\x20finer\x20precision\x0a\x20\x20than\x20based\x20on\x20their\x20type\x20alone.\x0a</p>\x0a<p>\x0a\x20\x20Notice\x20also\x20that\x20the\x20send\x20occurs\x20in\x20a\x20different\x20(anonymous)\x20function\x0a\x20\x20from\x20the\x20outer\x20one\x20containing\x20the\x20<code>make</code>\x20and\x20the\x20receive\x0a\x20\x20operations.\x0a</p>\x0a<p>\x0a\x20\x20Here's\x20another\x20example\x20of\x20send\x20on\x20a\x20different\x20<code>chan\x0a\x20\x20bool</code>,\x20also\x20in\x20package\x20<code>net/http</code>:\x0a</p>\x0a<img\x20class=\"ss\"\x20width='774'\x20src='chan2a.png'>\x0a<p>\x0a\x20\x20The\x20analysis\x20finds\x20just\x20one\x20receive\x20operation\x20that\x20might\x20receive\x0a\x20\x20from\x20this\x20channel,\x20in\x20the\x20test\x20for\x20this\x20feature.\x0a</p>\x0a<img\x20class=\"ss\"\x20width='737'\x20src='chan2b.png'>\x0a\x0a<h2>Known\x20issues</h2>\x0a<p>\x0a\x20\x20All\x20analysis\x20results\x20pertain\x20to\x20exactly\x0a\x20\x20one\x20configuration\x20(e.g.\x20amd64\x20linux).\x20\x20Files\x20that\x20are\x20conditionally\x0a\x20\x20compiled\x20based\x20on\x20different\x20platforms\x20or\x20build\x20tags\x20are\x20not\x20visible\x0a\x20\x20to\x20the\x20analysis.\x0a</p>\x0a<p>\x0a\x20\x20Files\x20that\x20<code>import\x20\"C\"</code>\x20require\x0a\x20\x20preprocessing\x20by\x20the\x20cgo\x20tool.\x20\x20The\x20file\x20offsets\x20after\x20preprocessing\x0a\x20\x20do\x20not\x20align\x20with\x20the\x20unpreprocessed\x20file,\x20so\x20markup\x20is\x20misaligned.\x0a</p>\x0a<p>\x0a\x20\x20Files\x20are\x20not\x20periodically\x20re-analyzed.\x0a\x20\x20If\x20the\x20files\x20change\x20underneath\x20the\x20running\x20server,\x20the\x20displayed\x0a\x20\x20markup\x20is\x20misaligned.\x0a</p>\x0a<p>\x0a\x20\x20Additional\x20issues\x20are\x20listed\x20at\x0a\x20\x20<a\x20href='https://go.googlesource.com/tools/+/master/godoc/analysis/README'>tools/godoc/analysis/README</a>.\x0a</p>\x0a",
 
 	"analysis/ident-def.png": "\x89PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\x00\x03\xd2\x00\x00\x00\xf5\x08\x03\x00\x00\x00\x8b\x0c=\xff\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x02\xfdPLTE!#\x20#$\"$%#($#&'%'(&-'\")+(4,\",.+01/>/\"241A2%685G6$8:7;<:Q9$>@=W>#AB@CEB\\B'cC$GIF\x00f\x00\x00g\x00\x00h\x00gF'\x00i\x01KLJ\x00j\x02\x02k\x03\x04l\x05mJ&\x06m\x06sJ(OQN\x0bo\x08\x0ep\x0awN&\x0aq\x16TUS\x10q\x0c\x0cr\x17\x0fs\x18~R%WYV\x12u\x1a,`\xae7]\xad\x15v\x1c\x86T)\x16w\x1d[]Z9a\xab\x19y\x1e^_];b\xac<c\xad\x8dZ(>e\xaf)z\x20ac`+{\"(|*\x92]%cebAh\xb2egd+\x7f,\x9a_)Li\xafDl\xb0.\x81.ikh0\x830Ho\xb31\x841/\x858Jq\xb6mol\xa3f);\x86:Us\xb3\xabg->\x88<Wu\xb5\xaej(sur@\x8b>B\x8c@\xb3m,vxu@\x8dGC\x8dA\\z\xbbxzwI\x8dH]}\xb7K\x8fJ\xb9r*_\x80\xbaM\x91L}\x7f|\xc1s-O\x93MP\x94Oc\x84\xbeN\x95U\x81\x83\x80\xc7x+W\x95VX\x97Xm\x87\xbcY\x98Y\xd1z(Z\x99Z[\x9aZ\x87\x89\x86\\\x9b[r\x8c\xc2\xd6~-^\x9d]\\\x9dc\x8a\x8c\x89d\x9ddz\x8f\xbff\x9ff\x8f\x91\x8eh\xa1h\xde\x85+~\x93\xc4j\xa3j\x92\x94\x91k\xa4ky\x97\xc6s\xa4lq\xa5s\x95\x97\x94\xec\x8a,\x83\x9b\xc5\x98\x9a\x96\x9a\x9b\x98u\xaaw\x86\x9e\xc8\xf1\x8e/\x9b\x9d\x9a~\xaay\x88\xa0\xcb\x9e\xa0\x9d\x80\xad|\xf7\x93-\xa0\xa2\x9f\xfd\x92/\x81\xb0\x85\xa2\xa4\xa1\x92\xa5\xca\xff\x952\x82\xb2\x86\xa4\xa6\xa3\x83\xb3\x87\x8b\xb2\x88\xa6\xa8\xa5\x96\xa9\xce\x8d\xb5\x8a\xa9\xab\xa8\x8e\xb6\x8c\x9e\xad\xcd\x8d\xb8\x93\xac\xae\xab\x95\xb8\x95\xa1\xb1\xd1\x97\xba\x96\xaf\xb1\xae\x98\xbb\x98\xa4\xb3\xd4\xb2\xb4\xb0\xa5\xb5\xd5\x9b\xbe\x9a\xb5\xb7\xb4\xac\xb7\xd1\xa3\xbf\x9d\xa2\xc0\xa4\xb7\xb9\xb6\xa4\xc2\xa6\xb9\xbb\xb8\xa5\xc4\xa8\xb1\xbd\xd7\xbb\xbd\xba\xa8\xc7\xaa\xb7\xbf\xd4\xaf\xc6\xab\xbe\xc0\xbd\xb9\xc1\xd6\xc0\xc2\xbe\xb2\xc9\xae\xc1\xc3\xc0\xbb\xc3\xd8\xbc\xc4\xd9\xb1\xcc\xb6\xc4\xc6\xc3\xb3\xcd\xb8\xb9\xcc\xb8\xc1\xc8\xde\xbb\xca\xde\xc7\xc9\xc6\xbb\xce\xba\xbd\xcf\xbb\xca\xcc\xc8\xc7\xcb\xdb\xbf\xd2\xbe\xc4\xcf\xdd\xcd\xcf\xcc\xcb\xcf\xdf\xc8\xd3\xc1\xc6\xd4\xc7\xcd\xd1\xe1\xd0\xd2\xcf\xc8\xd6\xca\xd2\xd2\xdd\xd2\xd4\xd1\xca\xd8\xcc\xd3\xd5\xd2\xce\xd6\xdf\xcc\xda\xcd\xd5\xd7\xd4\xd6\xd8\xd5\xcd\xdc\xcf\xd4\xdb\xd0\xd8\xd9\xe3\xd2\xdb\xe3\xd5\xdc\xd1\xd9\xdb\xd8\xd7\xde\xd3\xd5\xdf\xda\xdc\xde\xdb\xda\xdf\xe2\xd7\xe1\xdc\xe0\xde\xe2\xde\xe0\xdd\xd8\xe2\xdd\xdd\xe2\xe5\xe0\xe2\xdf\xe2\xe4\xe1\xdf\xe5\xe7\xe4\xe6\xe3\xe8\xe5\xea\xe2\xe7\xea\xe5\xe7\xe4\xe6\xe8\xe5\xe4\xe9\xec\xe7\xe9\xe6\xfe\xff\xfc\x93\x8dkM\x00\x00\x20\x00IDATx^\xed\x9d\x7ft\x14\xd5\xdd\xff\x07%\x064*\x15\xe1y<\xb3=lbJ0@\x94\x86F\xac(\x98o\xe5\xb4\x86\xf4\x89i\xfa\x8d\xf6\xa4R\x7f`A\x10\x1a\xcd\x93\xc3\xb1\"\x02\x15\x1e\x8c\xf5l\xea\x81\xd8\xb4\x91`h\xf6(\xb89r\xb2\x12\xe4\xc8\xba(<\x12\xda''\x94\xd2\xf6!\xc5\x08\xc8S(\xc8\x93v\xd7\xd4\xb3\xde\xef\xf9\xde{\xe7\xd7\xbd\xb3wfv\x03a\xc8\xec\xe7\xf5\xc7\xee\xec\xe43\xf7\xde\xf9\xcc\xbc\xf7\xde;;\x99\xb7\xf4\xff.\x00\x04\x00\xc0e\x86\xe4$[;\x9c\x0a\x07\x00\xe0R\x03\x92\x06\x00O\x01\x92\x06\x00O\x01\x92\x06\x00O\x01\x92\x06\x00O1\x92$]_/Z\x04\x00\x80\xc1=I\xf7w4\x07Zv\x9dS?u\x07\x82\xb6\xd1\x98?\xc9\xeb\x04\x8b\x84_\xcb\x849\xed\xc9\xdbX\xf0\xb1O.u\x8a\xb1'\xc5\x12\x9e\x95\xe5\x90S\xccP\xe9$;]\x82\x17z\x17\x14\x16TE\xca\xf6!\x94h\x983\xcd7\xed\x9eF\x84\xa2\xb2\\\x95@!\x1c\x11q*\xc7\x0e\xf1n\xa6\xb8\xf3\xa8\x0eW\x9f\xd7\xe7\x14\xa5s\xb6\xbe(wA\xc2)*\x89\xc8\xf4\x9dN!\x19\x85k\x92>\x11\x08\xf6\x1c\xeb\xd9\xd2<@?\x9d\x0b\xecjr\xd8\x00\xd5\xe6\x9e\x16,\x12\xce\xbf*\xb7G\xbb\x96\xca\x0d\xc9\x1bYp\xa0\xce\xef\x14\xe2\x80}\x09\x91^\xe5\xfdT\xd4\xd7h\x13\x96\x1aZa&\x06\xf6E\x0b\x16\x1d\xc6\x8a\xf6=\xda\xb9}\x11\xfd\xee\x88\xc8\x0b\xda\xba\xda\x17\xcaQ\x14\x8f\xc8\xb9Q\x14\x0b\xc9\x91\xb8p\xe3T\x11\xeff\x8a\xe9;\x1e\x8d\xb6\xc9\xfb\x9c\xa2t\xaa\x8b\xda\xea\xf2\xce;E%\xd1\x95\xa7}kZ$*\xc3pM\xd2\x87\x02\xc7\xf0\xeb@\xa0\x87~\x0av\x1cs\x92t\x9f\xbcZ\xb0\xa8\x10\x91\xf1\xa9\x8d\xbb\xc4?\xa3TiL\xe9\x9c\xb4\xc3\xb6\x84\x7f[\xa2-\xf9/\\\xd2Faf\x0a\xd7\xe2\x97\x9aj\xb2XG$\xbd\xba\x80\x088>\x05\xa7'&\xd7\xd6\xe1\xfeT\x8eYm\x9b\"\xe2\xddL9}\x07S\x97\xf4y\xb9\x15%\x86\xd2\\\xbdc\xb7NT&\xe1\x9a\xa4\x11\xed\x9eO\x06\xfa\xc9[w\xd3@\xbf\x93\xa4\xeb\xfc\xa7\x04\x8b\x0a\x8a\xa4\xe3\x05+Q\xaa\xa4|NZb[B\xf9\xc5\x94t\xb9\xbd\xa4K\xe8\xe0\xa4W\xee\xc4\xfd\\\x05]]QC$\x1d\xc9\x8f\x8d(I\xf7\xc9\x17:\x80\xb6NT&\xe1\x9e\xa41\xb1\xa3-A\xf2\x15{.p\x089I\xfac\xdf*\xc1\xa2\x8a\"i\xb4\xb2\x90\xbcn\xaf\xca\xbbg\xb5r&\xf7-*\xf4\x15-\xa0\xfao+\xcf+k\xa3+O\xd5\xce\x98\xb2H\x1d92\xb1\x1a\xbd>Yn\xe8\xab-\xc9\xadI\xb0\x01\x03Kf\xf8J\x16\xf6\x9aK\x88\xd6\x94\xf8\x0a\x17\x94p%\xec\x94\x15\xca\xc9\x07\xff\xda\xd5\xf7\xe4\xd5\x1c\xa7\x7f\x10\xd4\xb6R\xf6\xb5'\x07\x1c\xc6mX\x88f\xcarA\x9c+\xcc\x0c\x95\xf4\xd2\"\xba\xf3]x\xbb\xaaEt\xf5\xa2*\"\xe9\x8f\xcbC\x02IkU\xf0\x15\xa7\x91(v\xad\x06\x99\xb37\xa2F\x99\x8c\xfe\xd9D\xe9\x92^)\xcb\xdb\x8d)\xb8\x20\x0f\x83\x85\xcan\xae6\x1f\x00\xb59\x89\"\xdf\x8b3gDV\x15T\x0fp\xdb\x9d\xcf\x93\xd5\xcb\x15\\\xa2D\x87%SpQ\xd2'\x03\x18zy,\xd8\x81\x1c%]\xef;.XTQ%\xdd.\xe3\xe3]/\xaf\xeaj\x9d^NN\x87H~\xf9\xab\x91F<\x9e#\x1d{CW\x83\xff)\xbc\xd4WpO\xfb\xce\x1a\x99\x9e\x93L\xacN<\x14*\x99\x93?su\xad|\x9c\x0d\xe8\x92\xeb#\xa1\x85\xf2A\xbe\x84\xdf\xcaO\x85\"\xed\x852W\x02\x9e\xe4\xce\xa9\x8eF\xa3t\x1a\xe0\x97KC;\x8b\x16Y\xd5\xf6\xa7\x90O\x9e\xde\xf8\xeb|>\x20q\xa0Q>\x80\xde\x94\xb7\xf7\xf2\x85\x99\xa1\x92>^\"\xd74\x1e\x18$\x9f\xcb\x96\xd1\xd5\xcb\xca\xa8\xa4[\x17(\x92\x8e\x7f\xac\x10g\xab\xe0*N#Q\xecZ\x9dX\xb4\xa0\xe1o\xe8o\x0d\x05\xd1\x18\x9b(\xa4KZ\xb9\xa6\xa0N\xc1Ey@\xbd\xd1\x90\xdc\x18\x8d\x9e6\x1d\x00\xbd9\x91\x02yu\xb5\\\xb8\xb1\xa8\x95\xdb\x0co\x17U\x06Bl\xa2\x84\x87%SpQ\xd2\xe8d\x7fwK3\xd6tO`\xc0Q\xd2\xc7}\xcf\x0a\x165TIw\xe1\xc9t\x97\xfc&\"g\x12\xfe\xe6\x8e\x97\xd4\xe0\xb3x0t\x1e\xa1w\xe9\x85\xdf\x88\xdc\x85{\xb29\xf8,O\x94\xf9i\xbc\x1e\xcbQ.\x93\xbe`\x80\x0b\x88\x85H\xb7R\xb6\x10q%\xb4M\xa7=I\x81\xf9\xdca\x06\xdeEg\xf1I<\x1dY\xd6\xe6\x9f\x82\xcf\xdc\xda\xa4\x80\xba\x8a\xb337\x9a\x0b3C%\x8d\xceo\xac\xf0\xc9S\xc8V\xa5\xb5tum)\x95\xf4\xe9\xdc\xd3T\xd2\xd5j\xffU\xc5WaT\x9cN\xa2\x98\xb5,\xf5K\xf1\xcb2\xf2\xd3\"\x93(\xc4\x0c\xbc\xa9\xee\x1a\xed\xb2\xce\x0c\xbc\xf5\x03\xc04\xa7\xa8\x16o\xb9\x13\xd5%\xff|\x99\xab\xcdm\xf4DY\x1d\x96\x8c\xc0MIc\xe2-\x1d\xe4\x12Y\"\x918\xda\x94\xb0;\x00+}\x1f\x0b\x165\xf4^\xfa<Zz\xc7\x20.-1\xb3\x9e\x9c;\xfa\x15\xd0\xfa2\xfaVZ\x87\xce\xcb\xf4\xb7\xae\x06rr1\xb1\x1c\xe5~u\x18\xc0\x06\x9cm\xab\xb9\xa3@.C\\\x09\x9f\xce(Y\xd9\xde\x9b\x184\x15\xc0J\x9al\xdbhS\x9b\xbfN\x18\x10/+z4\xa903\x8a\xa4It\xe4G\xe4\xb4W{\xe9\xa5J/\x8d\x16\xb4RI\xf7\xedT\xe8\xe3\xab0*N#Q\xecZ\x96Hn\x0c\xc5\xf2\xa2dQO\x14A\x20i\xab\xac\xb3\x92\xd6\x0e\x80\xd1\x1cT\x14\xc2\x85\x0d\xa0\xb5\xcb\x90\x99dI[\x1d\x96\x8c\xc05I\xc7\x15\x01\xef\x0f$\x8e\x044\xfa-\xa3O\xf9\xeb\x05\x8b:\xaa\xa4\xd7\x16\xe0\xb3Z\xed\x92p/\xd1*\xeb?\xe0T)\xf2x\xb4\x02\xf5\xca\xf4\xbc\xa3'\x17\x13\xcbQ\xaeM\\\x99\x80\x83E%k;\xa3\xd5e\x88+\x01\x9do_R*\x17\xbdj*\xc0|y\xcc\xae6\xab\x80\x90~a\xc9A\xd2\x07\xe9\x148Q\x857\xabR6]\xa8\xcc\xa5Q\xa8\xcc<\x97f\xab0*N#Q\xdc\xce3$\x0a;Qg!9\xa6F\xa2\x08\x02I[e\x9d\x95\xb4v\x00\x8c\xe6\xa0\xa2w\xd1A\x1fB\xebR\x91\xb4\xd5a\xc9\x08\xdc\x92t\xa2i\x07}\xc7\x92N\x9c$t\x07N\x9e\xb4\xee\xa6W\xc9}\x82E\x1dE\xd2\x83\xd3\xf1!\xad\xbd\xa3\x97r\x96\xac5:\x9f;\xe8[I\x1d:+\xd3k?tV\xc7\xc4r\x94/R\x17\x98\x80\xd2\x0a\"\x8eE\xf8LeK\xe8%\xb7\xbc\xfc=\x94\xdbf.\x81\x9c\\\xed\xa4\xab1Ne\x8b\xda,\x02N\x155\x94\x9c5\x17f\x90\xa0sk*\xe9\xa2\x95tM\xc3\x1c<\xc4V\xa4P^\xa3H:\x96\x171I\x9a\xad\xc2\xa88\x8dD\xb1k9V-D\x8b\xe8UK#Q\x04^\xd2\x0dvYg%\xad\x1d\x00\xa39\xa8(\x82\x0e\xfaS\x904I\x94\xd5a\xc9\x08\xdc\x924j\xee\x20\xafd\xe0\xad`;\x97>M\x07\x89\xe6E\x03E\xd2\xeb\xc8\x99\x19Q\xe6h\x0dx\x1e\x1a+\xaa&C\xafU\xab\xc8\xd0\x92\xac\x0d\x91\xc1iE\x09\x9e2\xf6\xe5*\xa7\xb2\x1e\xcb\xa1\x7f\xdb3\x01%\xe4,K\x94\x913\x95)\xa1Q~\x97\x04T\x9b\x07\x0e\xd5\xd5\xb8\xa5\xca\x8c\x95\x11\x8e\xb06q\xc0`E\x03\xaa\xafN\x98\x0a3h#\xbd\xe5Y\xf9u\xbcX8\x93\xdc\x9e\x91\x202X\x9dO\x7f\x97\xce\xabW$\x8d\xea\x96\x99$\xcdVaT\x9cN\xa2\x98\xb5\x1c\x07\xfc\xa7\xfc\x07\xc8\x02\x93(\xc4H:\x0f\x7f\xfb$*\xec\xb2\xceJZ;\x00LsR\x90\xb4\x9e(\xab\xc3\x92\x11\xb8&\xe9C\x81\x8e\x9ec=-\xea\xddc\x89\xfe\xee@\xff\x19\xcb\xe0\xb5F\xcf\xbcV\xd0I+w\x8f=\xa5\xdc=\xb6N^\x16\xea\xac\x97\xb7#2\xc1+m\xebZEg\x7f\xb5\xf2\xba\xaeu2\xb9zt8ofc\xc34\xd9\xf7\xe6a.V'q\x80^9U\xe6\xebF@\xa3\xbc\xa4mc\xb9\\\xf8\xea\x01\xb6\x84F9\xbf\xa1\x0b\x07\x98\xef\xbal\xf4\xff\xba\xb3:\xefSr\xa5\xb7\xee\x00\xea\xad\xf3EO\x89k\x13\x07\xc4\xf7=;\xfd8\xea+X\xbd/\xce\x14\xc6\x12\x91\x17\x84\xde\xac($+\x0b\xe5\xa2\x86wq@\x1fY[\xd3\x19\xed\xac\x91;\xc9\xddc\xa1\x18\x8a\xe6\x99\x7f\xc4\xd2\xab\xe0*N#Q\xecZ\x96\xc4\x8c\x9a\x19\xf4\x1b\x88I\xd4\xa7\xe4\xee\xb1\xd6h\x94\x0c0\xaa\xa6\xbf\xba\xb1\xc2:\xeb\xea\x15\xef\x03\x09\xd3\x01\xd0\x9bsxZk,\xe4\xeb\x8d-\xab\xe6\x86+\x83\xfb\xa2Q\x7f]4JO#=QV\x87%#pM\xd2\xa8\x7fGK`\xebnu\x12\xd7O\xa6\xd2\xcdV\xa1\xa7\xf3j\x05\x8b\x06\xca=\xde%\xea=\xde\x91\xea\xc2)U]t\xb1o\xc9\xcc\xfc\x8aN\xb2\x94x\xbd,\xaf\xac\x8d\x9es}\x0b\xa7\x95\xac}\xd3'?\xcb\xc7j\xf4*3\xbdGM\x85%Z\xe7\xf8\xa7/m\x9f\xe3\xabfK\xd8^\xd5X\xe2+\xaaN:u\xe2\xab\xa6\xe5V\x1f\xa4\xf7x\xcb\xbe\xc3\xe4\xb7S\x8b\xda\xc4\x01\x11\x99\xfcB\xbbJV\xee\xd0\xd6\x0a\xe3\xe8,\xcf+x\x94\xca\xaa\xa2\xbd\xa14o\xfaB\xf2M\x97h\x98S\x20\x17\xcciL\xd0\x12B\xb8[,2Of\xb4*\xf8\x8a\xd3H\x14\xbb\x96\xa5\xd5\xdfJ\xdf\x99D\xd5\xa9\xb3f\xd2\xe7\xf6U\xe7\xe6\xd7\xbch\x99\x87x\x01\x8d\xf4\xfd\xd9t\x00\xb4\xe6$\x8a\xf0\xfe\xe4\xcby!\xd3\x1c\xfc\xb7j\x15\xf4\xd8\xeb\x89\xb2:,\x19\x81{\x92N\x83\x17\xe5?\x09\x16\x01\x00HfDH\x1a\xfe\xab\x12\x00ReDH\x1a\x00\x80T\x01I\x03\x80\xa7\x00I\x03\x80\xa7\x00I\x03\x80\xa7\x00I\x03\x80\xa7\x00I\x03\x80\xa7\x00I\x03\x80\xa7\x00I\x03\x80\xa7\x00I\x03\x80\xa7\x00I\x03\x80\xa7\x00I\x03\x80\xa7\x18I\x92\x86[\xbd\x01\xc0\x11\xf7$m\x18\xe8\xc4\x9a\x94\xe7\x149\xf8BX\x1b\xe8\x10\x86\xcdF%U\xb7\x98\xa1\xe3\xd8t\xc7\x00\x95\xa1\xda\xf5\xa4it#&\xd5FR\xd2O\xeaP\xf7-\xf3pM\xd2\x8c\x81\xce\xb9\xc0\xfe~\xccI\x87-\xac\x0dt\x08\x86\x8d\x8a#i\xfa\xac\xa4f\x95s\x018:\xc08\xed\xdb\x85\xda\xf5\xa4it#F\xd8H\xcb\xec\x08\x92j\x9f\xc9\xa1\xee[\xe6\xe1\x9a\xa4\x19\x03\x9ds\x81\xa3N\xd1\xc8\xde@\x87\x90\xfa\x03^\xd3\xf5YI\xd1*g\xe88:\xc08\xec\xdbE\xb0\xebI\xc3\x15\xc3\x0aQ#\xad\xb3\x93\x9cT\xa7L\x0ey\xdf2\x0c\xd7$\xcd\x18\xe8\xa4&i;\x03\x9d\xf4H\xd7g%E\xab\x9c\x8b\xc0\x10\x0b\xbb\x08v=\x17A\xd2\"\xacw(9\xa9N;?\xe4}\xcb0\xdc\x934\xd2\x0dtR\x92\xb4\xad\x81\x8ea\xa3\xc2\xf8\xc2\xe0\xc5\xd6\xfa\x99\xd3\xc8\x13|\x18\xff\x16\x0bC\x1a\xc3\xf6\x85s\x96\x11\xb9\xc50\xf6,|a\x9a\xf5\x8c\x85\x05\x8f\xd8\xd5\xc5\xc2\x01F\x14\xc0{\xdeh\xa4c\xd7s\xe1F7LR\x11c\xb6#l$\xbfC\xf6\x16<\xe2Lr\xf8W\xd5\xcf\xa0\x15w\xe1\xb8\x17\xd5\xbd0`\xf7-\xa3qQ\xd2\xba\x81\xce\xb9@\xc7\x96@s\xd8\xf4\xe0;\x13\xb6\x06:\x86\x8d\x0a\xe3\x0bC\x16K66\x96\xe4\x1df\xfd[,\x0ci\x0c\xdb\x17\xd6YF\xe8\x16\xc3\xd8\xb3p\x85\xe9^/\x16\x16<\x16\xae.B\x07\x18a\x00\xe7y\xa3\x93\x8e]\xcf\x85\x1b\xdd0Ie\xcdv\x84\x8d\xe4Z\xe6`\xc1#\xce$\x87_.\x0f\x85\xcap\xc5\xb1}%\xf5\xa7\xd5\xbd0`\xf7-\xa3qQ\xd2\xba\x81\xce\xb9@S\xf7\xd1\x9e\x96f\xbb+\xde\xf6\x06:\x04\xed\xd1\xaf\x86/\x0c\xf2\x97\xe0\xd1\xfd\xf9\x12b\xe7h<\xe1V<\xc2cm_\x8c\x12\xc4n1\x9c=\x8b^\x18\xe3\xf5\"\xb6\xe0\xb1vu\x11<[^\x1c\xc0\xec\x1bK\x1av=\x17ntc$\x95\xdbcq#\x99\xa7\xf7:Y\xf0Xd\xd2\xc0_\x8aO\x90\xf8\x1cr4\x1bIg\xfe\x94\xf9\x87Lc\xdf2\x1a7%\x8d\xd4\xe7x'\xba\xc9\xc9\x15k\xdam\x13ho\xa0C\xd0\xcf(\xf2\x9coE\xbc\xfe\xff\x20\xafm\xf2ygI\xb3\xb6/z\x09\x16n1\x9c=\x8b^\x18\xe3\xf5\x82\x84\x16<\xd6\xae.\xa9K\xda\xd87\x964\xecz.\xdc\xe8\xc6H*\xb7\xc7\xe2F\xea-s\xb6\xe0\xb1\xc8\xa4\x81\xffE\xf2J\x8f\xe6q\xf90\x8a\xe7\x9b\x1f\x00\xca\xec[&\xe3\x9a\xa4\x0d\x03\x1dmMx\xabe\xb0\x93\x81\x0eA?\xa3\x0c\xf1*C\xc1(yb\xbf\x93\xa4Y\xdb\x17=\xd6\xca-\x86\xb5g\xd1\x0bc\xbc^\x90\xd0\x82\xc7\xda\xd5%uI3{\xc1\x90\x86]\xcf\x85\x1b\xdd\x18I\xe5\xf6X\xdcH\xbde\xce\x16<\x16\x994`\x8e&\xfa\xd1Z\xf4\xee\x14\xf3\x97\xa3\xb1o\x19\x8d[\x92f\x0ctPG\x90.\xee\x08Z\x87;\x18\xe8\x10D\x92\xa6\x97\xd1\xa8E\xad\xe1\xdf\xc2\xf8\xac0\xb0\xb6/z\x09\x16n1\x9c=\x8b^\x18\xe3\xf5\x82\x84\x16<\xd6\xae.\xc9\x0e0\x16\x01v\x92N\xcd\xae\xe7\xc2\x8dn\x8c\xa4r{l#i\xd2\xb2\x14,x\xc4\x994\xf0\xd3_.\xe9\xd1D;\x0b\x07\x05\x16\x96\xfa\xbee4nI\x9a5\xd0\x09n!\x8bg\x02\xfb-\x83\x9d\x0ct\x08\"I\x17\xe1\xb3v\xe0\x8ej\xc4\xfa\xb7\x88\x0diX\xdb\x17\xa3\x04\xb1[\x0cg\xcf\xa2\x17\xc6x\xbd0=\x0e\xe3\x16c\xed\xea\x92\xec\x00c\x11`!\xe94\xecz.\xdc\xe8\xc6H*\xb7\xc7\xe2F\xea-K\xc1\x82G\x9cI\x03\xffL\xe2\x98[J\x8e&\x1a,\xdc9-\xf9\xc1\xfb\xfa\xbea>\xdex\xa1\xb7\xc3\x8dT\\\x934c\xa0s4\xb0\xed\xd0\xd1\xbd\x81\xa0\xf5\x90\xc9\xc1@\x87\xb1Q\xe1|a\xc85\xd2\xf69S\xc8\x06\x8c\x7f\x0b\x12\x19\xd2\x18\xb6/l\x09b\xb7\x18\xce\x9e\xc5(L\xf7z\xb1\xb4\xe0\x11\xb9\xba\x88\x1d`\x84\x01\xdc\xbe\xb1\xa4l\xd7\x83.\xdc\xe8\x86M\xaaa\xb6c\xd5Hc\x87\x9c-x\x04\x994U\\s\x20R5E9\xfc\xeb\xee\x98\x92|\xba\xe8\xfb\x86Y(/H\xfa{f\xe0\x9a\xa4Y\x03\x9d\x13\x1d\xcd\x81`\xb7\xb5\xa2\x9d\x0ct\x18\x1b\x15\xce\x17\xc6\xbf\xba\xbe`F-=\xffY\xff\x16\x91!\x8da\xfb\xc2\x95\x20t\x8b\xe1\xecY\x8c\xc2t\xeb\x19\x0b\x0b\x1e\xb1\xab\x8b\xd8\x01F\x18\xc0{\xde0\xa4l\xd7C\xb80\xa3\x1b.\xa9\x86\xd9\x8eU#\x99\x1dr\xb4\xe0\x11d\x92\xa3\xb4qI\xbeZ1\xb9\x81PtEE\xdb7L\xfb\xf4vA@&\xe0\x9e\xa4\xd3`\xa8\x06:p\xbf\xd10py$5\xe6\xcfL\xc3\xab\x14\x18\x11\x92\x1e\xea\x7fU^\x1eg\x9f\xc7\xb8<\x92\x1a\x82+\xdbV\x8c\x08I\x0f\x95\xcb\xe3\xec\xf3\x18\x97AR\x1b#\xa8\xba\xc1)(c\xf1\xb0\xa4\x95\x0b5\xc0E\xe5rHjL._Yt\xde)*c\xf1\xb0\xa4\xe9\x85\x1a\xe1\x8df\xc0\x90\xb9,\x92\xda\x90_m\xbe\x11\x1e\xd0\xf1\xb0\xa4\x01\x20\x13\x01I\x03\x80\xa7\x00I\x03\x80\xa7\x00I\x03\x80\xa7\x00I\x03\x80\xa7\x00I\x03\x80\xa7\x00I\x03\x80\xa7\x00I\x03\x80\xa7\x18I\x92\x1e\xea\xad\xde\x00\x90A\xb8'i\xc3@\x07\xd3\xb3\xad\xa9e\xaf}\xbc\x83\x81\x0e\x00\x00\x04\xd7$\xcd\x18\xe8\xa0xG`\xf7\x91\xbd\x81C\xf6[\xd8\x1b\xe8\x00\x00@pM\xd2\x8c\x81\x0e\xea\x20\x9e\x1b'\xe9\xa25N\x06:\x00\x00\x20\x17%\xcd\x18\xe8\xf4+O\x1d;g\x1f\x7f\xf1\x0ct\x00\xc0\xc3\xb8'i\xa4\x1b\xe8\xec\x0e\x0c:\x19\xb99\x18\xe8\x00\x00\xa0\xe2\xa2\xa4u\x03\x9d`\xb0gk\xa0y\xd7\x85\x18\xe8\x00\x00\xa0\xe0\xa2\xa4u\x03\x9d\x16j\xa0\xd3\xdcra\x06:\x00\x00\x20w%\x8d\xb4\xe7x\xd3\xbez\x20\xb0\xc7&\xd0\xd9@\x07\x00\x00\xe4\xa2\xa4\x19\x03\x1d\xd59'l\xe3\xb6\x91\x82\x81\x0e\x00\x00\xc8=I\xb3\x06:{\x9b\xa8\xbc;.\xcc@\x07\x00\x00\xe4\x9e\xa4Y\x03\x1d\xc5:\xe7\\\xc0\xfa\xf6\xb1T\x0ct\x00\x00@.J\x9a1\xd0A{\x03{\x8fv7m\x15\xd8\xb4\xaa8\x19\xe8\x00\x00\xa0\xe2\x9a\xa4Y\x03\x1dt(\x18\xd8\xb2\xd7Z\xd1\x8e\x06:\x00\x00\xa8\xb8'\xe94\x18\xaa\x81\x0e\x00d\x1e#B\xd2\xf0_\x95\x00\x90*#B\xd2\x00\x00\xa4\x0aH\x1a\x00<\x05H\x1a\x00<\x05H\x1a\x00<\x05H\x1a\x00<\x05H\x1a\x00<\x05H\x1a\x00<\x05H\x1a\x00<\x05H\x1a\x00<\x05H\x1a\x00<\x05H\x1a\x00<\xc5H\x924\xdc\xea\x0d\x00\x8e\xb8'i\xdd@g\xb0)\xa0\xd0l\xbf\x81\x9d\x81N\xef\x82\xc2\x82\xaaH\xd9>\xf36\xb6<+\xcb!\xa7\x18\xf2\x88a\xb9\xd4)\xe6\xa2\x11\x99\xbe\xd3)D\xe7l}Q\xee\x02\xc7\x87%#T%\x93\xfd\x0c\xe1\xd7*\xa7P\x0b,\x12U\x87\x8b\xcc\x13\xfd\xf7z\xaa-\xa3\xa4\x91_-;\x96\x15'\x93\xda1\xf6\x14\xaeI\xda0\xd0\x89\x05\xf6\xf6c\xf6*\x0f\xe8\xb7\xc6\xc6@\xa7\xd7\xf7h\xe7\xf6E\xa9\x1e\xbdH\xaf\xf2~*\xeak\xb4\x8f\xa4\x1c\xa8\xf3;\x85\xa4\x88V\xb1\xf5\xda\xae\xbc\xd4v\x81P]\xd4V\x97w\xde)\x0a\xa1\xbe\xd5r$\x86bQyuj*H\xc6\"Q\xc7\xa3\xd16Y\xf4-\x9aj\xcb\x14\x04\xf9\x15'J\xcf\x8ee\xc5\xc9\xa4r\x8c-j\x1b\xa9\xb8&i\xc6@\xa7\x9b<\xd9d\xa0i\x97\xfd\x06v\x06:5\xd5\xe4\xb5.EI\xff\xdb\x12m\xc9\xefx\xb8\x09\x8d\x17K\xd2F\xc5\x96kS\xed\xdb\x10:/\xb7\xa2\x84\xfd\xb3\xcfUZe\xf2\xa0\x89\x04\x8e\x1f2V\x89:(RV\xea-SH\xce\xaf8Qlv\x84\x15\x0bq>\xc6V\xb5\x8dP\\\x934c\xa0C\xd9\xb6\xc5\xfa\xa9&\x14;\x03\x9d\x92\x06\xf2\xda+w\xa2T(wK\xd2\xe5\xc2sG\xbc\xd6\x91>9\xd51\xfa\xa5\x96t\xea-SH\xce\xafsJ.\xa6\xa4\x9dk\x1bQ\xb8'i\xa4\x1b\xe8\x10z\x02'\xeccm\x0dt\x96\x16\x1d&o]\xb4k\xd8^\x95w\xcfj\xa5\x93`\x165v\xca\x0a\xe5\xe4\x83\x7f\xed\xea{\xf2j\x8e[\xc5\xe2q[\xed\x8c)\x8b\xd4\x81a[y^Y\x9b\xb2\xbaoQ\xa1\xafh\xc1)\xb4R\x96\xb7+\x93\xc1D\x91\xef\xc5\x993\"\xab\x0a\xaa\x07\xd8\xc2V\xca\xbev\xb5\x0a\xb6\xe2\x81%3|%\x0b{M\xcd9\x9f'\x1bs\x07\xad6\xa6\x04\x86\xc1Be\xb3\xd5\\l\xafO\x96\x1b\xfajKrk\xb8\xce\xde\x90\xb4Q\x18\xd7^\xa39\\\x09\xd1\x9a\x12_\xe1\x82\x12R\x84\x91(#\x96\x90\xac\xac\xb4Z\xc6\xe5W\xcb\x998Q|v\x8c\x8a\x99F\x1a\xb0\x8d\xf4\xaf\xaa\x9f1m\xa12\xe70\x92\xaa\x1d7\xfe|\xf0\x04.JZ7\xd0!\xb4t\xd8\xc6:\x18\xe8\x1c/\x91k\x1a\x0f(\xdd|\xbd\xbc\xaa\xabuzy\x82_\xd4\x19\xd8\x17\x9dS\x1d\x8dF\xffL>\xf8\xe5\xd2\xd0\xce\xa2E\xa6\xcd\x0c\xfa\x0a\xeei\xdfY#\xd3S\xae\xce\xdf\xd0\xd5\xe0\x7f\x8a,F\xf2\xcb_\x8d4b\x89(35:\x19\x8c\x14\xc8\xab\xab\xe5\xc2\x8dE\xadla\x7f\x0a\xf9\xe4\xe9\x8d\xbf\xce_\xc4W\xdc%\xd7GB\x0b\xe5\x83\xa6\xe6\xf4F\xa3Z\x9f\xa2\xd7\xc6\x94\xc0\xd2\x1b\x0d\xc9\x8d\xd1\xe8i.6\x1e\x0a\x95\xcc\xc9\x9f\xb9\xbaV\xe6\x12dH\x9a)\x8cm\xaf\xd1\x1c\xb6\x84\xdf\xcaO\x85\"\xed\x852I\x89\x91(#\x96\x20\xe8,\xd3i\x19\x9b_=g\xe2Dq\xd91*f\x1bi\xc0n\xe6\x97\xcbC\xa1\xb2<\xf2\x9d\xaf7\x879n\xdc\x01\xf0\x04.JZ7\xd0\xc1\x1c\xa13k\x1b\x1c\x0ct\xceo\xac\xf0\xc9S\xc8wx\x97\xfc&\"G<\xc4-r0\x03\xef\xa2\xb3\xf8\\\x9a\x8e\xacb\xab\xe6\xe0^#QFN\xb9w\xe5\x08~\x8d\xc8]\xf8\xfc,\xa9\xc1\x1a\x19\x0c\x91\x0b@\xf4$\xa3#\xc7\xa2Z\\\xc8NTW\xcf\x17\xe6\x9f\x82O\xe2\xda\xe9|\xc5\xb1\x10\x19\x0e\x94-\xe4\xd7\x12r\x95\x93\x96\xa9\x8d+\x81A\x1f\xde\xb2\xb1\xa8\\\xa6\xdd.\x17\xc9\x0e\xbc\x8d\xc2\x98\xf6\xf2\xcd\xd1Jh\x9bNt\xd2V@%\xad'\x8a\x8bu\x18x;\xb6\x8c\xc9/w\x00\xc4\x89\xd2\xb3\x83\x8c\x8a\xd9F\x1a\xb0\x9b\xf9K\xf1\xde\xc7\xe7T\x98\x92\xaa\x1f7\x18x\xb38\x15\xeeL\\\xed\x9d;Z\xec\xe3R0\xd0\x89G~D\x0e\xd6\xd2;\x06\x13\x98\x99\xf5\xdc\"\x07#i\xf2'z`\x85\xb1\xe7\xe5v\xf2\xd6@\x02\xea\xcb\xe8\xaa\xd2:r\xf6\x19\x97H\x19I\x87\xf0y6\x80\xd6.\xe3\x0b\xa3\x8f\x1dO:w\xce\xb6\xd5\xdcQ\x20\x97\x99\xd6\"\xfd\xa4ej\xe3J`\xd0\x85\xc3\xc6\xa2r\x7f\xb2\x05\x20'i\xbd0\xa6\xbd|s\xb4\x12>\x9dQ\xb2\xb2\xbd7A\xc7>F\xa2\xb8X\x07I;\xb5\x8c\xcd/w\x00\xc4\x89\x12I\x9am$\x03\xb3\x99\xffE\xf2\xda&\x9f\xe7\x93\x0a\x92\x16\xe2T\xb8\x1d\x8c\x81\x0e\xa6\xc9\xfa\xb1\xfc\x14\x07\x03\x9d\x83\xf4rY\xa2\x0a\x7f-\x97\xa9s#~\x91\xc3ty\x8c\x1eXal\xaf\x1cEZ@\xd5\xa3t\xd5\xa3\x15\x9aD\xcc%\x14\xbd\x8b\x0e\xfa\x10Z\xb7\x8c/Lx\xee\x1c,*Y\xdb\x19\xad\xb6\x964S\x1bW\x02\x83.\x1c6\x16\x95\x0b\xe6\x84m\xf2\xdf\xf1kL&\xb3Ha{\xf9\xe6\xe8%\x9co_R*\x17\xbd\x8a\xb8\xcd\xb8X\x07I;\xb5\x8c\xcd/w\x00\xc4\x89\x12I\x9am\xa4\x01\xbb\x992X\x8f\xe2\xafa\xab\xa4\x82\xa4\x0d\x9c\x0a\xb7\x815\xd0!~\x1bG\xec\xc3\x1d\x0ct\x8aV\xd2\xb7\x869xPyG/\xe5,\xb7\xc8A\x0fa;\xe93\x8c\x03+\x8c=KU\x80\xe8\xe5\x9b\xfa;\xe8\xaa\x92:2t3\xf5\xd2\xb4\x9b)\x8a\xa0\x83~E\"laI\xe7\x0e\xa9\xb8\xb4\x82\x0c\x0c\x17\x95\xf1k\x09Z/m\xd4\xe6(i6\x16\x95\x9b\xe6\xdc\x84(m\xaf\xa2\x1fF\xd2F{\xf9\xe6h%\xf4\x92\xdby\xfe\x1e\xca\xe5\xbf\x09\xb8X\xa7^\xda\xa1el~\xb9\x03\x20N\x94H\xd2l#\x0d\xd8\xcd\xfc\xf4B];\x1e\x90$%\xb5\xc1tX\xbc\x81[\x92f\x0dt\xc8TZ\xbbL&\xc6\xc9@\xa7p&\x99\xd7&\xc8Y\x13Qfc\x0d\x1b\xb9E\x8e\xeaj\\\x8c2\xd1\xd5\xcfTqlE\x09.\xb7/\x97\x04t\xd1\x80\x10\x19\xdb\xc7\x8a\xaa\xc9@o\x15\xb9\xee\x9e\xb7\x16\xd7[a\x92\x08[\x18+H\xbd\xe2\x12rz'\xca\xcaL\xcdA\xfaI\xcb\xd4\xe6(i6V\xd8\xe3\x0cL#\xe3\x9a\xfai\x03\xc8B\xd2\\s\xf4\x12\x1a\xe5w\xc9[u=\xb7\x19\x17\xeb\x20i\xc7\x961\xf9\xe5\x0e\x808Q\"I\xb3\x8d4`7\xf3\xcf$\x17>J\xab\xf9\xe6\x18\xc7\xcdt\x00F>\xaeI\x9a5\xd0A=\x01;oig\x03\x9dB\xb9\xa8\xe1\xdd\xcejz\x93\xe0:yY\xa8\xb3^\xde\xce/\xb24\xfa\x7f\x8dc?%\xd7=\xeb\x0e\xa0\xde:_\xf4\x94E\xec\xe1\xbc\x99\x8d\x0d\xd3d\xdf\x9b\x87q7\"\xaf\xebZ'\xd7\x92\xd5\x91\xdc\xd2\xb6\xaeUt\"X5\xfd\xd5\x8d\x15$\xe0\xf0\xb4\xd6X\xc8\xd7\x1b[V}\x9c)\x8c\xabB\xaf\x18\x9f\x88K\xda6\x96\xcb\x85\xaf\x1e`\xd7\x0e\xee\x8bF\xfdu\xd1(I\x89^\x1b_\x82\x8er]\xf9\x00\x9d\xb5\xe8\xb1\x89\x03\xf4\xeam\xd2\xa5\x86\x90\xfclW=9g\x99\xc2\xd8\xf6\x1a\xcdaKh\x94\xf3\x1b\xba\xf0^D\xb860M\xff\x94\xdc\xc4\xd5\x1a\x8d\xf2\xfd[:-c\xf3\xcb\x1e\x00Q\xa2\x98\xec0\x15\x1b\x8dda\xf3\xeb\x97k\x0eD\xaa\xa6\xf4!\xee\x10\xea\xc7\x8d\xad\xcd\x1b\xb8&i\xce@\xe7\xc8\x16\xdbPG\x03\x9d\x8a\xf6\x86\xd2\xbc\xe9\xea\x8f\x8f\x91\xea\xc2)U]\xe6E\x86\xf8\xaai\xb9\xd5\x07\xe9\xfd\xbf\xb2\xef0\xf9\xb9\xf3Y\xab\xd8\xbe\x85\xd3J\xd6\xbe\xe9#\x01\x89\xd7\xcb\xf2\xca\xda\x94+\x00}Kf\xe6Wt\xd2\xa5\xea\xdc\xfc\x9a\x17e\xb9\xbeH\x96C\xf9r^H\x99\x0dj\x85\xf1Uh\x15\xa3D\xeb\x1c\xff\xf4\xa5\xeds|\xd5\xec\xda\xdf\xaa\xd3I\xf2U\xa1\xd7\xc6\x97\xa0\x11/\xa0\x91>\xfa\xd3\x8b\x1e\xdb\xabl\xff(2\xd3U\x9eWNv\xcd(\x8ck\xaf\xd1\x1c\xb6\x84\xedU\x8d%\xbe\xa2\xea\x08\xdf\x06\xa6\xe9uj{\xb9\xee7\xbd\x961\xf9e\x0f\x80(QLv\x98\x8a\x8dF\xb2\xb0\xf9-m\\\x92?\xa3V\xb9\xd8b\x1cB\xed\xb8q\x87\xc5\x1b\xb8'\xe94\x00\x03\x1d\x00H\x95\x11!i\xf8\xafJ\x00H\x95\x11!i\x00\x00R\x05$\x0d\x00\x9e\x02$\x0d\x00\x9e\x02$\x0d\x00\x9e\x02$\x0d\x00\x9e\x02$\x0d\x00\x9e\x02$\x0d\x00\x9e\x02$\x0d\x00\x9e\x02$\x0d\x00\x9e\x02$\x0d\x00\x9e\x02$\x0d\x00\x9eb$I\x1an\xf5\x06\x00G\xdc\x93\xb4n\xa0\x83\xd0\xc0\xae-\x81-\xbb\x06\x1c6\xb03\xd0\xd1\xb9\xf4\x86)\xe9x\xde0\x88Mf:\xc9\xff\x0c\x92'\xd8\x1a\x8e@\x89\x869\xd3|\xd3\xeei$O'\x91\xab\x12\xd4\x09\xc7\xf4\xbf\x84Cm\x83\x90\xce\xd2\xdc\xb2Py\xd2\x7f\xa4\xda\x93\x86\xa5\x0d0\xcc\xb8&i\xc3@\x07\x9dk\xda\xdas\xb4gK\x93\xfd\x93M\xec\x0ct\xd26\xc5\xb9\x88\xa4\xe3y\xc3\x206\x99\x19\xd8\x17-Xt\x98s\x04\x8a\xc8\x0b\xda\xba\xda\x17\xcaQ\x14\x8f\xc8\xb9Q\x14\x0b\xc9\x11\xf3\x03#\x84m\x18\x9a/\xcc\xebrm\xe7Z9\xdd\xc7\xf8\xa7ai\x03\x0c3\xaeI\x9a1\xd0\x09\xb7\x90\xe7\xfe\x0c\xb6\x84m7\xb03\xd0I\xdf\x14\xe7\"\x92\xba\xe7\x0d\x83\xb5\xc9L\xe1Z\xc49\x02\xad.\x20\x02\x8eOYM\x9e\x08X[\x87\xd0\xc7r\xf2v\xa26\x0c\xc9\x17\xa6On\xc0\xaf\xab\xd3\x954J\xc7\xff\x02\x18V\\\x934c\xa0\xd3\xb1\x95\xae\x08\xda?\x9d\xdf\xce@'\xe9\xa9\x9f\x97=\xd6&3T\xd2\x8c#P5}\xbe&\xaa\xa8!\x92\x8e\xe4\xc7\x84\x92\x161\xa4\x07_>5\x9d|\x81\xfcI\xe6\x1f\xcf\x97\x0a\x20\xe9\xcb\x04\xf7$\x8dt\x03\x9d3M\xe13\xf13\xe1\xa63v\xb1v\x06:\xe9\x99\xe2\xe8\xf67HhSC\xe6\xaa\x8d\xa8QV&\xe5Z\x09\x16\xce2ix\xde0\x01\xbc\xc9\x8c\x09*i\xc6\x11\xa8Jy\xb2\xe6\xa2*\"\xe9\x8f\xcbCI\x926\xda`a\xd7\xc3y\xff\xe8\xf0N8\x1a\xd3\xd6\xd2\xb7\xd7\x8f[l\xc6fG\xe8\xa5\xc3x\xd3\x20\xab\x03\x00\x0c'.J\xda0\xd0\x89u\xe0\xa5\x0e\xfb#og\xa0\x93\x96)\x8ea\x7f#\xb6\xa9\x89E\x0b\x1a\xfe\x86\xfe\xd6P\x10\x8d1%X9\xcb\xa4\xe1y\xc3X\xf0\xb0&3f\xa8\xa4\x19G\xa0\xb2et\xf5\xb22*\xe9\xd6\x05\xc9\xbd\xb4\xde\x06\x0b\xbb\x1e\xd6\xfb\xc7\x80w\xc2QQ\x1f\x96\xaf\x20\xda\x8c\xcd\x8e\xd0K\x87\xf1\xa6\xb1:\x00\xc0\xb0\xe2\xa2\xa4u\x03\x9dxGKO\x7fOK\x87\x9du\xa5\x83\x81N\x1a\xa68\x8c\xfd\x8d\x85MM\xfdR\xfc\xb2\xac\xde\\\x82\xd0Y\x06\xa5\xeey\xc3\xd9\xc98\x0c\xbc\x19G\xa0R\xe5\xf9\x89\xb5\xa5T\xd2\xa7sO\x8b\x06\xde\xda\xd3p\x85v=\\\xc5:&o\x1a\x85\xc3\xca\xc5\xf4x<n\xb5\x19\x93\x1d\x0b/\x1d\xe3\x01\xc1V\x0eF\xc0p\xe2\xa6\xa4\x91\xfa\x1c\xefp\x0b\xbd\x00\xd4bg0\xedd\xa0\x93\xb2)\x0ek\x7fcaS\x13\xc9\x8d\xa1X^\xd4\\\x82\xd0Y\x06\xa5\xeey\xc3\xd9\xc98I\x1a\xe9\x8e@j/\xbdT\xe9\xa5\xd1\x82V[I3\x15\xeb)\xe1*6\xe0\xbdi\x14\xfeN{\xe9e\xf4w2\x8b\xcd\x8c\xecXx\xe9\x18\x92\xb6r0\x02\x86\x13\xd7$m\x18\xe8$\x02\xfb\xb5E\xcbh\x07\x03\x9d4LqX\xfb\x1b\x0bG\x95Da'\xea,L\x98K\x10:\xcb\xa0\xd4=o8;\x19\x07I3\x8e@UJ\xf3\x17*si\x14*\xb3\x954S\xb1\x9e\x12\xaeb\x1d\x937\x8d\x0a\xad\xfdt\xa7\xbc.n\xb1\x19\x93\x1d\x0b/\x1d\xa7\x03\x00\x0c/nI\x9a1\xd0\xd1$\xfd\xa1\x8d\xa4\x1d\x0ct\xd20\xc5a\xedo\xacljV-D\x8b\xe8\x158\xde\xd5E\xe4,\x83R\xf7\xbc\xe1\xecdD\x92N\xd0\x89/\x15\x15\xe3\x08T\xad|\x93\x94\xd7(\x92\x8e\xe5E\xd2\x914I\x09W\xb1\x8e\xc9\x9bF\xe5\xa9\"\xf2\x85\xd7I\xae4\x887c\xb2c\xe1\xa5cx\xd3X9\x18\x01\xc3\x89[\x92f\x0dtv\xa8\x03\xef\x1d\x96\xc1N\x06:\xe9\x98\xe20\xf67V65\x07\xfc\xa7\xfc\xc4\x07\x83/A\xe8,\x83R\xf7\xbc\xe1\xecdD\x92n#\xaeUg\xe5\xd7\x11\xe7\x08\xb4:\x9ff'\xaf^\x914\xaa[\x96\xa2\xa4\xf5\x94p\x15\xeb\x98\xbciT\x94\xdf\xa5\xab\x89\xa4\xc5\x9b1\xd9\xb1\xf0\xd21\xbci\xf8\x03\xf0\xf1F\xb8\xbd\xecR\xe0\x9a\xa4\x19\x03\x9dXsK\xf7\xb1\xee\x96f\xebK\xdeN\x06:\xe9\x98\xe2\xb0\xf67\x1665\x89\x1953\x94\x11\x83^\x82\xd8Y&-\xcf\x1b\xc6\xbf\x855\x99a\x1a&/\x08\xbdYQH\x9c\\\x18G\xa0\x88\\\xd3\x19\xed\xac\x91;\xc9\xddc\xa1\x18\x8a\xe6\x99$m\xb4\xc1\xc2\xae\x875\x8e1\xe0L|\x0cZ\xe5\xfa\xaez\xe5\xee1\xe1fLv,\xbct\x18o\x1a\xee\x00,\x94\x17\x98\x8b\x02\x86\x01\xd7$\xcd\x1a\xe8\xc4\xf7l\x09l\xddcm\x8b\xe5h\xa0\x93\x96)\x0ec\x7fceS\xd3\xea\xd7\xee\x9e\xd2J\x10;\xcb\xa4\xe3y\xc3\x04p&3\x0c\x9d\xe5y\x05\x8f\x1e&K\x8c#P\xa2aN\x81\\0\xa71\x81\xc5M~\x0dNT\x14\xf1_\x05F\x1b,\xecz8\xef\x1f\x1d\xce\xc4\x87\xa1\xb34\xaf\xa2\xab\xa4\xcbj3dd\xc7\xc2K\x87\xf5\xa6a\x0f@\xfbt\xe6\x072`\xd8pO\xd2i\x00\x06:\x00\x90*#B\xd2\xf0_\x95\x00\x90*#B\xd2\x00\x00\xa4\x0aH\x1a\x00<\x05H\x1a\x00<\x05H\x1a\x00<\x05H\xda]6_0N5\x00\x19\x06H\xda]\x9c\x04\xeb\x8cS\x0d@\x86\x01\x92v\x17'\xc1:\xe3T\x03\x90a\x80\xa4\xdd\xc5I\xb0\xce8\xd5\x00d\x18\x20iwq\x12\xac3N5\x00\x19\x06H\xda]\x9c\x04\xeb\x8cS\x0d\x97\x92K\xfbD\xa2K[\xdb\x88\x01$\xed.N\x82u\xc6\xa9\x86KF\x7f\xe5u\xd2\\\x84\xe6I9\xf3{\x9cb/\x1c\xb56\x20\x09\xefK:8\xf9\xa4S\xc8\xa5\xe1\xcc\xe4`\xf2J'\xc1:\xa3\x16\xe4\xfan&&N\x0ct\x1c%\xffa\x17\x98\x983@W\x09\xf7\xf8\xe2\xa0\xd5\x06$\xe1\x9e\xa4\x19\x03\x9d\xc4\xfe\xad\x81\xad\xf6\xdf\xec\xff\xbb\xe1;\xb3\x9f\xfe\xc26D\xcc\x1ai\x85\xbatd\xb44\xd164\x897\x8a1_\xff\xfe[_:\x05j|2\xab\xf8\x01\xeb\xbf\xae\x19\xf5\\\xd2\xbaoK\x84\xeb\xff\xaf\x93pu~v\xa5t=\xb7B-[\xdfM!\x1d9C\x12\xd7\x99\x1f\xe4d\xdf\x9e\xe2\xf8\xb6[\xda\xa6-\x86%\xe595\xc2=\xbe80\xb5\x01<\xaeI\x9a1\xd0I\x04\x03\x1f\x1e\xd9\x1b\xd8k\x17\xfe\xe4}o\xbd0\xfb3\xbb\x081\xebG5\xe9\xcb\xbb+\xb3l\"\x05|\xf6\x9b\xe2\xb7?z\xff\xf9\xe2\xd7\x9c\x025\xbe\xfc\xdd\x86;m\xfe\x1c\xbcb\xbdy\xd5+\xdf\x96\x1e\xfc\xc9\xe37KwY(8\x99\x9f\xdcr%\xf7\x99\x16\xc3\xee\xa6\x88`\xf6\x96\xe4\x95;l3N\xb8\xed\xba\x97*\xb3\x1d|\x8d4\xf6Hacq\xb7\xba$\xd8\xe3\x8b\x03S\x1b\xc0\xe3\x9a\xa4\x19\x03\x9d\xfd\x813t\xc5\x80u\xf4g\xc5o\xa0/\xfea\xfdw+\x8e\x8c^\xcc|Z\x91\xaa\xa4ONUF\xb1\x1f\x14\xff\x11\xebtC\xf1_\xec\xc3\x19^\xb3\x934Z\x9ee\x1e+n~B\xfa)\xd6\xe5\xad\xd2\xcf\xc4\x02\x16\xf0\x7f\x92%\xcd\xef\xa6\x08QW;y\x9e`%\xcb\x19i=J\xd8\x1c\x15\x0eC\xc7\xecb\xf2\x1e_\x1c\x98*\x00\x1e\xd7$\xcd\x18\xe8\xa8\xce9M6\x9d\xc6'\xc5\xefY\xff\xd1\x86\xca\xeb\xd832eIwK\xdd\xf4\x9dJ\x1a}~\xf7\x06\xfbp\x06{I\x0f\\WiZ\xa3J\xfa\x97W\xdd*\xd6\xaf\x00\x81\xa4\xf9\xddL\x95IN\x92>$\xa51\\\x17K:y\x8f/\x0e\x20iK\xdc\x934\xd2\x0dt\xb6*c\xa8\xa0\xd5\xec\xe8\x8b\xef\x14S^FhCq\xf1;\xea\x8cuC\xf1\xac\xb7^~`\xf6\xd3\xffCc>y\xe6;\xb3\xeeS\x97\x0d\xe2c\xb5\xde\xab\x7f\xfe\xb8\xab\xbf\xa5\x0e\xbc\x9b&gOxD\xd1\xc0\xa1o\xe5\x8c\xbe\xee\xf6~n\xa3\xf5\x13\x82=ROp\xc2K\x9a\xa4\xd1\x86\xef\xe0\x97/\xdf\xfe\xf1\xdd\x0f\xbc\xfc\x99\xd61\x82\x00\x00\x0f\xfaIDAT9\x0d1j\xfb\xf2\xad\xc7f?\xfc\x06\x9dl\xff\xcf\xf3\xdf\xbd\xf7\x19e\xe0\xad\xc7\xfeqVq\xf1\xa6O\x9e\xbf\x7f\xf6\xd3\xff\xa4\x1b.\xcf6=`M\x95\xf4\xe6[\xc7\x90\xd7\x07o\xbc\xea\xfao\xfc\x92*\xf5g7\x8f\xb9r\xccW\x7fN\x16\xbfw\xc3U7|\x8f\xae\xfc\xf9\xd7\xae\x19s\xb3:\xf0\xd6b\x91\xb1\x9b-xZ\xbe\x02\xad\xc0\xaf-l\x1d\xe7\xb2%iT3Y\xfa\x814:\xf0\xc8\x84\xec\xdbq\xcf\x19\x94\x14&\xd1\x10-%\xfb\xaf\x90\xa4\xe5\x87\xe6\x8f\xcf\xbe}0\x9e\xa3\x04<BJ\x987n\xf4\xb8\xb9\xea\x04\x99\xc9\x19\x93I<\x81\xd6E\xd6\xcd\x8c\x8a\x93\xf6\x18\x09kc\x16q\xc0K\x93\xb2'\xe1\xf4#~-K\x18$m\x85\x8b\x92\xd6\x0dtv5\xd1g`\x06\x04\xd3=\x85?|\xf4N\xf1k\x1f}\xf4W,\x9b\x8ff\xbd\xa6\xceX\xff\xfb\x9dY\xc5\xf7\xbd\xf6\x9b\xbb\x9f!\x11\xffy\xf7c\xbf\xf9\xe05<:\xe7\xd9\xab\x9d[\x87\xc6N\x08\x04o\x93\xa8\xa4+G=\x14\\\x9f3\x89\x0cE\xc3c'\xad\xe9X!\xad\xe16\xea\x9f/M\x94n\x92\xe6\x1d\xd3%\xfdV1\x1e\xf3\xbfP\xfc\xf2\xfbo\xdc\xf70\xb9D\xc7\xd4\xf6\xc2\x9d\x9b\xde\xdft\xe7\xf3x\xe9\x93\xbb\x1fx\xfb\xbd\xa7\x8b\xa9\xa4\xf5\xd8\xcf\xdfy\xe7\xfe\xef\xdf\xfd\xdd\x97\x9f\xff\xfa_i\xd9\xbb\xccg\xa2&\xe9\xefIX\x9d\xb7H\xb7>\xfe\xbd17\xfc\x0a\x7f\xfe\xc9U7|\xfb\x89\xbb$\xa2\xe4[\xae\xbc\xeb\xf1\xbb\xae\xbc\x85\xc8\xfc\xaa\xeb\x1f|\xfc_%*i=\x16\x19\xbb9\x10\x1e\xbb\xfc$:\xb9\xfc\xea0\xdfi\xef\x0d\x87\xb3\xe8\xd5\xb3\x9e\xe6+\xa4\x9c\x15k\xc6~\x8bxz\x87'L\x0d\x87\xc3\xf4\xaa\xa4\x9e\x92XK\xf3W&\x8c\x1d\xf7\xc8|\xe9(\xda\x1fn\x96V\x84\xc3D\xbbA\xa92\xdc2w\xd4\x1e\x12\xcb\xe4\xcc\xc8\xe4\xe0\x89\xf0\xe4\xab\xf5J\xe39\x93w\x1dS\x87\xfaI{,\xae\x8d\xad\x18Uf-\x0f.\xcf\x9a\x8f\xb8\xe60\xf0\xb5\x01<.JZ7\xd0\x19h\x0a\x9e\x8c\xf5\x07\x03-\xd6\xa1\xc6\xc0\xfbNr\xadJ\x19\xde\xdey/\xee'\x9f\xbf\x0f/}~\xff\xd3\xb8K\xfc\xe2\x1d\xf3\xf5\xb3\xa0tDY\x98:\x9e\\\x86\x9b\x94E\xd7\x05\x10\x19\xb8\xe1n+6\xee\xf68y\xda\xb0\xd9_o\xdbhi4\x1d2\xa8\x92~\x1fO\xa6\xdf+~\x1b/\xfd\x1e\x0f\x12\xd8\xda\xde/\xfe\x80\x86\xbd\x8f\xd0\x8f\xbfOV>LZ\xc6\xc4\"\xf4p\xf1\x93\xff@_\xaa\xd7\x01\x8eJ\xa6\xef-M\xd2O\xe0\xc9\xf4\xe3\xd2\x83x\xe9\xdf\xa5\x1f\xe2\x81\xf85\xff\x8a\x85\xfd\xcb\x1f\xbeB\xfe\xf2\xc4f\xf5\xf5\xc6k\xb1\xee\x7fu\x03\x91\xb4\x11\x8b\x98\xddD\x95d,=O0\xd6\xcdV/\x88g]\x8d\xc51?\x87.\xeb\x03o&%x\xadt\x1b>&\xf4\x9a\x98>\xf0\x1eh!\x02\xba\x89\xfc\x0e\xcc\xe4\x8c\xd9l.\xee\xce\x99A\xfa6\xfc\xf1\x9b\xcab\xd2\x1e[\xd6\xa6/n\x93\xc8L\xacC\xb9\xa6\xcd\x04\xe8\x98j\x038\xdc\x944R\x9f\xe3\x8d\xce\x04q\x7f\xbd;hs\x94\xc4\x92~A[|\xbf\xf8\x0f\xc2\xcd\xb6\xaa\xe7\xfa9z\x16\xa1\xe5D\xd2\xf3\xc6\xc7\x071\xe3*\xc9\xb9\xb3_\xb0\xd1\x99GF\x8f\x93\xc6e->\xa3K\xfa\xed\xe2\xcf\xd0\xf3\xf7\x7f\xf1O\xccw_\xe0j{A\xf9\xcd\xea\x81\x0d\xe8\xb3\xe2\xb7\xc8\xd2&\xd2\x1c&\x16K\xfa\xce\xbf\x1ae\x1fUNd\x03M\xd2\x0fJ\xafl\xbe\xf9\xda_\xfe\x0as\xcd-\x9b\xb5\xb5\xb4;V~\xb3\xba\xfe\x96\xcd\xaf\xd0N{\xf3]D\xd2F,2v\x13w\xa1\xd9\x03h\x20[\xf0@t]\xd2D\xee\xea5\x05]\xd2LJ\xf0Z\xe3\x82\x961\x97>\xf9\xd2\xed\xe3\xc7J7!.g\xccfG\xb7\xe9?Fc\x06r\xc6\xaf\xdf\xa16)i\x8f-k\xd3\x17+o\xa2o\x13\xcd\x01:|m\x00\x8fk\x926\x0ct\xc8[\xecL\x025\xd9xb\x89%\xad/\xbeQ\xfc\xb9p\xb3\xdd\xea\xa8O\x1d\x99\xd2Sy\x92:\x89\xc4]\xcezI\xf4\xe8\xf059\x01<\x97^\x9f\xf3\x9c.\xe9_\xdcM:[\x85\xa7\xb9\xda~\xfc4}{\xfa1\xdc'\x7fD\x96hs\x98X\xfc\xe11\xa6\xec=\x92i'5\xf1~\xe3\xaa\xcd\x9boP[\xf6Uu\x1c\xaep\xe3W\xe9\xdbWo\xdc\xfcS\xe9'\xba\xa4\x8dXd\xec&\x1e\x92\xe6lE[s\x12(\x09]\xd2\xe4\xdd,i&%\xf8\xc3$}#]\xd2{\xae\x1b\xb7xk\xf86\"5&g\xdcfxv\xbbG\xfb\xc3\x1e\xc9\xb0\x0aO\xdac\xcb\xda\xf4\xc5\xa9J\x07\xff\xcd\xc9\xa6\x00\x16\xa66\x80\xc7-I3\x06:\xf8D$K\x87\x02\xfcU*\x0e\x93\xa47\x99$\xfdA\xf1\xef\x85\x9b\x0d(SHtF\"\x17[\x10\xbd<6\x7f\xfc^\xcaI2\xb6\xfbP\xb4U\x9c^\xf1&\xf3{E\xd2_\xdc\xf7\x0c\xe9y\x7fO\xf9\x8c\xab\xed\x85\xfb\xc9\x95\xb1/\xef\x7f\x01\xfd\xaf2\x91\x7fA\xe9\xa5\xf5X,\xe9g\x98\xa2W\x8c6\xfd\xca\xab]\xf1\x1es\xf3\xe6\xcd_\xbb\xf6\xa7\x94\x9f\xf3\xbd\xf4\xb5\xf4\xedZ\xbd\x97\xa6\x97\xc7\x8cXd\xec&\xe6\xa1\xb9h\xeeC(\x19KI\x07\x8er)\xc1k\xbf\xa5o\xa4Kz\xe2d\xd2'~\x8bH\x9a\xc9\x19\xb7\x99\xc5\x15\xef\xe4=\xb6\xacM_\xac\x1cO\xdf\xc6W\x9a\x02X\xe0\x8a\xb7%nI\x9a5\xd0\xe9\x09\xe0\xa3{\xae\xd9\xee\xde\x01C\xd2\xb3\x7f\x815\xf6\x98I\xd2\xff\xb8\xefIr\xd9\xea\xe5\x97\xcd\xdb\xcd\x1b\xaf\xf4X\x93\xc7\xe1a\xf4\xa1,r*w(\x97\x83\x97?G~a\x99J\x84\xfbP\x92\x06\x8e]}\x8c\xbe+\x92\xdeD$\xfc\x8123\xde\xf4\x1b\xae\xb6\xf7\xe9\xdaw\xc8\\\xfa\xb1\xfb\xb1\x82\xff2[\xf9\x86\xd1cyI'&~\x13\xf1\xa8\xe2\xbd\x8b\xbc>Af\xd1x\xf9\xdb\x9b7\xbf2\xe6_H7}\xeb7\xc8\xac\x99\xac\xfd\xa1\xf48\xee\xb0\xafy\x85\\##\x926bI)\xdan\xe2\x0e;\xab?Kt\xb2\x8b$=u*B'H6\x98\x94p?m\xe9\x92\x1eGt\x95\x98D$\xcd\xe4\x8c\xdb\xccB\xd2\xc9{lY\x1b3\xb5'c\xf5f\xa5r\x8b_\xda@\xd2\x96\xb8&i\xc6@\xe7P`\xcf\xb1\xfdMA\xeb\xc9\x91r\xc5\xfbw\xf4~\xd0\x1f\xdf\xf7\x9b\xd7\x1e+\x9e\xf5\xf6\x7f\xff\xf5\xa3Y\x1b~\xf7\xe5\x1f6\xcc\"W\xc2\xffs\xf6\x03o\xbd\xff\xb22\x9de94J\xb9\x9a\xdd\x9d=n\xc5\xf2\x9cQW\x90;[\x16K\xf3Z\x82\x95\x12\xb9\xddjG\xd6\xc4\x97\xb6=\xa4L\xb4\x05pw\x8fm\xfa\xfa\xf3\xef\xbc\xf7\x02\x15+S\xdb\xf3\xc5\x9b\xde\xdbTL\xaex\xffq\xf6w_\xdbt/i\x19\x13\xfb\xcf\xff\xfa\xe8\xfbO~\xf4\xd1'j\x81k$\xf3o\xef\xf4\xee\xb1'nQ\xee\x1e\xbbK\xfa\xda\x0f\x1f\xbf\x85^\xf8\xfa\xc9U\xd7\x7f\xef\x89[%r\xa3\xe8\xd7\xa4\xbb\x1e\xc7\x7f\xc1K?\xbd\xea\x9ao\xdf5F\xba\xf2\xc1\x9f1\xb1\xa4\x14m7\xb1\x84\xc6\xdd>\xce<\xee\x8e\xef\x0e\x87\xb3*\xc3\xe1s\xa8?<\xbar7\xda[9\x9a^\xc7^\x91\xb5f\xebm\xd9\xe4\xcbKO\xc9\xe0nz\x1d\x9c\xce\x83\x95+\xde\xbbIi+\xa4y/=7I\xcaY\xb3\x9b\xcb\x19\x93I2\xb9\xd1G\xd8\xc6D@\xb0\xc7\xe2\xda\xd8\x8a\xd1\xfcQ\x8b\x83\x8bG\xcd7\xad\xe5\xd8\x9b4\x9e\x07T\\\x934k\xa0\xf3aK\x20\xf8\xa1`\x02\xa8\xf2\xf9\xbdtf:\xeb/\xe4\xc3'O\xce\xbe\xfb\xe9M\xc5\xc5\x1b6\x90U\x7f\xb8\x1b\xbf\x92\x1bA\xfe\xf2\xccw\xef~\xec\xbd\xe4m\x97g)\x87\xfe\xd0\xdc\x9c\xf1\x8b\x03WH?\xc0\xcb\x1d\xb7\xe5\\=U\xf9\x11\xfc\xd0\xbcqc'oM\xdeL\x81\xde\xe3]|\xbf\xfaE\xf1\xc1\x93\xdf\xb9\xf7\xc7\xef\xd3E\xa3\xb6/\xdexx\xf6\xc3o\xd0/\x9bO\x9e\xbe\xf7\xfe_\xbc=\x8b6G\x8b\xfd#3\xa9&\x17\xaf\x92n\xf2R\xee\xf1\xbeV\xf9\xd9y\xf3\x13\xff2f\xcc\x8dO\xd0\xc5\x9f\xdd|\xcdU7>N\x96~E\x7f\x97\xfe\x15]\xf9\xd51\xd7~\xe3\xc1+\xa5[\x99XZ\x8c\xb6\x9bx\xae\x9b\xc5\xff$\x87\xd93J\x99\xbc\x06\xd0\x0f\xf0\xeb\xe8\xeel\xfcJ\xf2\x10\x7f('{\xaa2%\xd5R\xb2_\x09%=k\xfcj\xbax\x05\xf9\x95+\xb1fBV\xce\xbc\xc0\xf8\xd1\xb8_gs\xc6d\x12\x9d\xb8b\xde\xfe\x13\xf8\x20\xc6\xfb\xf7\xce\xcb\xd2\xe6P\x82=\x16\xd7\xc6,\xe2\xea\xd6\xdf\x94}\xd3K\x09\xd3Z\x0e\xad6\x20\x09\xf7$}\x89xht\x8bS\xc8\xa5\xa2yt\xa5\xf9\x8e\x89\x8b\xf6\x9fX\x97\xc1nn\x9dH/y\xcd\x95\xa4\xafh\x17\xcaE{|\x91Pk\x03\x92\xf0\xbc\xa4\xd1\x9aq'\x9cB.\x0dg\xae{.y\xa5\x93`\x9dQ\x0b\xba\x1cv\xf3\xc4~\xdc;\xf7\x7fxL\xfb,\xdc\xe3\x8b\x06\xad\x0dH\xc2\xfb\x92\xbe\xbcq\x12\xac3N5\x00\x19\x06H\xda]\x9c\x04\xeb\x8cS\x0d@\x86\x01\x92v\x17'\xc1:\xe3T\x03\x90a\x80\xa4\xdd\xc5I\xb0\xce8\xd5\x00d\x18\x20iwq\x12\xac3N5\x00\x19\x06H\x1a\x00<\x05H\x1a\x00<\x05H\x1a\x00<\x05H\x1a\x00<\x05H\xda+\xc0\x0d\xcf\x00\x05$\xed\x09\xc0N\x06\xd0\x00I{\x01\xb0\x93\x01t\\\x95tw@\xfd\x97\x9d\xfe`\xa0\xc3\x9d{\xf0\x19g\x19\x0b\xb7\x18{S\x9c!\x13\xbc:\xf5\x07\xe2i\x8d\xac\x94$)\xfb\x90\x20\x00\xecd\x00\x1d7%}.\xb0K\xf9\xef\xf9c\x81\xf0\xa1p@\xff\x07\x9eK\x09\xe3,c\xe1\x16\xe3`\x8a3T\x16KN\x06\x19\x06Z#\x8f\x86\xc3/\x09\x9f\xe6\x01v2\x80\x8e\x9b\x92\x0ev\x1c\xa3\x92N4\x93\xff\xdf\xdf\xd5\xec\xca\x05\x1e\xbdRk\xb7\x18{\x07\x8d!\xb2\\Z\xee\x14b`dF\xfc\x80\x1exl\x0f\xa0\xe3\xa2\xa4\xbb\x9b\x06\xfa\xa9\xa4{\x02\xe4\xa1\x93\xd4\x1e\xcbE\xac\xddb\x86E\xd2+\xec\xad&\xad\x00I\x03\x0e\xb8'\xe9s\x81CH\x91t\x872\x11\xdc&x\xfc\xf4\xf0b8\xcb\xb0n1,\"S\x1cda\xd7#r\xcd1\x1b\xe8\x18\xacQ<>\x8e\x8eU*\x96\xc6\xb2\xf3\x0e\xc6\xe8\x86i$A,^\xb0\x93\x01t\xdc\x9341\xb7S$\xbdUyn\xd6.\xcbg\x80\x0d\x1b\xba\xb3\x0c\xeb\x16\xc3\x204\xc5\xb1\xb2\xeb\x11\xb9\xe6\x98\x0dt\x0c\xd6K\xd4\xa65\xde\xb4^!\x10g\xfe\xc8\x18\xdd\xb0\x8dDBI\x83\x9d\x0c\xc0\xe2\x9a\xa4{\x88\xf7\xac\"\xe9&\xe5\x91v{\xec-\x92\x87\x09\xedi\xb8\xc2\x81\xb7\xd8\x14Gl\xd7c\xe5\x9a\xc3\x19\xe8\x18\x04\xd4\xe7\x92\x9e8\xa2`z\xcc\x10kt\xc34R$\xe9\xb9\x12\xd8\xc9\x00\x06nI\x1a\xcf\x9c\x13\x89\xc4\xd1\xa6DBw\xae\x0c_\xfa^\x1a\xd9K\xda\xc2\x14Gl\xd7c\xe5\x9a\xc3\x19\xe8\x184)\xcf\xca=\"i\xf0O\xb6e\x8dn\x1c$\x0dv2\x00\x8b[\x92>\x12\xd0\xe8G\x1d\x8a\x96\x82\x97|.M\xb0\x93\xb4\x85)\x8e\xd8\xae\xc7\xca5\x873\xd01\xd8u\xb5\xa2\xcdpP\xc1\xf4+\x14\xfb\x08}\x07I#\xb0\x93\x01\x18\xdc\x92t\xe2$\xa1;p\xf2d\x02\x8f\xc1\xc9\xaf\xc1\xe7\xdc\xb9\xe2m'i\x0bS\x1c\xb1]\x8f\x95k\x0eg\xa0\x932\xe9I\x1a\xaex\x03:nIZ\xa1_\xfd]\x9atQ;\xdc\xf9]\xdav.-6\xc5\xe1\xedz\x8e<\xa7\x0c\x99\xad\\s\xac$m\xbf\xb7\x20i`\x88\xb8)\xe9D\x7fw\xa0\x9fx;\x1f\x0d\xec8\x12&~k\x97\x18\xc3Y\x86u\x8ba\x10\x9a\xe2\x98\xecz\xe6J\xb7+\xc1\"\xd7\x1c\x93\x81\x0eCp\xac\xcd%-\xd6\xe8\x86i\xe41r\xf7\xd8\xfap8)S`'\x03\xe8\xb8)\xe9~2\x95\xa6\xbf\xb8\xf6o\x0b\x04]\xb8\xc7\xdbp\x96a\xddbXD\xa68\x88\xb7\xeb\x09\xe4h\x96Z\x02\xd7\x1c\xde@\x87e[\x8e\xcdm\xd9\xac\xd1\x8d\xd1Hz\x8f7!\xc9\xf9\x0d\xecd\x00\x1d7%\x0d\\4\xc0N\x06\xd0\x00I{\x04\xb0\x93\x01\x14@\xd2\x00\xe0)@\xd2\x00\xe0)@\xd2\x00\xe0)@\xd2\x00\xe0)@\xd2\x00\xe0)@\xd2\x00\xe0)@\xd2\x00\xe0)@\xd2\x00\xe0)@\xd2\x00\xe0)@\xd2\x00\xe0)@\xd2\x00\xe0)@\xd2\x00\xe0)\\\x95\xb4n\xa0\x83P\xd8\x95G\x9a\x8c\x14\x86\xc9\xc4\x07\xf0\"nJZ7\xd0A\xe8D\x20\x13\x1e\x9e\xb5c\xafS\x84\x05\xc3d\xe2\x03x\x117%\xad\x19\xe8\x20\xd4\xdf\x92\x11\x92\x9e\x9c\xf4\xec\x82\x94\x19\x16\xc7\x0f\xc0\x8b\xb8(i\xdd@\x07\x85\x03\xe1\x8c\x90\xf4$\x9040\xec\xb8'i\xc3@\x07\xc5\x06\xb4\xc7\xf3{\x82\xfdWH\xd2\xf2C\xf3\xc7g\xdf>\x88?5M\xce\x9e\xf0\xc8\x00\x1e\x93\xa8O\x19\x9aD\x9eC4\xaa\x09\x1d\x19-M\xe4bY\xd7\x1c\x96\xe13\xf1\x01\xbc\x88{\x926\x0ct\x08^\x92t\xac\xa5\xf9+\x13\xc6\x8e{d\xbe\x84\xd5Y9\xea\xa1\xe0\xfa\x9cI\x094\xb0+<aj8L\xae\x03\xf6\x87G\xaf@hwe\x16\x17\xcb\xb9\xe6\x18\x0c\xa3\x89\x0f\xe0E\\\x934c\xa0C\xf0\x92\xa41\x93\xa4\xdb\xce\xe1\x81\x08\xe9\x9b\xc9\xc3\x06\xf7H\xf4\xa9\x89\xc6\xc0\x9b}\xa6\xaf\x1ekr\xcdQ\x19F\x13\x1f\xc0\x8b\xb8%i\xd6@\x87\xe05Ig\xa9\xc3\xe7y\xe3\xe3\x83\x98q\x95t\xadX\xd2Z\xac\xc95Ga8M|\x00/\xe2\x96\xa4Y\x03\x1d\x82\xd7$=I[Pg\xd0\xf4\xf1\x9d\x16\x92\xd6bM\xcf\xe3W\x18N\x13\x1f\xc0\x8b\xb8%i\xd6@\x87\xe05Ik\x13\xe2\xf9\xe3\xf7RN\xd2\xb5D\xd2\xd4\x82\x80\x8awy\x16\x1f+\x94\xb4\x8b&>\xc0\x88\xc4-I+xw.\xad\xf5\xc7\x1dR\x0by[\xfe\x1cy\x9d:\x15\xa1\x13tE\xf6b\xfc\xad69\x8b\x8f\x15JzXM|\x00\x0f\xe2\xa6\xa4u\x03\x9dX\x7f\x7f`G\xbf\xc9ay\xe42\xb8\x9b^\xdbVT\xb6X\x9a\xd7\x12\xacT\x9cgWd\xad\xd9z[\xf61\xbc45\xe7\xb9\xe7&KW\x04z\x98X\xd65\x87a\x18M|\x00/\xe2\xa6\xa4u\x03\x9d\xbd\xca\xac\xfa\x9c\xd3\x06#\x84\xfd\x8a\xe5\xcd7\x95O\x1d\xb7\xe5\\=U1\xcb\x89?\x94\x93=\x95\x0eG\x0eM\xcd\x1e{\xfbbI\xfa\x01\x13\xcb\xba\xe6\xb0\x0c\x9f\x89\x0f\xe0E\xdc\x944\x00\x00\x17\x1d\x904\x00x\x0a\x904\x00x\x0a\x904\x00x\x0a\x904\x00x\x0a\x904\x00x\x0a\x904\x00x\x0a\x904\x00x\x0a\x904\x00x\x0a\x904\x00x\x0a\x904\x00x\x0a\x904\x00x\x8a\x8c\x96\xf4<)g>X\x02\x00\xde\"\xa3%\xdd\xbf#01g\xc0)\x0a\x00F\x12\xaeJZ3\xd0\x19\x08\xb7\x04\x82\xfb\x07\x1d\xa2\x87\x85\xb0\xb4\xdf)\x04\x00F\x12nJZ3\xd09\x17\x08v\x1f\xd9\xdb\xb4\xd5\x0dM\xef\x91v;\x85\x00\xc0H\xc2MIk\x06:;Z\xc8\xf3\xc7\xce\x04\x86\xea\x18u!\x80\xa4\x01\x8f\xe1\xa2\xa4u\x03\x9d\xad-\xf4\xf3\x0e\xdd\xc6\xf2\x12\x02\x92\x06<\x86{\x926\x0ct\xfa\x8f\xd1\x15\xbb\xb6\xd8\xc6\x0f\x0f\xddR\xd8)\x04\x00F\x12\xeeI\x9a7\xd0A(\xd1\xec\x86\xb8\xe29\x93w\x1dK8E\x01\xc0\x88\xc15I\x9b\x0ctp'\x1d8c\x1d=|l3\x1e\xfc\x07\x00\x1e\xc0-I\x9b\x0dt\xd0\xee\xc0\x11\xdb\x0d\x86\x89\x81\x9c\xf1\xebw\xb8R3\x00\x0c\x0bnI\xdad\xa03\xb8#\xe0\xcem\\{\xa4\x0e\xa7\x10\x00\x18I\xb8%i\xde@g\x20\xd8\xc4=\x8e\xfe\xd2\x01W\xbc\x01\x8f\xe1\x96\xa4\x15\xd4\xb9\xf4\x99\xe6-\xe7\xb0\xcac\x0e\xd1\xc3\x01H\x1a\xf0\x18nJZ3\xd09\x1ah>\xd2\xdf\xdf\xbf\xab\xc5i\x83a`7H\x1a\xf0\x16nJZ3\xd0\xd9\xa6\xce\xaa/\xf9\xad&\xf1\xfe\xbd\xf3\xb2\\\x1a\xf1\x03\xc0\xf0\xe0\xa6\xa4]g\xae$}\xe5\x92\x7f\x8f\x00\xc0\xb0\x92\xd1\x92\xee\xff\xf0\x98S\x08\x00\x8c02Z\xd2\x00\xe0=@\xd2\x00\xe0)@\xd2\x00\xe0)@\xd2\x00\xe0)@\xd2\x00\xe0)@\xd2\x00\xe0)@\xd2\x00\xe0)\xfe??\xe8B\x81\x97E\xcd\x14\x00\x00\x00\x00IEND\xaeB`\x82",
 
@@ -45,9 +45,11 @@
 
 	"error.html": "<!--\x0a\x09Copyright\x202009\x20The\x20Go\x20Authors.\x20All\x20rights\x20reserved.\x0a\x09Use\x20of\x20this\x20source\x20code\x20is\x20governed\x20by\x20a\x20BSD-style\x0a\x09license\x20that\x20can\x20be\x20found\x20in\x20the\x20LICENSE\x20file.\x0a-->\x0a\x0a<p>\x0a<span\x20class=\"alert\"\x20style=\"font-size:120%\">{{html\x20.}}</span>\x0a</p>\x0a",
 
-	"example.html": "<div\x20id=\"example_{{.Name}}\"\x20class=\"toggle\">\x0a\x09<div\x20class=\"collapsed\">\x0a\x09\x09<p\x20class=\"exampleHeading\x20toggleButton\">\xe2\x96\xb9\x20<span\x20class=\"text\">Example{{example_suffix\x20.Name}}</span></p>\x0a\x09</div>\x0a\x09<div\x20class=\"expanded\">\x0a\x09\x09<p\x20class=\"exampleHeading\x20toggleButton\">\xe2\x96\xbe\x20<span\x20class=\"text\">Example{{example_suffix\x20.Name}}</span></p>\x0a\x09\x09{{with\x20.Doc}}<p>{{html\x20.}}</p>{{end}}\x0a\x09\x09{{$output\x20:=\x20.Output}}\x0a\x09\x09{{with\x20.Play}}\x0a\x09\x09\x09<div\x20class=\"play\">\x0a\x09\x09\x09\x09<div\x20class=\"input\"><textarea\x20class=\"code\"\x20spellcheck=\"false\">{{html\x20.}}</textarea></div>\x0a\x09\x09\x09\x09<div\x20class=\"output\"><pre>{{html\x20$output}}</pre></div>\x0a\x09\x09\x09\x09<div\x20class=\"buttons\">\x0a\x09\x09\x09\x09\x09<a\x20class=\"run\"\x20title=\"Run\x20this\x20code\x20[shift-enter]\">Run</a>\x0a\x09\x09\x09\x09\x09<a\x20class=\"fmt\"\x20title=\"Format\x20this\x20code\">Format</a>\x0a\x09\x09\x09\x09\x09{{if\x20not\x20$.GoogleCN}}\x0a\x09\x09\x09\x09\x09<a\x20class=\"share\"\x20title=\"Share\x20this\x20code\">Share</a>\x0a\x09\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09</div>\x0a\x09\x09\x09</div>\x0a\x09\x09{{else}}\x0a\x09\x09\x09<p>Code:</p>\x0a\x09\x09\x09<pre\x20class=\"code\">{{.Code}}</pre>\x0a\x09\x09\x09{{with\x20.Output}}\x0a\x09\x09\x09<p>Output:</p>\x0a\x09\x09\x09<pre\x20class=\"output\">{{html\x20.}}</pre>\x0a\x09\x09\x09{{end}}\x0a\x09\x09{{end}}\x0a\x09</div>\x0a</div>\x0a",
+	"example.html": "<div\x20id=\"example_{{.Name}}\"\x20class=\"toggle\">\x0a\x09<div\x20class=\"collapsed\">\x0a\x09\x09<p\x20class=\"exampleHeading\x20toggleButton\">\xe2\x96\xb9\x20<span\x20class=\"text\">Example{{example_suffix\x20.Name}}</span></p>\x0a\x09</div>\x0a\x09<div\x20class=\"expanded\">\x0a\x09\x09<p\x20class=\"exampleHeading\x20toggleButton\">\xe2\x96\xbe\x20<span\x20class=\"text\">Example{{example_suffix\x20.Name}}</span></p>\x0a\x09\x09{{with\x20.Doc}}<p>{{html\x20.}}</p>{{end}}\x0a\x09\x09{{$output\x20:=\x20.Output}}\x0a\x09\x09{{with\x20.Play}}\x0a\x09\x09\x09<div\x20class=\"play\">\x0a\x09\x09\x09\x09<div\x20class=\"input\"><textarea\x20class=\"code\"\x20spellcheck=\"false\">{{html\x20.}}</textarea></div>\x0a\x09\x09\x09\x09<div\x20class=\"output\"><pre>{{html\x20$output}}</pre></div>\x0a\x09\x09\x09\x09<div\x20class=\"buttons\">\x0a\x09\x09\x09\x09\x09<a\x20class=\"run\"\x20title=\"Run\x20this\x20code\x20[shift-enter]\">Run</a>\x0a\x09\x09\x09\x09\x09<a\x20class=\"fmt\"\x20title=\"Format\x20this\x20code\">Format</a>\x0a\x09\x09\x09\x09\x09<a\x20class=\"share\"\x20title=\"Share\x20this\x20code\">Share</a>\x0a\x09\x09\x09\x09</div>\x0a\x09\x09\x09</div>\x0a\x09\x09{{else}}\x0a\x09\x09\x09<p>Code:</p>\x0a\x09\x09\x09<pre\x20class=\"code\">{{.Code}}</pre>\x0a\x09\x09\x09{{with\x20.Output}}\x0a\x09\x09\x09<p>Output:</p>\x0a\x09\x09\x09<pre\x20class=\"output\">{{html\x20.}}</pre>\x0a\x09\x09\x09{{end}}\x0a\x09\x09{{end}}\x0a\x09</div>\x0a</div>\x0a",
 
-	"godoc.html": "<!DOCTYPE\x20html>\x0a<html>\x0a<head>\x0a<meta\x20http-equiv=\"Content-Type\"\x20content=\"text/html;\x20charset=utf-8\">\x0a<meta\x20name=\"viewport\"\x20content=\"width=device-width,\x20initial-scale=1\">\x0a<meta\x20name=\"theme-color\"\x20content=\"#375EAB\">\x0a{{with\x20.Tabtitle}}\x0a\x20\x20<title>{{html\x20.}}\x20-\x20Go\x20Documentation\x20Server</title>\x0a{{else}}\x0a\x20\x20<title>Go\x20Documentation\x20Server</title>\x0a{{end}}\x0a<link\x20type=\"text/css\"\x20rel=\"stylesheet\"\x20href=\"/lib/godoc/style.css\">\x0a{{if\x20.TreeView}}\x0a<link\x20rel=\"stylesheet\"\x20href=\"/lib/godoc/jquery.treeview.css\">\x0a{{end}}\x0a<script>window.initFuncs\x20=\x20[];</script>\x0a<script\x20src=\"/lib/godoc/jquery.js\"\x20defer></script>\x0a{{if\x20.TreeView}}\x0a<script\x20src=\"/lib/godoc/jquery.treeview.js\"\x20defer></script>\x0a<script\x20src=\"/lib/godoc/jquery.treeview.edit.js\"\x20defer></script>\x0a{{end}}\x0a\x0a{{if\x20.Playground}}\x0a<script\x20src=\"/lib/godoc/playground.js\"\x20defer></script>\x0a{{end}}\x0a{{with\x20.Version}}<script>var\x20goVersion\x20=\x20{{printf\x20\"%q\"\x20.}};</script>{{end}}\x0a<script\x20src=\"/lib/godoc/godocs.js\"\x20defer></script>\x0a</head>\x0a<body>\x0a\x0a<div\x20id='lowframe'\x20style=\"position:\x20fixed;\x20bottom:\x200;\x20left:\x200;\x20height:\x200;\x20width:\x20100%;\x20border-top:\x20thin\x20solid\x20grey;\x20background-color:\x20white;\x20overflow:\x20auto;\">\x0a...\x0a</div><!--\x20#lowframe\x20-->\x0a\x0a<div\x20id=\"topbar\"{{if\x20.Title}}\x20class=\"wide\"{{end}}><div\x20class=\"container\">\x0a<div\x20class=\"top-heading\"\x20id=\"heading-wide\"><a\x20href=\"/pkg/\">Go\x20Documentation\x20Server</a></div>\x0a<div\x20class=\"top-heading\"\x20id=\"heading-narrow\"><a\x20href=\"/pkg/\">GoDoc</a></div>\x0a<a\x20href=\"#\"\x20id=\"menu-button\"><span\x20id=\"menu-button-arrow\">&#9661;</span></a>\x0a<form\x20method=\"GET\"\x20action=\"/search\">\x0a<div\x20id=\"menu\">\x0a{{if\x20(and\x20.Playground\x20.Title)}}\x0a<a\x20id=\"playgroundButton\"\x20href=\"http://play.golang.org/\"\x20title=\"Show\x20Go\x20Playground\">Play</a>\x0a{{end}}\x0a<span\x20class=\"search-box\"><input\x20type=\"search\"\x20id=\"search\"\x20name=\"q\"\x20placeholder=\"Search\"\x20aria-label=\"Search\"\x20required><button\x20type=\"submit\"><span><!--\x20magnifying\x20glass:\x20--><svg\x20width=\"24\"\x20height=\"24\"\x20viewBox=\"0\x200\x2024\x2024\"><title>submit\x20search</title><path\x20d=\"M15.5\x2014h-.79l-.28-.27C15.41\x2012.59\x2016\x2011.11\x2016\x209.5\x2016\x205.91\x2013.09\x203\x209.5\x203S3\x205.91\x203\x209.5\x205.91\x2016\x209.5\x2016c1.61\x200\x203.09-.59\x204.23-1.57l.27.28v.79l5\x204.99L20.49\x2019l-4.99-5zm-6\x200C7.01\x2014\x205\x2011.99\x205\x209.5S7.01\x205\x209.5\x205\x2014\x207.01\x2014\x209.5\x2011.99\x2014\x209.5\x2014z\"/><path\x20d=\"M0\x200h24v24H0z\"\x20fill=\"none\"/></svg></span></button></span>\x0a</div>\x0a</form>\x0a\x0a</div></div>\x0a\x0a{{if\x20.Playground}}\x0a<div\x20id=\"playground\"\x20class=\"play\">\x0a\x09<div\x20class=\"input\"><textarea\x20class=\"code\"\x20spellcheck=\"false\">package\x20main\x0a\x0aimport\x20\"fmt\"\x0a\x0afunc\x20main()\x20{\x0a\x09fmt.Println(\"Hello,\x20\xe4\xb8\x96\xe7\x95\x8c\")\x0a}</textarea></div>\x0a\x09<div\x20class=\"output\"></div>\x0a\x09<div\x20class=\"buttons\">\x0a\x09\x09<a\x20class=\"run\"\x20title=\"Run\x20this\x20code\x20[shift-enter]\">Run</a>\x0a\x09\x09<a\x20class=\"fmt\"\x20title=\"Format\x20this\x20code\">Format</a>\x0a\x09\x09{{if\x20not\x20$.GoogleCN}}\x0a\x09\x09<a\x20class=\"share\"\x20title=\"Share\x20this\x20code\">Share</a>\x0a\x09\x09{{end}}\x0a\x09</div>\x0a</div>\x0a{{end}}\x0a\x0a<div\x20id=\"page\"{{if\x20.Title}}\x20class=\"wide\"{{end}}>\x0a<div\x20class=\"container\">\x0a\x0a{{if\x20or\x20.Title\x20.SrcPath}}\x0a\x20\x20<h1>\x0a\x20\x20\x20\x20{{html\x20.Title}}\x0a\x20\x20\x20\x20{{html\x20.SrcPath\x20|\x20srcBreadcrumb}}\x0a\x20\x20</h1>\x0a{{end}}\x0a\x0a{{with\x20.Subtitle}}\x0a\x20\x20<h2>{{html\x20.}}</h2>\x0a{{end}}\x0a\x0a{{with\x20.SrcPath}}\x0a\x20\x20<h2>\x0a\x20\x20\x20\x20Documentation:\x20{{html\x20.\x20|\x20srcToPkgLink}}\x0a\x20\x20</h2>\x0a{{end}}\x0a\x0a{{/*\x20The\x20Table\x20of\x20Contents\x20is\x20automatically\x20inserted\x20in\x20this\x20<div>.\x0a\x20\x20\x20\x20\x20Do\x20not\x20delete\x20this\x20<div>.\x20*/}}\x0a<div\x20id=\"nav\"></div>\x0a\x0a{{/*\x20Body\x20is\x20HTML-escaped\x20elsewhere\x20*/}}\x0a{{printf\x20\"%s\"\x20.Body}}\x0a\x0a<div\x20id=\"footer\">\x0aBuild\x20version\x20{{html\x20.Version}}.<br>\x0aExcept\x20as\x20<a\x20href=\"https://developers.google.com/site-policies#restrictions\">noted</a>,\x0athe\x20content\x20of\x20this\x20page\x20is\x20licensed\x20under\x20the\x0aCreative\x20Commons\x20Attribution\x203.0\x20License,\x0aand\x20code\x20is\x20licensed\x20under\x20a\x20<a\x20href=\"/LICENSE\">BSD\x20license</a>.<br>\x0a<a\x20href=\"/doc/tos.html\">Terms\x20of\x20Service</a>\x20|\x0a<a\x20href=\"http://www.google.com/intl/en/policies/privacy/\">Privacy\x20Policy</a>\x0a</div>\x0a\x0a</div><!--\x20.container\x20-->\x0a</div><!--\x20#page\x20-->\x0a</body>\x0a</html>\x0a",
+	"favicon.ico": "\x00\x00\x01\x00\x02\x00\x20\x20\x00\x00\x01\x00\x20\x00\xa8\x10\x00\x00&\x00\x00\x00\x10\x10\x00\x00\x01\x00\x08\x00h\x05\x00\x00\xce\x10\x00\x00(\x00\x00\x00\x20\x00\x00\x00@\x00\x00\x00\x01\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00TN8\xffTN8\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xffTN8\xffTN8\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00TN8\xffTN8\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xffTN8\xffTN8\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00TN8\xffTN8\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xffTN8\xffTN8\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00TN8\xffTN8\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xffTN8\xffTN8\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00TN8\xffTN8\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xffTN8\xffTN8\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00TN8\xffTN8\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xffTN8\xffTN8\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00TN8\xffTN8\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xffTN8\xffTN8\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00TN8\xffTN8\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xffTN8\xffTN8\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00TN8\xffTN8\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xffTN8\xffTN8\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00TN8\xffTN8\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xffTN8\xffTN8\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00TN8\xffTN8\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xffTN8\xffTN8\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00TN8\xffTN8\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xffTN8\xffTN8\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00TN8\xffTN8\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xda\xc1e\xff\xc6\xb0\\\xff\xc6\xb0\\\xff\xdf\xc6h\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xffTN8\xffTN8\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00TN8\xffTN8\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xe6\xe1\xcd\xff\xfb\xfc\xff\xff\xfb\xfc\xff\xff\xe2\xda\xbc\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xffTN8\xffTN8\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00TN8\xffTN8\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xf8\xdcs\xff\xe6\xcck\xff\xf1\xf0\xea\xff\xfb\xfc\xff\xff\xfb\xfc\xff\xff\xe9\xe5\xd7\xff\xe4\xcaj\xff\xf8\xdcs\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xffTN8\xffTN8\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00TN8\xffTN8\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfb\xdeu\xff\xa9\x9a`\xff\x94\x93|\xff\x94\x9f\xb7\xff\x9a\xa6\xc1\xff\x9b\xa7\xc2\xff\x93\x9c\xb0\xff\x96\x93z\xff\xb0\x9f_\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xffTN8\xffTN8\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00TN8\xffTN8\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xf8\xdcy\xffv\x8d\xc0\xfft\x8c\xc3\xfft\x8c\xc3\xfft\x8c\xc3\xfft\x8c\xc3\xfft\x8c\xc3\xfft\x8c\xc3\xff|\x8f\xb7\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xffTN8\xffTN8\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00TN8\xffTN8\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe2{\xff\xfe\xee\xb1\xff\xff\xf7\xd9\xff\xff\xf9\xe3\xff\xff\xf5\xcf\xff\xa0\xa9\xb5\xfft\x8c\xc3\xffSb\x85\xff39I\xff5<L\xffYj\x90\xfft\x8c\xc3\xff\xb0\xb4\xb2\xff\xff\xf2\xc3\xff\xff\xf3\xc9\xff\xfe\xee\xaf\xff\xfe\xe3\x7f\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xffTN8\xffTN8\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00TN8\xffTN8\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe4\x84\xff\xff\xfa\xe8\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff\xcc\xca\xbd\xff\x1f\x20#\xff\x1f\x20#\xff\x1f\x20#\xff'(*\xff\xdd\xde\xd7\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfd\xf4\xff\xfe\xe8\x98\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xffTN8\xffTN8\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00TN8\xffTN8\xff\xfe\xe1v\xff\xfe\xe1v\xff\xff\xf8\xde\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xa0\x97v\xffLG4\xffQK5\xff\xb3\xad\x9a\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfd\xf7\xff\xfe\xe4\x85\xff\xfe\xe1v\xff\xfe\xe1v\xffTN8\xffTN8\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00TN8\xf3TN8\xff\xf8\xdct\xff\xfe\xe8\x95\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf6\xf6\xf6\xff_ac\xff(*.\xff{}\x7f\xff\xfe\xfb\xef\xff\xfe\xe1w\xff\xfe\xe7\x91\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xd4\xd4\xd5\xff@AD\xff126\xff\xb3\xb4\xb5\xff\xff\xf1\xc1\xff\xfe\xe1v\xff\xf8\xdct\xffTN8\xffTN8\xf3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00TN8\xdaTN8\xff\xeb\xd0o\xff\xfe\xee\xb3\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x97\x98\x9a\xff\x11\x13\x17\xff\x11\x13\x17\xff\x11\x13\x17\xff\xc1\xc2\xc3\xff\xfe\xe5\x86\xff\xfe\xee\xb1\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffPQT\xff\x11\x13\x17\xff\x11\x13\x17\xff\x1f!%\xff\xfc\xf5\xdd\xff\xfe\xe1v\xff\xea\xd0o\xffTN8\xffSN8\xd9\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00UO7\xafTN8\xff\xca\xb5c\xff\xfe\xef\xb4\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x96\x96\x98\xff\x11\x13\x17\xff\x11\x13\x17\xff\x11\x13\x17\xff\xc0\xc0\xc1\xff\xfe\xe5\x87\xff\xfe\xee\xb1\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffOPS\xff\x11\x13\x17\xff\x11\x13\x17\xff\x1e\x20$\xff\xfb\xf4\xdc\xff\xfe\xe1v\xff\xc9\xb3b\xffTN8\xffTN8\xb1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00TN9UWR9\xf4\x90\x81N\xff\xe2\xc9l\xff\xfe\xe8\x97\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf5\xf5\xf5\xff[\\_\xff%&*\xffvwy\xff\xfe\xfb\xf1\xff\xfe\xe1w\xff\xfe\xe7\x93\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xd1\xd2\xd2\xff;=@\xff,.1\xff\xb0\xb0\xb2\xff\xff\xf2\xc2\xff\xfe\xe1v\xff\xd8\xc0h\xffxmE\xffTN8\xf8TO9g\x00\x00\x00\x00TL9CWP9\xfe\xd2\xbbf\xff\xed\xd2p\xff\xfc\xdfv\xff\xfd\xe0v\xff\xff\xf8\xe0\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xee\xb3\xff\xfe\xe1v\xff\xfe\xe1v\xff\xff\xf7\xd9\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfd\xf8\xff\xfe\xe5\x86\xff\xfe\xe1v\xff\xfe\xe1v\xff\xf7\xdbs\xff\xa2\x91T\xffTN8\xffUO8WUN8\xbb\x82vI\xff\xf3\xd8s\xff\x9d\x8dS\xff\x9d\x8eR\xff\xf6\xdas\xff\xfd\xe3\x84\xff\xff\xfa\xea\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf4\xcb\xff\xfe\xe1w\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe3\x81\xff\xff\xf8\xe0\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfd\xf6\xff\xfe\xe9\x9a\xff\xfe\xe0v\xff\xd6\xbeg\xff\x98\x89Q\xff\xb1\x9fY\xff\xf5\xd9s\xffTN8\xffUN8\xd0TO8\xe0kb@\xff\xfa\xdet\xff\xf9\xddu\xff\xfe\xe1v\xff\xc9\xb3b\xff\x92\x83N\xff\xf5\xdby\xff\xfe\xef\xb4\xff\xff\xf7\xdd\xff\xff\xf9\xe5\xff\xff\xf5\xd2\xff\xfe\xea\xa0\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1w\xff\xfe\xeb\xa3\xff\xff\xf3\xc7\xff\xff\xf4\xcc\xff\xfe\xee\xb3\xff\xfe\xe3\x80\xff\xf5\xd9s\xff\xa1\x91T\xff\xe9\xcfn\xff\xf7\xdbs\xff\xed\xd2p\xff\xdb\xc3i\xffTN8\xffTN8\xf5UN7\xc1TN8\xff~rG\xff\xb2\xa0[\xff\x8c~M\xffTN8\xffTN8\xffh_?\xff\xc0\xac_\xff\xf9\xdct\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xfe\xe1v\xff\xf8\xdct\xff\xc0\xac_\xffg_?\xffTN8\xff]U;\xff\xa3\x92U\xff\xaa\x99W\xffe]>\xffTN8\xffSM8\xd6TL9CTN8\xfcTN8\xffTN8\xffTN8\xffTN8\xffTO8\xe3TN8\xffTN8\xff_W;\xff\x92\x84O\xff\xb4\xa1[\xff\xd4\xbdg\xff\xe7\xcdm\xff\xf1\xd6q\xff\xfa\xdet\xff\xfa\xdet\xff\xf1\xd6q\xff\xe7\xcdm\xff\xd4\xbdg\xff\xb4\xa1[\xff\x92\x84O\xff_W;\xffTN8\xffTN8\xffUN9\xdcTN8\xffTN8\xffTN8\xffTN8\xffTN8\xfeUO8W\x00\x00\x00\x00TO6=TO9\xb9TN8\xdeUN8\xcaUN8i\x00\x00\x00\x02SM9YSN8\xdfTN8\xffTN8\xffTN8\xffTN8\xffTN8\xffTN8\xffTN8\xffTN8\xffTN8\xffTN8\xffTN8\xffTN8\xffTN8\xffTN8\xffSN8\xdcSM8V\x00\x00\x00\x01TN8[TN8\xc3SN8\xdfTN8\xc0TM8I\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00UUU\x03RN7ATO8\x92TO8\xbcTN8\xdeTN8\xeeTN8\xeeTN8\xffTN8\xffTN8\xf1TN8\xeeTN8\xe3TO8\xbcTN7\x8fTO6=\x80\x80\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xc0\x00\x00\x03\xc0\x00\x00\x03\xc0\x00\x00\x03\xc0\x00\x00\x03\xc0\x00\x00\x03\xc0\x00\x00\x03\xc0\x00\x00\x03\xc0\x00\x00\x03\xc0\x00\x00\x03\xc0\x00\x00\x03\xc0\x00\x00\x03\xc0\x00\x00\x03\xc0\x00\x00\x03\xc0\x00\x00\x03\xc0\x00\x00\x03\xc0\x00\x00\x03\xc0\x00\x00\x03\xc0\x00\x00\x03\xc0\x00\x00\x03\xc0\x00\x00\x03\xc0\x00\x00\x03\xc0\x00\x00\x03\xc0\x00\x00\x03\x80\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x00\x00\x01\xff\x00\x00\xff\xff\xff\xff\xff(\x00\x00\x00\x10\x00\x00\x00\x20\x00\x00\x00\x01\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11\x13\x17\x00\x1f\x20#\x00.,'\x00WN1\x00TN8\x00ue7\x00xh4\x00{sN\x00\xaa\x92H\x00\xa5\x92T\x00t\x8c\xc3\x00\xc8\xa7N\x00\x8e\x99\xa6\x00\xa6\xa3\x89\x00\xc8\xb3r\x00\xc2\xb2z\x00\xcf\xbby\x00\xca\xbf\x8f\x00\xcc\xc1\x96\x00\xf3\xd5t\x00\xff\xddw\x00\xff\xdfw\x00\xff\xdfx\x00\xff\xe1u\x00\xff\xe0y\x00\xfe\xe1v\x00\xe7\xe1\xd2\x00\xf5\xf6\xfb\x00\xf7\xfa\xff\x00\xfb\xfc\xff\x00\xfb\xfe\xff\x00\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x04\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x04\x20\x20\x04\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x04\x20\x20\x04\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x04\x20\x20\x04\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x04\x20\x20\x04\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x04\x20\x20\x04\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x19\x04\x20\x20\x04\x19\x19\x19\x19\x19\x10\x0f\x19\x15\x14\x14\x19\x04\x20\x20\x04\x19\x19\x19\x18\x0a\x1d\x1d\x0a\x19\x14\x14\x19\x04\x20\x20\x04\x19\x15\x19\x19\x0d\x0a\x0a\x0c\x19\x17\x16\x19\x04\x20\x20\x04\x19\x13\x1f\x1f\x0e\x01\x01\x0e\x1f\x1f\x13\x19\x04\x20\x20\x04\x19\x1a\x1e\x00\x02\x19\x19\x1a\x1d\x00\x02\x19\x04\x20\x04\x06\x0b\x1a\x1f\x00\x02\x19\x19\x1a\x1f\x00\x02\x0b\x05\x04\x04\x0b\x08\x0e\x1b\x1c\x0e\x19\x19\x0e\x1f\x1f\x0e\x08\x0b\x04\x20\x04\x07\x08\x0b\x0b\x19\x19\x19\x19\x12\x11\x09\x07\x04\x20\x20\x20\x20\x20\x07\x07\x03\x04\x04\x03\x07\x07\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x80\x01\x00\x00\x80\x01\x00\x00\x80\x01\x00\x00\x80\x01\x00\x00\x80\x01\x00\x00\x80\x01\x00\x00\x80\x01\x00\x00\x80\x01\x00\x00\x80\x01\x00\x00\x80\x01\x00\x00\x80\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x01\x00\x00\xf0\x0f\x00\x00\xff\xff\x00\x00",
+
+	"godoc.html": "<!DOCTYPE\x20html>\x0a<html>\x0a<head>\x0a<meta\x20http-equiv=\"Content-Type\"\x20content=\"text/html;\x20charset=utf-8\">\x0a<meta\x20name=\"viewport\"\x20content=\"width=device-width,\x20initial-scale=1\">\x0a<meta\x20name=\"theme-color\"\x20content=\"#375EAB\">\x0a{{with\x20.Tabtitle}}\x0a\x20\x20<title>{{html\x20.}}\x20-\x20Go\x20Documentation\x20Server</title>\x0a{{else}}\x0a\x20\x20<title>Go\x20Documentation\x20Server</title>\x0a{{end}}\x0a<link\x20type=\"text/css\"\x20rel=\"stylesheet\"\x20href=\"/lib/godoc/style.css\">\x0a{{if\x20.TreeView}}\x0a<link\x20rel=\"stylesheet\"\x20href=\"/lib/godoc/jquery.treeview.css\">\x0a{{end}}\x0a<script>window.initFuncs\x20=\x20[];</script>\x0a<script\x20src=\"/lib/godoc/jquery.js\"\x20defer></script>\x0a{{if\x20.TreeView}}\x0a<script\x20src=\"/lib/godoc/jquery.treeview.js\"\x20defer></script>\x0a<script\x20src=\"/lib/godoc/jquery.treeview.edit.js\"\x20defer></script>\x0a{{end}}\x0a\x0a{{if\x20.Playground}}\x0a<script\x20src=\"/lib/godoc/playground.js\"\x20defer></script>\x0a{{end}}\x0a{{with\x20.Version}}<script>var\x20goVersion\x20=\x20{{printf\x20\"%q\"\x20.}};</script>{{end}}\x0a<script\x20src=\"/lib/godoc/godocs.js\"\x20defer></script>\x0a</head>\x0a<body>\x0a\x0a<div\x20id='lowframe'\x20style=\"position:\x20fixed;\x20bottom:\x200;\x20left:\x200;\x20height:\x200;\x20width:\x20100%;\x20border-top:\x20thin\x20solid\x20grey;\x20background-color:\x20white;\x20overflow:\x20auto;\">\x0a...\x0a</div><!--\x20#lowframe\x20-->\x0a\x0a<div\x20id=\"topbar\"{{if\x20.Title}}\x20class=\"wide\"{{end}}><div\x20class=\"container\">\x0a<div\x20class=\"top-heading\"\x20id=\"heading-wide\"><a\x20href=\"/pkg/\">Go\x20Documentation\x20Server</a></div>\x0a<div\x20class=\"top-heading\"\x20id=\"heading-narrow\"><a\x20href=\"/pkg/\">GoDoc</a></div>\x0a<a\x20href=\"#\"\x20id=\"menu-button\"><span\x20id=\"menu-button-arrow\">&#9661;</span></a>\x0a<form\x20method=\"GET\"\x20action=\"/search\">\x0a<div\x20id=\"menu\">\x0a{{if\x20(and\x20.Playground\x20.Title)}}\x0a<a\x20id=\"playgroundButton\"\x20href=\"https://play.golang.org/\"\x20title=\"Show\x20Go\x20Playground\">Play</a>\x0a{{end}}\x0a<span\x20class=\"search-box\"><input\x20type=\"search\"\x20id=\"search\"\x20name=\"q\"\x20placeholder=\"Search\"\x20aria-label=\"Search\"\x20required><button\x20type=\"submit\"><span><!--\x20magnifying\x20glass:\x20--><svg\x20width=\"24\"\x20height=\"24\"\x20viewBox=\"0\x200\x2024\x2024\"><title>submit\x20search</title><path\x20d=\"M15.5\x2014h-.79l-.28-.27C15.41\x2012.59\x2016\x2011.11\x2016\x209.5\x2016\x205.91\x2013.09\x203\x209.5\x203S3\x205.91\x203\x209.5\x205.91\x2016\x209.5\x2016c1.61\x200\x203.09-.59\x204.23-1.57l.27.28v.79l5\x204.99L20.49\x2019l-4.99-5zm-6\x200C7.01\x2014\x205\x2011.99\x205\x209.5S7.01\x205\x209.5\x205\x2014\x207.01\x2014\x209.5\x2011.99\x2014\x209.5\x2014z\"/><path\x20d=\"M0\x200h24v24H0z\"\x20fill=\"none\"/></svg></span></button></span>\x0a</div>\x0a</form>\x0a\x0a</div></div>\x0a\x0a{{if\x20.Playground}}\x0a<div\x20id=\"playground\"\x20class=\"play\">\x0a\x09<div\x20class=\"input\"><textarea\x20class=\"code\"\x20spellcheck=\"false\">package\x20main\x0a\x0aimport\x20\"fmt\"\x0a\x0afunc\x20main()\x20{\x0a\x09fmt.Println(\"Hello,\x20\xe4\xb8\x96\xe7\x95\x8c\")\x0a}</textarea></div>\x0a\x09<div\x20class=\"output\"></div>\x0a\x09<div\x20class=\"buttons\">\x0a\x09\x09<a\x20class=\"run\"\x20title=\"Run\x20this\x20code\x20[shift-enter]\">Run</a>\x0a\x09\x09<a\x20class=\"fmt\"\x20title=\"Format\x20this\x20code\">Format</a>\x0a\x09\x09<a\x20class=\"share\"\x20title=\"Share\x20this\x20code\">Share</a>\x0a\x09</div>\x0a</div>\x0a{{end}}\x0a\x0a<div\x20id=\"page\"{{if\x20.Title}}\x20class=\"wide\"{{end}}>\x0a<div\x20class=\"container\">\x0a\x0a{{if\x20or\x20.Title\x20.SrcPath}}\x0a\x20\x20<h1>\x0a\x20\x20\x20\x20{{html\x20.Title}}\x0a\x20\x20\x20\x20{{html\x20.SrcPath\x20|\x20srcBreadcrumb}}\x0a\x20\x20</h1>\x0a{{end}}\x0a\x0a{{with\x20.Subtitle}}\x0a\x20\x20<h2>{{html\x20.}}</h2>\x0a{{end}}\x0a\x0a{{with\x20.SrcPath}}\x0a\x20\x20<h2>\x0a\x20\x20\x20\x20Documentation:\x20{{html\x20.\x20|\x20srcToPkgLink}}\x0a\x20\x20</h2>\x0a{{end}}\x0a\x0a{{/*\x20The\x20Table\x20of\x20Contents\x20is\x20automatically\x20inserted\x20in\x20this\x20<div>.\x0a\x20\x20\x20\x20\x20Do\x20not\x20delete\x20this\x20<div>.\x20*/}}\x0a<div\x20id=\"nav\"></div>\x0a\x0a{{/*\x20Body\x20is\x20HTML-escaped\x20elsewhere\x20*/}}\x0a{{printf\x20\"%s\"\x20.Body}}\x0a\x0a<div\x20id=\"footer\">\x0aBuild\x20version\x20{{html\x20.Version}}.<br>\x0aExcept\x20as\x20<a\x20href=\"https://developers.google.com/site-policies#restrictions\">noted</a>,\x0athe\x20content\x20of\x20this\x20page\x20is\x20licensed\x20under\x20the\x0aCreative\x20Commons\x20Attribution\x203.0\x20License,\x0aand\x20code\x20is\x20licensed\x20under\x20a\x20<a\x20href=\"/LICENSE\">BSD\x20license</a>.<br>\x0a<a\x20href=\"https://golang.org/doc/tos.html\">Terms\x20of\x20Service</a>\x20|\x0a<a\x20href=\"https://www.google.com/intl/en/policies/privacy/\">Privacy\x20Policy</a>\x0a</div>\x0a\x0a</div><!--\x20.container\x20-->\x0a</div><!--\x20#page\x20-->\x0a</body>\x0a</html>\x0a",
 
 	"godocs.js": "//\x20Copyright\x202012\x20The\x20Go\x20Authors.\x20All\x20rights\x20reserved.\x0a//\x20Use\x20of\x20this\x20source\x20code\x20is\x20governed\x20by\x20a\x20BSD-style\x0a//\x20license\x20that\x20can\x20be\x20found\x20in\x20the\x20LICENSE\x20file.\x0a\x0a/*\x20A\x20little\x20code\x20to\x20ease\x20navigation\x20of\x20these\x20documents.\x0a\x20*\x0a\x20*\x20On\x20window\x20load\x20we:\x0a\x20*\x20\x20+\x20Generate\x20a\x20table\x20of\x20contents\x20(generateTOC)\x0a\x20*\x20\x20+\x20Bind\x20foldable\x20sections\x20(bindToggles)\x0a\x20*\x20\x20+\x20Bind\x20links\x20to\x20foldable\x20sections\x20(bindToggleLinks)\x0a\x20*/\x0a\x0a(function()\x20{\x0a\x20\x20'use\x20strict';\x0a\x0a\x20\x20//\x20Mobile-friendly\x20topbar\x20menu\x0a\x20\x20$(function()\x20{\x0a\x20\x20\x20\x20var\x20menu\x20=\x20$('#menu');\x0a\x20\x20\x20\x20var\x20menuButton\x20=\x20$('#menu-button');\x0a\x20\x20\x20\x20var\x20menuButtonArrow\x20=\x20$('#menu-button-arrow');\x0a\x20\x20\x20\x20menuButton.click(function(event)\x20{\x0a\x20\x20\x20\x20\x20\x20menu.toggleClass('menu-visible');\x0a\x20\x20\x20\x20\x20\x20menuButtonArrow.toggleClass('vertical-flip');\x0a\x20\x20\x20\x20\x20\x20event.preventDefault();\x0a\x20\x20\x20\x20\x20\x20return\x20false;\x0a\x20\x20\x20\x20});\x0a\x20\x20});\x0a\x0a\x20\x20/*\x20Generates\x20a\x20table\x20of\x20contents:\x20looks\x20for\x20h2\x20and\x20h3\x20elements\x20and\x20generates\x0a\x20\x20\x20*\x20links.\x20\"Decorates\"\x20the\x20element\x20with\x20id==\"nav\"\x20with\x20this\x20table\x20of\x20contents.\x0a\x20\x20\x20*/\x0a\x20\x20function\x20generateTOC()\x20{\x0a\x20\x20\x20\x20if\x20($('#manual-nav').length\x20>\x200)\x20{\x0a\x20\x20\x20\x20\x20\x20return;\x0a\x20\x20\x20\x20}\x0a\x0a\x20\x20\x20\x20//\x20For\x20search,\x20we\x20send\x20the\x20toc\x20precomputed\x20from\x20server-side.\x0a\x20\x20\x20\x20//\x20TODO:\x20Ideally,\x20this\x20should\x20always\x20be\x20precomputed\x20for\x20all\x20pages,\x20but\x20then\x0a\x20\x20\x20\x20//\x20we\x20need\x20to\x20do\x20HTML\x20parsing\x20on\x20the\x20server-side.\x0a\x20\x20\x20\x20if\x20(location.pathname\x20===\x20'/search')\x20{\x0a\x20\x20\x20\x20\x20\x20return;\x0a\x20\x20\x20\x20}\x0a\x0a\x20\x20\x20\x20var\x20nav\x20=\x20$('#nav');\x0a\x20\x20\x20\x20if\x20(nav.length\x20===\x200)\x20{\x0a\x20\x20\x20\x20\x20\x20return;\x0a\x20\x20\x20\x20}\x0a\x0a\x20\x20\x20\x20var\x20toc_items\x20=\x20[];\x0a\x20\x20\x20\x20$(nav)\x0a\x20\x20\x20\x20\x20\x20.nextAll('h2,\x20h3')\x0a\x20\x20\x20\x20\x20\x20.each(function()\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20var\x20node\x20=\x20this;\x0a\x20\x20\x20\x20\x20\x20\x20\x20if\x20(node.id\x20==\x20'')\x20node.id\x20=\x20'tmp_'\x20+\x20toc_items.length;\x0a\x20\x20\x20\x20\x20\x20\x20\x20var\x20link\x20=\x20$('<a/>')\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20.attr('href',\x20'#'\x20+\x20node.id)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20.text($(node).text());\x0a\x20\x20\x20\x20\x20\x20\x20\x20var\x20item;\x0a\x20\x20\x20\x20\x20\x20\x20\x20if\x20($(node).is('h2'))\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20item\x20=\x20$('<dt/>');\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x20else\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20//\x20h3\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20item\x20=\x20$('<dd\x20class=\"indent\"/>');\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20item.append(link);\x0a\x20\x20\x20\x20\x20\x20\x20\x20toc_items.push(item);\x0a\x20\x20\x20\x20\x20\x20});\x0a\x20\x20\x20\x20if\x20(toc_items.length\x20<=\x201)\x20{\x0a\x20\x20\x20\x20\x20\x20return;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20var\x20dl1\x20=\x20$('<dl/>');\x0a\x20\x20\x20\x20var\x20dl2\x20=\x20$('<dl/>');\x0a\x0a\x20\x20\x20\x20var\x20split_index\x20=\x20toc_items.length\x20/\x202\x20+\x201;\x0a\x20\x20\x20\x20if\x20(split_index\x20<\x208)\x20{\x0a\x20\x20\x20\x20\x20\x20split_index\x20=\x20toc_items.length;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20for\x20(var\x20i\x20=\x200;\x20i\x20<\x20split_index;\x20i++)\x20{\x0a\x20\x20\x20\x20\x20\x20dl1.append(toc_items[i]);\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20for\x20(;\x20/*\x20keep\x20using\x20i\x20*/\x20i\x20<\x20toc_items.length;\x20i++)\x20{\x0a\x20\x20\x20\x20\x20\x20dl2.append(toc_items[i]);\x0a\x20\x20\x20\x20}\x0a\x0a\x20\x20\x20\x20var\x20tocTable\x20=\x20$('<table\x20class=\"unruled\"/>').appendTo(nav);\x0a\x20\x20\x20\x20var\x20tocBody\x20=\x20$('<tbody/>').appendTo(tocTable);\x0a\x20\x20\x20\x20var\x20tocRow\x20=\x20$('<tr/>').appendTo(tocBody);\x0a\x0a\x20\x20\x20\x20//\x201st\x20column\x0a\x20\x20\x20\x20$('<td\x20class=\"first\"/>')\x0a\x20\x20\x20\x20\x20\x20.appendTo(tocRow)\x0a\x20\x20\x20\x20\x20\x20.append(dl1);\x0a\x20\x20\x20\x20//\x202nd\x20column\x0a\x20\x20\x20\x20$('<td/>')\x0a\x20\x20\x20\x20\x20\x20.appendTo(tocRow)\x0a\x20\x20\x20\x20\x20\x20.append(dl2);\x0a\x20\x20}\x0a\x0a\x20\x20function\x20bindToggle(el)\x20{\x0a\x20\x20\x20\x20$('.toggleButton',\x20el).click(function()\x20{\x0a\x20\x20\x20\x20\x20\x20if\x20($(this).closest('.toggle,\x20.toggleVisible')[0]\x20!=\x20el)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20Only\x20trigger\x20the\x20closest\x20toggle\x20header.\x0a\x20\x20\x20\x20\x20\x20\x20\x20return;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x0a\x20\x20\x20\x20\x20\x20if\x20($(el).is('.toggle'))\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20$(el)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20.addClass('toggleVisible')\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20.removeClass('toggle');\x0a\x20\x20\x20\x20\x20\x20}\x20else\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20$(el)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20.addClass('toggle')\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20.removeClass('toggleVisible');\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20});\x0a\x20\x20}\x0a\x0a\x20\x20function\x20bindToggles(selector)\x20{\x0a\x20\x20\x20\x20$(selector).each(function(i,\x20el)\x20{\x0a\x20\x20\x20\x20\x20\x20bindToggle(el);\x0a\x20\x20\x20\x20});\x0a\x20\x20}\x0a\x0a\x20\x20function\x20bindToggleLink(el,\x20prefix)\x20{\x0a\x20\x20\x20\x20$(el).click(function()\x20{\x0a\x20\x20\x20\x20\x20\x20var\x20href\x20=\x20$(el).attr('href');\x0a\x20\x20\x20\x20\x20\x20var\x20i\x20=\x20href.indexOf('#'\x20+\x20prefix);\x0a\x20\x20\x20\x20\x20\x20if\x20(i\x20<\x200)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20return;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20var\x20id\x20=\x20'#'\x20+\x20prefix\x20+\x20href.slice(i\x20+\x201\x20+\x20prefix.length);\x0a\x20\x20\x20\x20\x20\x20if\x20($(id).is('.toggle'))\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20$(id)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20.find('.toggleButton')\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20.first()\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20.click();\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20});\x0a\x20\x20}\x0a\x20\x20function\x20bindToggleLinks(selector,\x20prefix)\x20{\x0a\x20\x20\x20\x20$(selector).each(function(i,\x20el)\x20{\x0a\x20\x20\x20\x20\x20\x20bindToggleLink(el,\x20prefix);\x0a\x20\x20\x20\x20});\x0a\x20\x20}\x0a\x0a\x20\x20function\x20setupDropdownPlayground()\x20{\x0a\x20\x20\x20\x20if\x20(!$('#page').is('.wide'))\x20{\x0a\x20\x20\x20\x20\x20\x20return;\x20//\x20don't\x20show\x20on\x20front\x20page\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20var\x20button\x20=\x20$('#playgroundButton');\x0a\x20\x20\x20\x20var\x20div\x20=\x20$('#playground');\x0a\x20\x20\x20\x20var\x20setup\x20=\x20false;\x0a\x20\x20\x20\x20button.toggle(\x0a\x20\x20\x20\x20\x20\x20function()\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20button.addClass('active');\x0a\x20\x20\x20\x20\x20\x20\x20\x20div.show();\x0a\x20\x20\x20\x20\x20\x20\x20\x20if\x20(setup)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20return;\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20setup\x20=\x20true;\x0a\x20\x20\x20\x20\x20\x20\x20\x20playground({\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20codeEl:\x20$('.code',\x20div),\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20outputEl:\x20$('.output',\x20div),\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20runEl:\x20$('.run',\x20div),\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20fmtEl:\x20$('.fmt',\x20div),\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20shareEl:\x20$('.share',\x20div),\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20shareRedirect:\x20'//play.golang.org/p/',\x0a\x20\x20\x20\x20\x20\x20\x20\x20});\x0a\x20\x20\x20\x20\x20\x20},\x0a\x20\x20\x20\x20\x20\x20function()\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20button.removeClass('active');\x0a\x20\x20\x20\x20\x20\x20\x20\x20div.hide();\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20);\x0a\x20\x20\x20\x20$('#menu').css('min-width',\x20'+=60');\x0a\x0a\x20\x20\x20\x20//\x20Hide\x20inline\x20playground\x20if\x20we\x20click\x20somewhere\x20on\x20the\x20page.\x0a\x20\x20\x20\x20//\x20This\x20is\x20needed\x20in\x20mobile\x20devices,\x20where\x20the\x20\"Play\"\x20button\x0a\x20\x20\x20\x20//\x20is\x20not\x20clickable\x20once\x20the\x20playground\x20opens\x20up.\x0a\x20\x20\x20\x20$('#page').click(function()\x20{\x0a\x20\x20\x20\x20\x20\x20if\x20(button.hasClass('active'))\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20button.click();\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20});\x0a\x20\x20}\x0a\x0a\x20\x20function\x20setupInlinePlayground()\x20{\x0a\x20\x20\x20\x20'use\x20strict';\x0a\x20\x20\x20\x20//\x20Set\x20up\x20playground\x20when\x20each\x20element\x20is\x20toggled.\x0a\x20\x20\x20\x20$('div.play').each(function(i,\x20el)\x20{\x0a\x20\x20\x20\x20\x20\x20//\x20Set\x20up\x20playground\x20for\x20this\x20example.\x0a\x20\x20\x20\x20\x20\x20var\x20setup\x20=\x20function()\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20var\x20code\x20=\x20$('.code',\x20el);\x0a\x20\x20\x20\x20\x20\x20\x20\x20playground({\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20codeEl:\x20code,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20outputEl:\x20$('.output',\x20el),\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20runEl:\x20$('.run',\x20el),\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20fmtEl:\x20$('.fmt',\x20el),\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20shareEl:\x20$('.share',\x20el),\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20shareRedirect:\x20'//play.golang.org/p/',\x0a\x20\x20\x20\x20\x20\x20\x20\x20});\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20Make\x20the\x20code\x20textarea\x20resize\x20to\x20fit\x20content.\x0a\x20\x20\x20\x20\x20\x20\x20\x20var\x20resize\x20=\x20function()\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20code.height(0);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20var\x20h\x20=\x20code[0].scrollHeight;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20code.height(h\x20+\x2020);\x20//\x20minimize\x20bouncing.\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20code.closest('.input').height(h);\x0a\x20\x20\x20\x20\x20\x20\x20\x20};\x0a\x20\x20\x20\x20\x20\x20\x20\x20code.on('keydown',\x20resize);\x0a\x20\x20\x20\x20\x20\x20\x20\x20code.on('keyup',\x20resize);\x0a\x20\x20\x20\x20\x20\x20\x20\x20code.keyup();\x20//\x20resize\x20now.\x0a\x20\x20\x20\x20\x20\x20};\x0a\x0a\x20\x20\x20\x20\x20\x20//\x20If\x20example\x20already\x20visible,\x20set\x20up\x20playground\x20now.\x0a\x20\x20\x20\x20\x20\x20if\x20($(el).is(':visible'))\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20setup();\x0a\x20\x20\x20\x20\x20\x20\x20\x20return;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x0a\x20\x20\x20\x20\x20\x20//\x20Otherwise,\x20set\x20up\x20playground\x20when\x20example\x20is\x20expanded.\x0a\x20\x20\x20\x20\x20\x20var\x20built\x20=\x20false;\x0a\x20\x20\x20\x20\x20\x20$(el)\x0a\x20\x20\x20\x20\x20\x20\x20\x20.closest('.toggle')\x0a\x20\x20\x20\x20\x20\x20\x20\x20.click(function()\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20//\x20Only\x20set\x20up\x20once.\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(!built)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20setup();\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20built\x20=\x20true;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20});\x0a\x20\x20\x20\x20});\x0a\x20\x20}\x0a\x0a\x20\x20//\x20fixFocus\x20tries\x20to\x20put\x20focus\x20to\x20div#page\x20so\x20that\x20keyboard\x20navigation\x20works.\x0a\x20\x20function\x20fixFocus()\x20{\x0a\x20\x20\x20\x20var\x20page\x20=\x20$('div#page');\x0a\x20\x20\x20\x20var\x20topbar\x20=\x20$('div#topbar');\x0a\x20\x20\x20\x20page.css('outline',\x200);\x20//\x20disable\x20outline\x20when\x20focused\x0a\x20\x20\x20\x20page.attr('tabindex',\x20-1);\x20//\x20and\x20set\x20tabindex\x20so\x20that\x20it\x20is\x20focusable\x0a\x20\x20\x20\x20$(window)\x0a\x20\x20\x20\x20\x20\x20.resize(function(evt)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20only\x20focus\x20page\x20when\x20the\x20topbar\x20is\x20at\x20fixed\x20position\x20(that\x20is,\x20it's\x20in\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20front\x20of\x20page,\x20and\x20keyboard\x20event\x20will\x20go\x20to\x20the\x20former\x20by\x20default.)\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20by\x20focusing\x20page,\x20keyboard\x20event\x20will\x20go\x20to\x20page\x20so\x20that\x20up/down\x20arrow,\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20space,\x20etc.\x20will\x20work\x20as\x20expected.\x0a\x20\x20\x20\x20\x20\x20\x20\x20if\x20(topbar.css('position')\x20==\x20'fixed')\x20page.focus();\x0a\x20\x20\x20\x20\x20\x20})\x0a\x20\x20\x20\x20\x20\x20.resize();\x0a\x20\x20}\x0a\x0a\x20\x20function\x20toggleHash()\x20{\x0a\x20\x20\x20\x20var\x20id\x20=\x20window.location.hash.substring(1);\x0a\x20\x20\x20\x20//\x20Open\x20all\x20of\x20the\x20toggles\x20for\x20a\x20particular\x20hash.\x0a\x20\x20\x20\x20var\x20els\x20=\x20$(\x0a\x20\x20\x20\x20\x20\x20document.getElementById(id),\x0a\x20\x20\x20\x20\x20\x20$('a[name]').filter(function()\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20return\x20$(this).attr('name')\x20==\x20id;\x0a\x20\x20\x20\x20\x20\x20})\x0a\x20\x20\x20\x20);\x0a\x0a\x20\x20\x20\x20while\x20(els.length)\x20{\x0a\x20\x20\x20\x20\x20\x20for\x20(var\x20i\x20=\x200;\x20i\x20<\x20els.length;\x20i++)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20var\x20el\x20=\x20$(els[i]);\x0a\x20\x20\x20\x20\x20\x20\x20\x20if\x20(el.is('.toggle'))\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20el.find('.toggleButton')\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20.first()\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20.click();\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20els\x20=\x20el.parent();\x0a\x20\x20\x20\x20}\x0a\x20\x20}\x0a\x0a\x20\x20function\x20personalizeInstallInstructions()\x20{\x0a\x20\x20\x20\x20var\x20prefix\x20=\x20'?download=';\x0a\x20\x20\x20\x20var\x20s\x20=\x20window.location.search;\x0a\x20\x20\x20\x20if\x20(s.indexOf(prefix)\x20!=\x200)\x20{\x0a\x20\x20\x20\x20\x20\x20//\x20No\x20'download'\x20query\x20string;\x20detect\x20\"test\"\x20instructions\x20from\x20User\x20Agent.\x0a\x20\x20\x20\x20\x20\x20if\x20(navigator.platform.indexOf('Win')\x20!=\x20-1)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20$('.testUnix').hide();\x0a\x20\x20\x20\x20\x20\x20\x20\x20$('.testWindows').show();\x0a\x20\x20\x20\x20\x20\x20}\x20else\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20$('.testUnix').show();\x0a\x20\x20\x20\x20\x20\x20\x20\x20$('.testWindows').hide();\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20return;\x0a\x20\x20\x20\x20}\x0a\x0a\x20\x20\x20\x20var\x20filename\x20=\x20s.substr(prefix.length);\x0a\x20\x20\x20\x20var\x20filenameRE\x20=\x20/^go1\\.\\d+(\\.\\d+)?([a-z0-9]+)?\\.([a-z0-9]+)(-[a-z0-9]+)?(-osx10\\.[68])?\\.([a-z.]+)$/;\x0a\x20\x20\x20\x20var\x20m\x20=\x20filenameRE.exec(filename);\x0a\x20\x20\x20\x20if\x20(!m)\x20{\x0a\x20\x20\x20\x20\x20\x20//\x20Can't\x20interpret\x20file\x20name;\x20bail.\x0a\x20\x20\x20\x20\x20\x20return;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20$('.downloadFilename').text(filename);\x0a\x20\x20\x20\x20$('.hideFromDownload').hide();\x0a\x0a\x20\x20\x20\x20var\x20os\x20=\x20m[3];\x0a\x20\x20\x20\x20var\x20ext\x20=\x20m[6];\x0a\x20\x20\x20\x20if\x20(ext\x20!=\x20'tar.gz')\x20{\x0a\x20\x20\x20\x20\x20\x20$('#tarballInstructions').hide();\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20if\x20(os\x20!=\x20'darwin'\x20||\x20ext\x20!=\x20'pkg')\x20{\x0a\x20\x20\x20\x20\x20\x20$('#darwinPackageInstructions').hide();\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20if\x20(os\x20!=\x20'windows')\x20{\x0a\x20\x20\x20\x20\x20\x20$('#windowsInstructions').hide();\x0a\x20\x20\x20\x20\x20\x20$('.testUnix').show();\x0a\x20\x20\x20\x20\x20\x20$('.testWindows').hide();\x0a\x20\x20\x20\x20}\x20else\x20{\x0a\x20\x20\x20\x20\x20\x20if\x20(ext\x20!=\x20'msi')\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20$('#windowsInstallerInstructions').hide();\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20if\x20(ext\x20!=\x20'zip')\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20$('#windowsZipInstructions').hide();\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20$('.testUnix').hide();\x0a\x20\x20\x20\x20\x20\x20$('.testWindows').show();\x0a\x20\x20\x20\x20}\x0a\x0a\x20\x20\x20\x20var\x20download\x20=\x20'https://dl.google.com/go/'\x20+\x20filename;\x0a\x0a\x20\x20\x20\x20var\x20message\x20=\x20$(\x0a\x20\x20\x20\x20\x20\x20'<p\x20class=\"downloading\">'\x20+\x0a\x20\x20\x20\x20\x20\x20\x20\x20'Your\x20download\x20should\x20begin\x20shortly.\x20'\x20+\x0a\x20\x20\x20\x20\x20\x20\x20\x20'If\x20it\x20does\x20not,\x20click\x20<a>this\x20link</a>.</p>'\x0a\x20\x20\x20\x20);\x0a\x20\x20\x20\x20message.find('a').attr('href',\x20download);\x0a\x20\x20\x20\x20message.insertAfter('#nav');\x0a\x0a\x20\x20\x20\x20window.location\x20=\x20download;\x0a\x20\x20}\x0a\x0a\x20\x20function\x20updateVersionTags()\x20{\x0a\x20\x20\x20\x20var\x20v\x20=\x20window.goVersion;\x0a\x20\x20\x20\x20if\x20(/^go[0-9.]+$/.test(v))\x20{\x0a\x20\x20\x20\x20\x20\x20$('.versionTag')\x0a\x20\x20\x20\x20\x20\x20\x20\x20.empty()\x0a\x20\x20\x20\x20\x20\x20\x20\x20.text(v);\x0a\x20\x20\x20\x20\x20\x20$('.whereTag').hide();\x0a\x20\x20\x20\x20}\x0a\x20\x20}\x0a\x0a\x20\x20function\x20addPermalinks()\x20{\x0a\x20\x20\x20\x20function\x20addPermalink(source,\x20parent)\x20{\x0a\x20\x20\x20\x20\x20\x20var\x20id\x20=\x20source.attr('id');\x0a\x20\x20\x20\x20\x20\x20if\x20(id\x20==\x20''\x20||\x20id.indexOf('tmp_')\x20===\x200)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20Auto-generated\x20permalink.\x0a\x20\x20\x20\x20\x20\x20\x20\x20return;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20if\x20(parent.find('>\x20.permalink').length)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20Already\x20attached.\x0a\x20\x20\x20\x20\x20\x20\x20\x20return;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20parent\x0a\x20\x20\x20\x20\x20\x20\x20\x20.append('\x20')\x0a\x20\x20\x20\x20\x20\x20\x20\x20.append($(\"<a\x20class='permalink'>&#xb6;</a>\").attr('href',\x20'#'\x20+\x20id));\x0a\x20\x20\x20\x20}\x0a\x0a\x20\x20\x20\x20$('#page\x20.container')\x0a\x20\x20\x20\x20\x20\x20.find('h2[id],\x20h3[id]')\x0a\x20\x20\x20\x20\x20\x20.each(function()\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20var\x20el\x20=\x20$(this);\x0a\x20\x20\x20\x20\x20\x20\x20\x20addPermalink(el,\x20el);\x0a\x20\x20\x20\x20\x20\x20});\x0a\x0a\x20\x20\x20\x20$('#page\x20.container')\x0a\x20\x20\x20\x20\x20\x20.find('dl[id]')\x0a\x20\x20\x20\x20\x20\x20.each(function()\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20var\x20el\x20=\x20$(this);\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20Add\x20the\x20anchor\x20to\x20the\x20\"dt\"\x20element.\x0a\x20\x20\x20\x20\x20\x20\x20\x20addPermalink(el,\x20el.find('>\x20dt').first());\x0a\x20\x20\x20\x20\x20\x20});\x0a\x20\x20}\x0a\x0a\x20\x20$('.js-expandAll').click(function()\x20{\x0a\x20\x20\x20\x20if\x20($(this).hasClass('collapsed'))\x20{\x0a\x20\x20\x20\x20\x20\x20toggleExamples('toggle');\x0a\x20\x20\x20\x20\x20\x20$(this).text('(Collapse\x20All)');\x0a\x20\x20\x20\x20}\x20else\x20{\x0a\x20\x20\x20\x20\x20\x20toggleExamples('toggleVisible');\x0a\x20\x20\x20\x20\x20\x20$(this).text('(Expand\x20All)');\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20$(this).toggleClass('collapsed');\x0a\x20\x20});\x0a\x0a\x20\x20function\x20toggleExamples(className)\x20{\x0a\x20\x20\x20\x20//\x20We\x20need\x20to\x20explicitly\x20iterate\x20through\x20divs\x20starting\x20with\x20\"example_\"\x0a\x20\x20\x20\x20//\x20to\x20avoid\x20toggling\x20Overview\x20and\x20Index\x20collapsibles.\x0a\x20\x20\x20\x20$(\"[id^='example_']\").each(function()\x20{\x0a\x20\x20\x20\x20\x20\x20//\x20Check\x20for\x20state\x20and\x20click\x20it\x20only\x20if\x20required.\x0a\x20\x20\x20\x20\x20\x20if\x20($(this).hasClass(className))\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20$(this)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20.find('.toggleButton')\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20.first()\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20.click();\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20});\x0a\x20\x20}\x0a\x0a\x20\x20$(document).ready(function()\x20{\x0a\x20\x20\x20\x20generateTOC();\x0a\x20\x20\x20\x20addPermalinks();\x0a\x20\x20\x20\x20bindToggles('.toggle');\x0a\x20\x20\x20\x20bindToggles('.toggleVisible');\x0a\x20\x20\x20\x20bindToggleLinks('.exampleLink',\x20'example_');\x0a\x20\x20\x20\x20bindToggleLinks('.overviewLink',\x20'');\x0a\x20\x20\x20\x20bindToggleLinks('.examplesLink',\x20'');\x0a\x20\x20\x20\x20bindToggleLinks('.indexLink',\x20'');\x0a\x20\x20\x20\x20setupDropdownPlayground();\x0a\x20\x20\x20\x20setupInlinePlayground();\x0a\x20\x20\x20\x20fixFocus();\x0a\x20\x20\x20\x20setupTypeInfo();\x0a\x20\x20\x20\x20setupCallgraphs();\x0a\x20\x20\x20\x20toggleHash();\x0a\x20\x20\x20\x20personalizeInstallInstructions();\x0a\x20\x20\x20\x20updateVersionTags();\x0a\x0a\x20\x20\x20\x20//\x20godoc.html\x20defines\x20window.initFuncs\x20in\x20the\x20<head>\x20tag,\x20and\x20root.html\x20and\x0a\x20\x20\x20\x20//\x20codewalk.js\x20push\x20their\x20on-page-ready\x20functions\x20to\x20the\x20list.\x0a\x20\x20\x20\x20//\x20We\x20execute\x20those\x20functions\x20here,\x20to\x20avoid\x20loading\x20jQuery\x20until\x20the\x20page\x0a\x20\x20\x20\x20//\x20content\x20is\x20loaded.\x0a\x20\x20\x20\x20for\x20(var\x20i\x20=\x200;\x20i\x20<\x20window.initFuncs.length;\x20i++)\x20window.initFuncs[i]();\x0a\x20\x20});\x0a\x0a\x20\x20//\x20--\x20analysis\x20---------------------------------------------------------\x0a\x0a\x20\x20//\x20escapeHTML\x20returns\x20HTML\x20for\x20s,\x20with\x20metacharacters\x20quoted.\x0a\x20\x20//\x20It\x20is\x20safe\x20for\x20use\x20in\x20both\x20elements\x20and\x20attributes\x0a\x20\x20//\x20(unlike\x20the\x20\"set\x20innerText,\x20read\x20innerHTML\"\x20trick).\x0a\x20\x20function\x20escapeHTML(s)\x20{\x0a\x20\x20\x20\x20return\x20s\x0a\x20\x20\x20\x20\x20\x20.replace(/&/g,\x20'&amp;')\x0a\x20\x20\x20\x20\x20\x20.replace(/\\\"/g,\x20'&quot;')\x0a\x20\x20\x20\x20\x20\x20.replace(/\\'/g,\x20'&#39;')\x0a\x20\x20\x20\x20\x20\x20.replace(/</g,\x20'&lt;')\x0a\x20\x20\x20\x20\x20\x20.replace(/>/g,\x20'&gt;');\x0a\x20\x20}\x0a\x0a\x20\x20//\x20makeAnchor\x20returns\x20HTML\x20for\x20an\x20<a>\x20element,\x20given\x20an\x20anchorJSON\x20object.\x0a\x20\x20function\x20makeAnchor(json)\x20{\x0a\x20\x20\x20\x20var\x20html\x20=\x20escapeHTML(json.Text);\x0a\x20\x20\x20\x20if\x20(json.Href\x20!=\x20'')\x20{\x0a\x20\x20\x20\x20\x20\x20html\x20=\x20\"<a\x20href='\"\x20+\x20escapeHTML(json.Href)\x20+\x20\"'>\"\x20+\x20html\x20+\x20'</a>';\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20return\x20html;\x0a\x20\x20}\x0a\x0a\x20\x20function\x20showLowFrame(html)\x20{\x0a\x20\x20\x20\x20var\x20lowframe\x20=\x20document.getElementById('lowframe');\x0a\x20\x20\x20\x20lowframe.style.height\x20=\x20'200px';\x0a\x20\x20\x20\x20lowframe.innerHTML\x20=\x0a\x20\x20\x20\x20\x20\x20\"<p\x20style='text-align:\x20left;'>\"\x20+\x0a\x20\x20\x20\x20\x20\x20html\x20+\x0a\x20\x20\x20\x20\x20\x20'</p>\\n'\x20+\x0a\x20\x20\x20\x20\x20\x20\"<div\x20onclick='hideLowFrame()'\x20style='position:\x20absolute;\x20top:\x200;\x20right:\x200;\x20cursor:\x20pointer;'>\xe2\x9c\x98</div>\";\x0a\x20\x20}\x0a\x0a\x20\x20document.hideLowFrame\x20=\x20function()\x20{\x0a\x20\x20\x20\x20var\x20lowframe\x20=\x20document.getElementById('lowframe');\x0a\x20\x20\x20\x20lowframe.style.height\x20=\x20'0px';\x0a\x20\x20};\x0a\x0a\x20\x20//\x20onClickCallers\x20is\x20the\x20onclick\x20action\x20for\x20the\x20'func'\x20tokens\x20of\x20a\x0a\x20\x20//\x20function\x20declaration.\x0a\x20\x20document.onClickCallers\x20=\x20function(index)\x20{\x0a\x20\x20\x20\x20var\x20data\x20=\x20document.ANALYSIS_DATA[index];\x0a\x20\x20\x20\x20if\x20(data.Callers.length\x20==\x201\x20&&\x20data.Callers[0].Sites.length\x20==\x201)\x20{\x0a\x20\x20\x20\x20\x20\x20document.location\x20=\x20data.Callers[0].Sites[0].Href;\x20//\x20jump\x20to\x20sole\x20caller\x0a\x20\x20\x20\x20\x20\x20return;\x0a\x20\x20\x20\x20}\x0a\x0a\x20\x20\x20\x20var\x20html\x20=\x0a\x20\x20\x20\x20\x20\x20'Callers\x20of\x20<code>'\x20+\x20escapeHTML(data.Callee)\x20+\x20'</code>:<br/>\\n';\x0a\x20\x20\x20\x20for\x20(var\x20i\x20=\x200;\x20i\x20<\x20data.Callers.length;\x20i++)\x20{\x0a\x20\x20\x20\x20\x20\x20var\x20caller\x20=\x20data.Callers[i];\x0a\x20\x20\x20\x20\x20\x20html\x20+=\x20'<code>'\x20+\x20escapeHTML(caller.Func)\x20+\x20'</code>';\x0a\x20\x20\x20\x20\x20\x20var\x20sites\x20=\x20caller.Sites;\x0a\x20\x20\x20\x20\x20\x20if\x20(sites\x20!=\x20null\x20&&\x20sites.length\x20>\x200)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20html\x20+=\x20'\x20at\x20line\x20';\x0a\x20\x20\x20\x20\x20\x20\x20\x20for\x20(var\x20j\x20=\x200;\x20j\x20<\x20sites.length;\x20j++)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(j\x20>\x200)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20html\x20+=\x20',\x20';\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20html\x20+=\x20'<code>'\x20+\x20makeAnchor(sites[j])\x20+\x20'</code>';\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20html\x20+=\x20'<br/>\\n';\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20showLowFrame(html);\x0a\x20\x20};\x0a\x0a\x20\x20//\x20onClickCallees\x20is\x20the\x20onclick\x20action\x20for\x20the\x20'('\x20token\x20of\x20a\x20function\x20call.\x0a\x20\x20document.onClickCallees\x20=\x20function(index)\x20{\x0a\x20\x20\x20\x20var\x20data\x20=\x20document.ANALYSIS_DATA[index];\x0a\x20\x20\x20\x20if\x20(data.Callees.length\x20==\x201)\x20{\x0a\x20\x20\x20\x20\x20\x20document.location\x20=\x20data.Callees[0].Href;\x20//\x20jump\x20to\x20sole\x20callee\x0a\x20\x20\x20\x20\x20\x20return;\x0a\x20\x20\x20\x20}\x0a\x0a\x20\x20\x20\x20var\x20html\x20=\x20'Callees\x20of\x20this\x20'\x20+\x20escapeHTML(data.Descr)\x20+\x20':<br/>\\n';\x0a\x20\x20\x20\x20for\x20(var\x20i\x20=\x200;\x20i\x20<\x20data.Callees.length;\x20i++)\x20{\x0a\x20\x20\x20\x20\x20\x20html\x20+=\x20'<code>'\x20+\x20makeAnchor(data.Callees[i])\x20+\x20'</code><br/>\\n';\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20showLowFrame(html);\x0a\x20\x20};\x0a\x0a\x20\x20//\x20onClickTypeInfo\x20is\x20the\x20onclick\x20action\x20for\x20identifiers\x20declaring\x20a\x20named\x20type.\x0a\x20\x20document.onClickTypeInfo\x20=\x20function(index)\x20{\x0a\x20\x20\x20\x20var\x20data\x20=\x20document.ANALYSIS_DATA[index];\x0a\x20\x20\x20\x20var\x20html\x20=\x0a\x20\x20\x20\x20\x20\x20'Type\x20<code>'\x20+\x0a\x20\x20\x20\x20\x20\x20data.Name\x20+\x0a\x20\x20\x20\x20\x20\x20'</code>:\x20'\x20+\x0a\x20\x20\x20\x20\x20\x20'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<small>(size='\x20+\x0a\x20\x20\x20\x20\x20\x20data.Size\x20+\x0a\x20\x20\x20\x20\x20\x20',\x20align='\x20+\x0a\x20\x20\x20\x20\x20\x20data.Align\x20+\x0a\x20\x20\x20\x20\x20\x20')</small><br/>\\n';\x0a\x20\x20\x20\x20html\x20+=\x20implementsHTML(data);\x0a\x20\x20\x20\x20html\x20+=\x20methodsetHTML(data);\x0a\x20\x20\x20\x20showLowFrame(html);\x0a\x20\x20};\x0a\x0a\x20\x20//\x20implementsHTML\x20returns\x20HTML\x20for\x20the\x20implements\x20relation\x20of\x20the\x0a\x20\x20//\x20specified\x20TypeInfoJSON\x20value.\x0a\x20\x20function\x20implementsHTML(info)\x20{\x0a\x20\x20\x20\x20var\x20html\x20=\x20'';\x0a\x20\x20\x20\x20if\x20(info.ImplGroups\x20!=\x20null)\x20{\x0a\x20\x20\x20\x20\x20\x20for\x20(var\x20i\x20=\x200;\x20i\x20<\x20info.ImplGroups.length;\x20i++)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20var\x20group\x20=\x20info.ImplGroups[i];\x0a\x20\x20\x20\x20\x20\x20\x20\x20var\x20x\x20=\x20'<code>'\x20+\x20escapeHTML(group.Descr)\x20+\x20'</code>\x20';\x0a\x20\x20\x20\x20\x20\x20\x20\x20for\x20(var\x20j\x20=\x200;\x20j\x20<\x20group.Facts.length;\x20j++)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20var\x20fact\x20=\x20group.Facts[j];\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20var\x20y\x20=\x20'<code>'\x20+\x20makeAnchor(fact.Other)\x20+\x20'</code>';\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(fact.ByKind\x20!=\x20null)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20html\x20+=\x20escapeHTML(fact.ByKind)\x20+\x20'\x20type\x20'\x20+\x20y\x20+\x20'\x20implements\x20'\x20+\x20x;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\x20else\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20html\x20+=\x20x\x20+\x20'\x20implements\x20'\x20+\x20y;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20html\x20+=\x20'<br/>\\n';\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20return\x20html;\x0a\x20\x20}\x0a\x0a\x20\x20//\x20methodsetHTML\x20returns\x20HTML\x20for\x20the\x20methodset\x20of\x20the\x20specified\x0a\x20\x20//\x20TypeInfoJSON\x20value.\x0a\x20\x20function\x20methodsetHTML(info)\x20{\x0a\x20\x20\x20\x20var\x20html\x20=\x20'';\x0a\x20\x20\x20\x20if\x20(info.Methods\x20!=\x20null)\x20{\x0a\x20\x20\x20\x20\x20\x20for\x20(var\x20i\x20=\x200;\x20i\x20<\x20info.Methods.length;\x20i++)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20html\x20+=\x20'<code>'\x20+\x20makeAnchor(info.Methods[i])\x20+\x20'</code><br/>\\n';\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20return\x20html;\x0a\x20\x20}\x0a\x0a\x20\x20//\x20onClickComm\x20is\x20the\x20onclick\x20action\x20for\x20channel\x20\"make\"\x20and\x20\"<-\"\x0a\x20\x20//\x20send/receive\x20tokens.\x0a\x20\x20document.onClickComm\x20=\x20function(index)\x20{\x0a\x20\x20\x20\x20var\x20ops\x20=\x20document.ANALYSIS_DATA[index].Ops;\x0a\x20\x20\x20\x20if\x20(ops.length\x20==\x201)\x20{\x0a\x20\x20\x20\x20\x20\x20document.location\x20=\x20ops[0].Op.Href;\x20//\x20jump\x20to\x20sole\x20element\x0a\x20\x20\x20\x20\x20\x20return;\x0a\x20\x20\x20\x20}\x0a\x0a\x20\x20\x20\x20var\x20html\x20=\x20'Operations\x20on\x20this\x20channel:<br/>\\n';\x0a\x20\x20\x20\x20for\x20(var\x20i\x20=\x200;\x20i\x20<\x20ops.length;\x20i++)\x20{\x0a\x20\x20\x20\x20\x20\x20html\x20+=\x0a\x20\x20\x20\x20\x20\x20\x20\x20makeAnchor(ops[i].Op)\x20+\x0a\x20\x20\x20\x20\x20\x20\x20\x20'\x20by\x20<code>'\x20+\x0a\x20\x20\x20\x20\x20\x20\x20\x20escapeHTML(ops[i].Fn)\x20+\x0a\x20\x20\x20\x20\x20\x20\x20\x20'</code><br/>\\n';\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20if\x20(ops.length\x20==\x200)\x20{\x0a\x20\x20\x20\x20\x20\x20html\x20+=\x20'(none)<br/>\\n';\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20showLowFrame(html);\x0a\x20\x20};\x0a\x0a\x20\x20$(window).load(function()\x20{\x0a\x20\x20\x20\x20//\x20Scroll\x20window\x20so\x20that\x20first\x20selection\x20is\x20visible.\x0a\x20\x20\x20\x20//\x20(This\x20means\x20we\x20don't\x20need\x20to\x20emit\x20id='L%d'\x20spans\x20for\x20each\x20line.)\x0a\x20\x20\x20\x20//\x20TODO(adonovan):\x20ideally,\x20scroll\x20it\x20so\x20that\x20it's\x20under\x20the\x20pointer,\x0a\x20\x20\x20\x20//\x20but\x20I\x20don't\x20know\x20how\x20to\x20get\x20the\x20pointer\x20y\x20coordinate.\x0a\x20\x20\x20\x20var\x20elts\x20=\x20document.getElementsByClassName('selection');\x0a\x20\x20\x20\x20if\x20(elts.length\x20>\x200)\x20{\x0a\x20\x20\x20\x20\x20\x20elts[0].scrollIntoView();\x0a\x20\x20\x20\x20}\x0a\x20\x20});\x0a\x0a\x20\x20//\x20setupTypeInfo\x20populates\x20the\x20\"Implements\"\x20and\x20\"Method\x20set\"\x20toggle\x20for\x0a\x20\x20//\x20each\x20type\x20in\x20the\x20package\x20doc.\x0a\x20\x20function\x20setupTypeInfo()\x20{\x0a\x20\x20\x20\x20for\x20(var\x20i\x20in\x20document.ANALYSIS_DATA)\x20{\x0a\x20\x20\x20\x20\x20\x20var\x20data\x20=\x20document.ANALYSIS_DATA[i];\x0a\x0a\x20\x20\x20\x20\x20\x20var\x20el\x20=\x20document.getElementById('implements-'\x20+\x20i);\x0a\x20\x20\x20\x20\x20\x20if\x20(el\x20!=\x20null)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20el\x20!=\x20null\x20=>\x20data\x20is\x20TypeInfoJSON.\x0a\x20\x20\x20\x20\x20\x20\x20\x20if\x20(data.ImplGroups\x20!=\x20null)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20el.innerHTML\x20=\x20implementsHTML(data);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20el.parentNode.parentNode.style.display\x20=\x20'block';\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20}\x0a\x0a\x20\x20\x20\x20\x20\x20var\x20el\x20=\x20document.getElementById('methodset-'\x20+\x20i);\x0a\x20\x20\x20\x20\x20\x20if\x20(el\x20!=\x20null)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20el\x20!=\x20null\x20=>\x20data\x20is\x20TypeInfoJSON.\x0a\x20\x20\x20\x20\x20\x20\x20\x20if\x20(data.Methods\x20!=\x20null)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20el.innerHTML\x20=\x20methodsetHTML(data);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20el.parentNode.parentNode.style.display\x20=\x20'block';\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20}\x0a\x20\x20}\x0a\x0a\x20\x20function\x20setupCallgraphs()\x20{\x0a\x20\x20\x20\x20if\x20(document.CALLGRAPH\x20==\x20null)\x20{\x0a\x20\x20\x20\x20\x20\x20return;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20document.getElementById('pkg-callgraph').style.display\x20=\x20'block';\x0a\x0a\x20\x20\x20\x20var\x20treeviews\x20=\x20document.getElementsByClassName('treeview');\x0a\x20\x20\x20\x20for\x20(var\x20i\x20=\x200;\x20i\x20<\x20treeviews.length;\x20i++)\x20{\x0a\x20\x20\x20\x20\x20\x20var\x20tree\x20=\x20treeviews[i];\x0a\x20\x20\x20\x20\x20\x20if\x20(tree.id\x20==\x20null\x20||\x20tree.id.indexOf('callgraph-')\x20!=\x200)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20continue;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20var\x20id\x20=\x20tree.id.substring('callgraph-'.length);\x0a\x20\x20\x20\x20\x20\x20$(tree).treeview({\x20collapsed:\x20true,\x20animated:\x20'fast'\x20});\x0a\x20\x20\x20\x20\x20\x20document.cgAddChildren(tree,\x20tree,\x20[id]);\x0a\x20\x20\x20\x20\x20\x20tree.parentNode.parentNode.style.display\x20=\x20'block';\x0a\x20\x20\x20\x20}\x0a\x20\x20}\x0a\x0a\x20\x20document.cgAddChildren\x20=\x20function(tree,\x20ul,\x20indices)\x20{\x0a\x20\x20\x20\x20if\x20(indices\x20!=\x20null)\x20{\x0a\x20\x20\x20\x20\x20\x20for\x20(var\x20i\x20=\x200;\x20i\x20<\x20indices.length;\x20i++)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20var\x20li\x20=\x20cgAddChild(tree,\x20ul,\x20document.CALLGRAPH[indices[i]]);\x0a\x20\x20\x20\x20\x20\x20\x20\x20if\x20(i\x20==\x20indices.length\x20-\x201)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20$(li).addClass('last');\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20$(tree).treeview({\x20animated:\x20'fast',\x20add:\x20ul\x20});\x0a\x20\x20};\x0a\x0a\x20\x20//\x20cgAddChild\x20adds\x20an\x20<li>\x20element\x20for\x20document.CALLGRAPH\x20node\x20cgn\x20to\x0a\x20\x20//\x20the\x20parent\x20<ul>\x20element\x20ul.\x20tree\x20is\x20the\x20tree's\x20root\x20<ul>\x20element.\x0a\x20\x20function\x20cgAddChild(tree,\x20ul,\x20cgn)\x20{\x0a\x20\x20\x20\x20var\x20li\x20=\x20document.createElement('li');\x0a\x20\x20\x20\x20ul.appendChild(li);\x0a\x20\x20\x20\x20li.className\x20=\x20'closed';\x0a\x0a\x20\x20\x20\x20var\x20code\x20=\x20document.createElement('code');\x0a\x0a\x20\x20\x20\x20if\x20(cgn.Callees\x20!=\x20null)\x20{\x0a\x20\x20\x20\x20\x20\x20$(li).addClass('expandable');\x0a\x0a\x20\x20\x20\x20\x20\x20//\x20Event\x20handlers\x20and\x20innerHTML\x20updates\x20don't\x20play\x20nicely\x20together,\x0a\x20\x20\x20\x20\x20\x20//\x20hence\x20all\x20this\x20explicit\x20DOM\x20manipulation.\x0a\x20\x20\x20\x20\x20\x20var\x20hitarea\x20=\x20document.createElement('div');\x0a\x20\x20\x20\x20\x20\x20hitarea.className\x20=\x20'hitarea\x20expandable-hitarea';\x0a\x20\x20\x20\x20\x20\x20li.appendChild(hitarea);\x0a\x0a\x20\x20\x20\x20\x20\x20li.appendChild(code);\x0a\x0a\x20\x20\x20\x20\x20\x20var\x20childUL\x20=\x20document.createElement('ul');\x0a\x20\x20\x20\x20\x20\x20li.appendChild(childUL);\x0a\x20\x20\x20\x20\x20\x20childUL.setAttribute('style',\x20'display:\x20none;');\x0a\x0a\x20\x20\x20\x20\x20\x20var\x20onClick\x20=\x20function()\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20document.cgAddChildren(tree,\x20childUL,\x20cgn.Callees);\x0a\x20\x20\x20\x20\x20\x20\x20\x20hitarea.removeEventListener('click',\x20onClick);\x0a\x20\x20\x20\x20\x20\x20};\x0a\x20\x20\x20\x20\x20\x20hitarea.addEventListener('click',\x20onClick);\x0a\x20\x20\x20\x20}\x20else\x20{\x0a\x20\x20\x20\x20\x20\x20li.appendChild(code);\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20code.innerHTML\x20+=\x20'&nbsp;'\x20+\x20makeAnchor(cgn.Func);\x0a\x20\x20\x20\x20return\x20li;\x0a\x20\x20}\x0a})();\x0a",
 
@@ -81,7 +83,7 @@
 
 	"package.html": "<!--\x0a\x09Copyright\x202009\x20The\x20Go\x20Authors.\x20All\x20rights\x20reserved.\x0a\x09Use\x20of\x20this\x20source\x20code\x20is\x20governed\x20by\x20a\x20BSD-style\x0a\x09license\x20that\x20can\x20be\x20found\x20in\x20the\x20LICENSE\x20file.\x0a-->\x0a<!--\x0a\x09Note:\x20Static\x20(i.e.,\x20not\x20template-generated)\x20href\x20and\x20id\x0a\x09attributes\x20start\x20with\x20\"pkg-\"\x20to\x20make\x20it\x20impossible\x20for\x0a\x09them\x20to\x20conflict\x20with\x20generated\x20attributes\x20(some\x20of\x20which\x0a\x09correspond\x20to\x20Go\x20identifiers).\x0a-->\x0a{{with\x20.PDoc}}\x0a\x09<script>\x0a\x09document.ANALYSIS_DATA\x20=\x20{{$.AnalysisData}};\x0a\x09document.CALLGRAPH\x20=\x20{{$.CallGraph}};\x0a\x09</script>\x0a\x0a\x09{{if\x20$.IsMain}}\x0a\x09\x09{{/*\x20command\x20documentation\x20*/}}\x0a\x09\x09{{comment_html\x20.Doc}}\x0a\x09{{else}}\x0a\x09\x09{{/*\x20package\x20documentation\x20*/}}\x0a\x09\x09<div\x20id=\"short-nav\">\x0a\x09\x09\x09<dl>\x0a\x09\x09\x09<dd><code>import\x20\"{{html\x20.ImportPath}}\"</code></dd>\x0a\x09\x09\x09</dl>\x0a\x09\x09\x09<dl>\x0a\x09\x09\x09<dd><a\x20href=\"#pkg-overview\"\x20class=\"overviewLink\">Overview</a></dd>\x0a\x09\x09\x09<dd><a\x20href=\"#pkg-index\"\x20class=\"indexLink\">Index</a></dd>\x0a\x09\x09\x09{{if\x20$.Examples}}\x0a\x09\x09\x09\x09<dd><a\x20href=\"#pkg-examples\"\x20class=\"examplesLink\">Examples</a></dd>\x0a\x09\x09\x09{{end}}\x0a\x09\x09\x09{{if\x20$.Dirs}}\x0a\x09\x09\x09\x09<dd><a\x20href=\"#pkg-subdirectories\">Subdirectories</a></dd>\x0a\x09\x09\x09{{end}}\x0a\x09\x09\x09</dl>\x0a\x09\x09</div>\x0a\x09\x09<!--\x20The\x20package's\x20Name\x20is\x20printed\x20as\x20title\x20by\x20the\x20top-level\x20template\x20-->\x0a\x09\x09<div\x20id=\"pkg-overview\"\x20class=\"toggleVisible\">\x0a\x09\x09\x09<div\x20class=\"collapsed\">\x0a\x09\x09\x09\x09<h2\x20class=\"toggleButton\"\x20title=\"Click\x20to\x20show\x20Overview\x20section\">Overview\x20\xe2\x96\xb9</h2>\x0a\x09\x09\x09</div>\x0a\x09\x09\x09<div\x20class=\"expanded\">\x0a\x09\x09\x09\x09<h2\x20class=\"toggleButton\"\x20title=\"Click\x20to\x20hide\x20Overview\x20section\">Overview\x20\xe2\x96\xbe</h2>\x0a\x09\x09\x09\x09{{comment_html\x20.Doc}}\x0a\x09\x09\x09\x09{{example_html\x20$\x20\"\"}}\x0a\x09\x09\x09</div>\x0a\x09\x09</div>\x0a\x0a\x09\x09<div\x20id=\"pkg-index\"\x20class=\"toggleVisible\">\x0a\x09\x09<div\x20class=\"collapsed\">\x0a\x09\x09\x09<h2\x20class=\"toggleButton\"\x20title=\"Click\x20to\x20show\x20Index\x20section\">Index\x20\xe2\x96\xb9</h2>\x0a\x09\x09</div>\x0a\x09\x09<div\x20class=\"expanded\">\x0a\x09\x09\x09<h2\x20class=\"toggleButton\"\x20title=\"Click\x20to\x20hide\x20Index\x20section\">Index\x20\xe2\x96\xbe</h2>\x0a\x0a\x09\x09<!--\x20Table\x20of\x20contents\x20for\x20API;\x20must\x20be\x20named\x20manual-nav\x20to\x20turn\x20off\x20auto\x20nav.\x20-->\x0a\x09\x09\x09<div\x20id=\"manual-nav\">\x0a\x09\x09\x09<dl>\x0a\x09\x09\x09{{if\x20.Consts}}\x0a\x09\x09\x09\x09<dd><a\x20href=\"#pkg-constants\">Constants</a></dd>\x0a\x09\x09\x09{{end}}\x0a\x09\x09\x09{{if\x20.Vars}}\x0a\x09\x09\x09\x09<dd><a\x20href=\"#pkg-variables\">Variables</a></dd>\x0a\x09\x09\x09{{end}}\x0a\x09\x09\x09{{range\x20.Funcs}}\x0a\x09\x09\x09\x09{{$name_html\x20:=\x20html\x20.Name}}\x0a\x09\x09\x09\x09<dd><a\x20href=\"#{{$name_html}}\">{{node_html\x20$\x20.Decl\x20false\x20|\x20sanitize}}</a></dd>\x0a\x09\x09\x09{{end}}\x0a\x09\x09\x09{{range\x20.Types}}\x0a\x09\x09\x09\x09{{$tname_html\x20:=\x20html\x20.Name}}\x0a\x09\x09\x09\x09<dd><a\x20href=\"#{{$tname_html}}\">type\x20{{$tname_html}}</a></dd>\x0a\x09\x09\x09\x09{{range\x20.Funcs}}\x0a\x09\x09\x09\x09\x09{{$name_html\x20:=\x20html\x20.Name}}\x0a\x09\x09\x09\x09\x09<dd>&nbsp;\x20&nbsp;\x20<a\x20href=\"#{{$name_html}}\">{{node_html\x20$\x20.Decl\x20false\x20|\x20sanitize}}</a></dd>\x0a\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09{{range\x20.Methods}}\x0a\x09\x09\x09\x09\x09{{$name_html\x20:=\x20html\x20.Name}}\x0a\x09\x09\x09\x09\x09<dd>&nbsp;\x20&nbsp;\x20<a\x20href=\"#{{$tname_html}}.{{$name_html}}\">{{node_html\x20$\x20.Decl\x20false\x20|\x20sanitize}}</a></dd>\x0a\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09{{end}}\x0a\x09\x09\x09{{if\x20$.Notes}}\x0a\x09\x09\x09\x09{{range\x20$marker,\x20$item\x20:=\x20$.Notes}}\x0a\x09\x09\x09\x09<dd><a\x20href=\"#pkg-note-{{$marker}}\">{{noteTitle\x20$marker\x20|\x20html}}s</a></dd>\x0a\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09{{end}}\x0a\x09\x09\x09</dl>\x0a\x09\x09\x09</div><!--\x20#manual-nav\x20-->\x0a\x0a\x09\x09{{if\x20$.Examples}}\x0a\x09\x09<div\x20id=\"pkg-examples\">\x0a\x09\x09\x09<h3>Examples</h3>\x0a\x09\x09\x09<div\x20class=\"js-expandAll\x20expandAll\x20collapsed\">(Expand\x20All)</div>\x0a\x09\x09\x09<dl>\x0a\x09\x09\x09{{range\x20$.Examples}}\x0a\x09\x09\x09<dd><a\x20class=\"exampleLink\"\x20href=\"#example_{{.Name}}\">{{example_name\x20.Name}}</a></dd>\x0a\x09\x09\x09{{end}}\x0a\x09\x09\x09</dl>\x0a\x09\x09</div>\x0a\x09\x09{{end}}\x0a\x0a\x09\x09{{with\x20.Filenames}}\x0a\x09\x09\x09<h3>Package\x20files</h3>\x0a\x09\x09\x09<p>\x0a\x09\x09\x09<span\x20style=\"font-size:90%\">\x0a\x09\x09\x09{{range\x20.}}\x0a\x09\x09\x09\x09<a\x20href=\"{{.|srcLink|html}}\">{{.|filename|html}}</a>\x0a\x09\x09\x09{{end}}\x0a\x09\x09\x09</span>\x0a\x09\x09\x09</p>\x0a\x09\x09{{end}}\x0a\x09\x09</div><!--\x20.expanded\x20-->\x0a\x09\x09</div><!--\x20#pkg-index\x20-->\x0a\x0a\x09\x09{{if\x20ne\x20$.CallGraph\x20\"null\"}}\x0a\x09\x09<div\x20id=\"pkg-callgraph\"\x20class=\"toggle\"\x20style=\"display:\x20none\">\x0a\x09\x09<div\x20class=\"collapsed\">\x0a\x09\x09\x09<h2\x20class=\"toggleButton\"\x20title=\"Click\x20to\x20show\x20Internal\x20Call\x20Graph\x20section\">Internal\x20call\x20graph\x20\xe2\x96\xb9</h2>\x0a\x09\x09</div>\x20<!--\x20.expanded\x20-->\x0a\x09\x09<div\x20class=\"expanded\">\x0a\x09\x09\x09<h2\x20class=\"toggleButton\"\x20title=\"Click\x20to\x20hide\x20Internal\x20Call\x20Graph\x20section\">Internal\x20call\x20graph\x20\xe2\x96\xbe</h2>\x0a\x09\x09\x09<p>\x0a\x09\x09\x09\x20\x20In\x20the\x20call\x20graph\x20viewer\x20below,\x20each\x20node\x0a\x09\x09\x09\x20\x20is\x20a\x20function\x20belonging\x20to\x20this\x20package\x0a\x09\x09\x09\x20\x20and\x20its\x20children\x20are\x20the\x20functions\x20it\x0a\x09\x09\x09\x20\x20calls&mdash;perhaps\x20dynamically.\x0a\x09\x09\x09</p>\x0a\x09\x09\x09<p>\x0a\x09\x09\x09\x20\x20The\x20root\x20nodes\x20are\x20the\x20entry\x20points\x20of\x20the\x0a\x09\x09\x09\x20\x20package:\x20functions\x20that\x20may\x20be\x20called\x20from\x0a\x09\x09\x09\x20\x20outside\x20the\x20package.\x0a\x09\x09\x09\x20\x20There\x20may\x20be\x20non-exported\x20or\x20anonymous\x0a\x09\x09\x09\x20\x20functions\x20among\x20them\x20if\x20they\x20are\x20called\x0a\x09\x09\x09\x20\x20dynamically\x20from\x20another\x20package.\x0a\x09\x09\x09</p>\x0a\x09\x09\x09<p>\x0a\x09\x09\x09\x20\x20Click\x20a\x20node\x20to\x20visit\x20that\x20function's\x20source\x20code.\x0a\x09\x09\x09\x20\x20From\x20there\x20you\x20can\x20visit\x20its\x20callers\x20by\x0a\x09\x09\x09\x20\x20clicking\x20its\x20declaring\x20<code>func</code>\x0a\x09\x09\x09\x20\x20token.\x0a\x09\x09\x09</p>\x0a\x09\x09\x09<p>\x0a\x09\x09\x09\x20\x20Functions\x20may\x20be\x20omitted\x20if\x20they\x20were\x0a\x09\x09\x09\x20\x20determined\x20to\x20be\x20unreachable\x20in\x20the\x0a\x09\x09\x09\x20\x20particular\x20programs\x20or\x20tests\x20that\x20were\x0a\x09\x09\x09\x20\x20analyzed.\x0a\x09\x09\x09</p>\x0a\x09\x09\x09<!--\x20Zero\x20means\x20show\x20all\x20package\x20entry\x20points.\x20-->\x0a\x09\x09\x09<ul\x20style=\"margin-left:\x200.5in\"\x20id=\"callgraph-0\"\x20class=\"treeview\"></ul>\x0a\x09\x09</div>\x0a\x09\x09</div>\x20<!--\x20#pkg-callgraph\x20-->\x0a\x09\x09{{end}}\x0a\x0a\x09\x09{{with\x20.Consts}}\x0a\x09\x09\x09<h2\x20id=\"pkg-constants\">Constants</h2>\x0a\x09\x09\x09{{range\x20.}}\x0a\x09\x09\x09\x09{{comment_html\x20.Doc}}\x0a\x09\x09\x09\x09<pre>{{node_html\x20$\x20.Decl\x20true}}</pre>\x0a\x09\x09\x09{{end}}\x0a\x09\x09{{end}}\x0a\x09\x09{{with\x20.Vars}}\x0a\x09\x09\x09<h2\x20id=\"pkg-variables\">Variables</h2>\x0a\x09\x09\x09{{range\x20.}}\x0a\x09\x09\x09\x09{{comment_html\x20.Doc}}\x0a\x09\x09\x09\x09<pre>{{node_html\x20$\x20.Decl\x20true}}</pre>\x0a\x09\x09\x09{{end}}\x0a\x09\x09{{end}}\x0a\x09\x09{{range\x20.Funcs}}\x0a\x09\x09\x09{{/*\x20Name\x20is\x20a\x20string\x20-\x20no\x20need\x20for\x20FSet\x20*/}}\x0a\x09\x09\x09{{$name_html\x20:=\x20html\x20.Name}}\x0a\x09\x09\x09<h2\x20id=\"{{$name_html}}\">func\x20<a\x20href=\"{{posLink_url\x20$\x20.Decl}}\">{{$name_html}}</a>\x0a\x09\x09\x09\x09<a\x20class=\"permalink\"\x20href=\"#{{$name_html}}\">&#xb6;</a>\x0a\x09\x09\x09\x09{{$since\x20:=\x20since\x20\"func\"\x20\"\"\x20.Name\x20$.PDoc.ImportPath}}\x0a\x09\x09\x09\x09{{if\x20$since}}<span\x20title=\"Added\x20in\x20Go\x20{{$since}}\">{{$since}}</span>{{end}}\x0a\x09\x09\x09</h2>\x0a\x09\x09\x09<pre>{{node_html\x20$\x20.Decl\x20true}}</pre>\x0a\x09\x09\x09{{comment_html\x20.Doc}}\x0a\x09\x09\x09{{example_html\x20$\x20.Name}}\x0a\x09\x09\x09{{callgraph_html\x20$\x20\"\"\x20.Name}}\x0a\x0a\x09\x09{{end}}\x0a\x09\x09{{range\x20.Types}}\x0a\x09\x09\x09{{$tname\x20:=\x20.Name}}\x0a\x09\x09\x09{{$tname_html\x20:=\x20html\x20.Name}}\x0a\x09\x09\x09<h2\x20id=\"{{$tname_html}}\">type\x20<a\x20href=\"{{posLink_url\x20$\x20.Decl}}\">{{$tname_html}}</a>\x0a\x09\x09\x09\x09<a\x20class=\"permalink\"\x20href=\"#{{$tname_html}}\">&#xb6;</a>\x0a\x09\x09\x09\x09{{$since\x20:=\x20since\x20\"type\"\x20\"\"\x20.Name\x20$.PDoc.ImportPath}}\x0a\x09\x09\x09\x09{{if\x20$since}}<span\x20title=\"Added\x20in\x20Go\x20{{$since}}\">{{$since}}</span>{{end}}\x0a\x09\x09\x09</h2>\x0a\x09\x09\x09{{comment_html\x20.Doc}}\x0a\x09\x09\x09<pre>{{node_html\x20$\x20.Decl\x20true}}</pre>\x0a\x0a\x09\x09\x09{{range\x20.Consts}}\x0a\x09\x09\x09\x09{{comment_html\x20.Doc}}\x0a\x09\x09\x09\x09<pre>{{node_html\x20$\x20.Decl\x20true}}</pre>\x0a\x09\x09\x09{{end}}\x0a\x0a\x09\x09\x09{{range\x20.Vars}}\x0a\x09\x09\x09\x09{{comment_html\x20.Doc}}\x0a\x09\x09\x09\x09<pre>{{node_html\x20$\x20.Decl\x20true}}</pre>\x0a\x09\x09\x09{{end}}\x0a\x0a\x09\x09\x09{{example_html\x20$\x20$tname}}\x0a\x09\x09\x09{{implements_html\x20$\x20$tname}}\x0a\x09\x09\x09{{methodset_html\x20$\x20$tname}}\x0a\x0a\x09\x09\x09{{range\x20.Funcs}}\x0a\x09\x09\x09\x09{{$name_html\x20:=\x20html\x20.Name}}\x0a\x09\x09\x09\x09<h3\x20id=\"{{$name_html}}\">func\x20<a\x20href=\"{{posLink_url\x20$\x20.Decl}}\">{{$name_html}}</a>\x0a\x09\x09\x09\x09\x09<a\x20class=\"permalink\"\x20href=\"#{{$name_html}}\">&#xb6;</a>\x0a\x09\x09\x09\x09\x09{{$since\x20:=\x20since\x20\"func\"\x20\"\"\x20.Name\x20$.PDoc.ImportPath}}\x0a\x09\x09\x09\x09\x09{{if\x20$since}}<span\x20title=\"Added\x20in\x20Go\x20{{$since}}\">{{$since}}</span>{{end}}\x0a\x09\x09\x09\x09</h3>\x0a\x09\x09\x09\x09<pre>{{node_html\x20$\x20.Decl\x20true}}</pre>\x0a\x09\x09\x09\x09{{comment_html\x20.Doc}}\x0a\x09\x09\x09\x09{{example_html\x20$\x20.Name}}\x0a\x09\x09\x09\x09{{callgraph_html\x20$\x20\"\"\x20.Name}}\x0a\x09\x09\x09{{end}}\x0a\x0a\x09\x09\x09{{range\x20.Methods}}\x0a\x09\x09\x09\x09{{$name_html\x20:=\x20html\x20.Name}}\x0a\x09\x09\x09\x09<h3\x20id=\"{{$tname_html}}.{{$name_html}}\">func\x20({{html\x20.Recv}})\x20<a\x20href=\"{{posLink_url\x20$\x20.Decl}}\">{{$name_html}}</a>\x0a\x09\x09\x09\x09\x09<a\x20class=\"permalink\"\x20href=\"#{{$tname_html}}.{{$name_html}}\">&#xb6;</a>\x0a\x09\x09\x09\x09\x09{{$since\x20:=\x20since\x20\"method\"\x20.Recv\x20.Name\x20$.PDoc.ImportPath}}\x0a\x09\x09\x09\x09\x09{{if\x20$since}}<span\x20title=\"Added\x20in\x20Go\x20{{$since}}\">{{$since}}</span>{{end}}\x0a\x09\x09\x09\x09</h3>\x0a\x09\x09\x09\x09<pre>{{node_html\x20$\x20.Decl\x20true}}</pre>\x0a\x09\x09\x09\x09{{comment_html\x20.Doc}}\x0a\x09\x09\x09\x09{{$name\x20:=\x20printf\x20\"%s_%s\"\x20$tname\x20.Name}}\x0a\x09\x09\x09\x09{{example_html\x20$\x20$name}}\x0a\x09\x09\x09\x09{{callgraph_html\x20$\x20.Recv\x20.Name}}\x0a\x09\x09\x09{{end}}\x0a\x09\x09{{end}}\x0a\x09{{end}}\x0a\x0a\x09{{with\x20$.Notes}}\x0a\x09\x09{{range\x20$marker,\x20$content\x20:=\x20.}}\x0a\x09\x09\x09<h2\x20id=\"pkg-note-{{$marker}}\">{{noteTitle\x20$marker\x20|\x20html}}s</h2>\x0a\x09\x09\x09<ul\x20style=\"list-style:\x20none;\x20padding:\x200;\">\x0a\x09\x09\x09{{range\x20.}}\x0a\x09\x09\x09<li><a\x20href=\"{{posLink_url\x20$\x20.}}\"\x20style=\"float:\x20left;\">&#x261e;</a>\x20{{comment_html\x20.Body}}</li>\x0a\x09\x09\x09{{end}}\x0a\x09\x09\x09</ul>\x0a\x09\x09{{end}}\x0a\x09{{end}}\x0a{{end}}\x0a\x0a{{with\x20.PAst}}\x0a\x09{{range\x20$filename,\x20$ast\x20:=\x20.}}\x0a\x09\x09<a\x20href=\"{{$filename|srcLink|html}}\">{{$filename|filename|html}}</a>:<pre>{{node_html\x20$\x20$ast\x20false}}</pre>\x0a\x09{{end}}\x0a{{end}}\x0a\x0a{{with\x20.Dirs}}\x0a\x09{{/*\x20DirList\x20entries\x20are\x20numbers\x20and\x20strings\x20-\x20no\x20need\x20for\x20FSet\x20*/}}\x0a\x09{{if\x20$.PDoc}}\x0a\x09\x09<h2\x20id=\"pkg-subdirectories\">Subdirectories</h2>\x0a\x09{{end}}\x0a\x09<div\x20class=\"pkg-dir\">\x0a\x09\x09<table>\x0a\x09\x09\x09<tr>\x0a\x09\x09\x09\x09<th\x20class=\"pkg-name\">Name</th>\x0a\x09\x09\x09\x09<th\x20class=\"pkg-synopsis\">Synopsis</th>\x0a\x09\x09\x09</tr>\x0a\x0a\x09\x09\x09{{if\x20not\x20(or\x20(eq\x20$.Dirname\x20\"/src/cmd\")\x20$.DirFlat)}}\x0a\x09\x09\x09<tr>\x0a\x09\x09\x09\x09<td\x20colspan=\"2\"><a\x20href=\"..\">..</a></td>\x0a\x09\x09\x09</tr>\x0a\x09\x09\x09{{end}}\x0a\x0a\x09\x09\x09{{range\x20.List}}\x0a\x09\x09\x09\x09<tr>\x0a\x09\x09\x09\x09{{if\x20$.DirFlat}}\x0a\x09\x09\x09\x09\x09{{if\x20.HasPkg}}\x0a\x09\x09\x09\x09\x09\x09<td\x20class=\"pkg-name\">\x0a\x09\x09\x09\x09\x09\x09\x09<a\x20href=\"{{html\x20.Path}}/{{modeQueryString\x20$.Mode\x20|\x20html}}\">{{html\x20.Path}}</a>\x0a\x09\x09\x09\x09\x09\x09</td>\x0a\x09\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09{{else}}\x0a\x09\x09\x09\x09\x09<td\x20class=\"pkg-name\"\x20style=\"padding-left:\x20{{multiply\x20.Depth\x2020}}px;\">\x0a\x09\x09\x09\x09\x09\x09<a\x20href=\"{{html\x20.Path}}/{{modeQueryString\x20$.Mode\x20|\x20html}}\">{{html\x20.Name}}</a>\x0a\x09\x09\x09\x09\x09</td>\x0a\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09\x09<td\x20class=\"pkg-synopsis\">\x0a\x09\x09\x09\x09\x09\x09{{html\x20.Synopsis}}\x0a\x09\x09\x09\x09\x09</td>\x0a\x09\x09\x09\x09</tr>\x0a\x09\x09\x09{{end}}\x0a\x09\x09</table>\x0a\x09</div>\x0a{{end}}\x0a",
 
-	"packageroot.html": "<!--\x0a\x09Copyright\x202018\x20The\x20Go\x20Authors.\x20All\x20rights\x20reserved.\x0a\x09Use\x20of\x20this\x20source\x20code\x20is\x20governed\x20by\x20a\x20BSD-style\x0a\x09license\x20that\x20can\x20be\x20found\x20in\x20the\x20LICENSE\x20file.\x0a-->\x0a<!--\x0a\x09Note:\x20Static\x20(i.e.,\x20not\x20template-generated)\x20href\x20and\x20id\x0a\x09attributes\x20start\x20with\x20\"pkg-\"\x20to\x20make\x20it\x20impossible\x20for\x0a\x09them\x20to\x20conflict\x20with\x20generated\x20attributes\x20(some\x20of\x20which\x0a\x09correspond\x20to\x20Go\x20identifiers).\x0a-->\x0a{{with\x20.PAst}}\x0a\x09{{range\x20$filename,\x20$ast\x20:=\x20.}}\x0a\x09\x09<a\x20href=\"{{$filename|srcLink|html}}\">{{$filename|filename|html}}</a>:<pre>{{node_html\x20$\x20$ast\x20false}}</pre>\x0a\x09{{end}}\x0a{{end}}\x0a\x0a{{with\x20.Dirs}}\x0a\x09{{/*\x20DirList\x20entries\x20are\x20numbers\x20and\x20strings\x20-\x20no\x20need\x20for\x20FSet\x20*/}}\x0a\x09{{if\x20$.PDoc}}\x0a\x09\x09<h2\x20id=\"pkg-subdirectories\">Subdirectories</h2>\x0a\x09{{end}}\x0a\x09\x09<div\x20id=\"manual-nav\">\x0a\x09\x09\x09<dl>\x0a\x09\x09\x09\x09<dt><a\x20href=\"#stdlib\">Standard\x20library</a></dt>\x0a\x09\x09\x09\x09{{if\x20hasThirdParty\x20.List\x20}}\x0a\x09\x09\x09\x09\x09<dt><a\x20href=\"#thirdparty\">Third\x20party</a></dt>\x0a\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09<dt><a\x20href=\"#other\">Other\x20packages</a></dt>\x0a\x09\x09\x09\x09<dd><a\x20href=\"#subrepo\">Sub-repositories</a></dd>\x0a\x09\x09\x09\x09<dd><a\x20href=\"#community\">Community</a></dd>\x0a\x09\x09\x09</dl>\x0a\x09\x09</div>\x0a\x0a\x09\x09<div\x20id=\"stdlib\"\x20class=\"toggleVisible\">\x0a\x09\x09\x09<div\x20class=\"collapsed\">\x0a\x09\x09\x09\x09<h2\x20class=\"toggleButton\"\x20title=\"Click\x20to\x20show\x20Standard\x20library\x20section\">Standard\x20library\x20\xe2\x96\xb9</h2>\x0a\x09\x09\x09</div>\x0a\x09\x09\x09<div\x20class=\"expanded\">\x0a\x09\x09\x09\x09<h2\x20class=\"toggleButton\"\x20title=\"Click\x20to\x20hide\x20Standard\x20library\x20section\">Standard\x20library\x20\xe2\x96\xbe</h2>\x0a\x09\x09\x09\x09<img\x20alt=\"\"\x20class=\"gopher\"\x20src=\"/doc/gopher/pkg.png\"/>\x0a\x09\x09\x09\x09<div\x20class=\"pkg-dir\">\x0a\x09\x09\x09\x09\x09<table>\x0a\x09\x09\x09\x09\x09\x09<tr>\x0a\x09\x09\x09\x09\x09\x09\x09<th\x20class=\"pkg-name\">Name</th>\x0a\x09\x09\x09\x09\x09\x09\x09<th\x20class=\"pkg-synopsis\">Synopsis</th>\x0a\x09\x09\x09\x09\x09\x09</tr>\x0a\x0a\x09\x09\x09\x09\x09\x09{{range\x20.List}}\x0a\x09\x09\x09\x09\x09\x09\x09<tr>\x0a\x09\x09\x09\x09\x09\x09\x09{{if\x20eq\x20.RootType\x20\"GOROOT\"}}\x0a\x09\x09\x09\x09\x09\x09\x09{{if\x20$.DirFlat}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09{{if\x20.HasPkg}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09<td\x20class=\"pkg-name\">\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09<a\x20href=\"{{html\x20.Path}}/{{modeQueryString\x20$.Mode\x20|\x20html}}\">{{html\x20.Path}}</a>\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09</td>\x0a\x09\x09\x09\x09\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09\x09\x09\x09{{else}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09<td\x20class=\"pkg-name\"\x20style=\"padding-left:\x20{{multiply\x20.Depth\x2020}}px;\">\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09<a\x20href=\"{{html\x20.Path}}/{{modeQueryString\x20$.Mode\x20|\x20html}}\">{{html\x20.Name}}</a>\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09</td>\x0a\x09\x09\x09\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09<td\x20class=\"pkg-synopsis\">\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09{{html\x20.Synopsis}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09</td>\x0a\x09\x09\x09\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09\x09\x09\x09</tr>\x0a\x09\x09\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09\x09</table>\x0a\x09\x09\x09\x09</div>\x20<!--\x20.pkg-dir\x20-->\x0a\x09\x09\x09</div>\x20<!--\x20.expanded\x20-->\x0a\x09\x09</div>\x20<!--\x20#stdlib\x20.toggleVisible\x20-->\x0a\x0a\x09{{if\x20hasThirdParty\x20.List\x20}}\x0a\x09\x09<div\x20id=\"thirdparty\"\x20class=\"toggleVisible\">\x0a\x09\x09\x09<div\x20class=\"collapsed\">\x0a\x09\x09\x09\x09<h2\x20class=\"toggleButton\"\x20title=\"Click\x20to\x20show\x20Third\x20party\x20section\">Third\x20party\x20\xe2\x96\xb9</h2>\x0a\x09\x09\x09</div>\x0a\x09\x09\x09<div\x20class=\"expanded\">\x0a\x09\x09\x09\x09<h2\x20class=\"toggleButton\"\x20title=\"Click\x20to\x20hide\x20Third\x20party\x20section\">Third\x20party\x20\xe2\x96\xbe</h2>\x0a\x09\x09\x09\x09<div\x20class=\"pkg-dir\">\x0a\x09\x09\x09\x09\x09<table>\x0a\x09\x09\x09\x09\x09\x09<tr>\x0a\x09\x09\x09\x09\x09\x09\x09<th\x20class=\"pkg-name\">Name</th>\x0a\x09\x09\x09\x09\x09\x09\x09<th\x20class=\"pkg-synopsis\">Synopsis</th>\x0a\x09\x09\x09\x09\x09\x09</tr>\x0a\x0a\x09\x09\x09\x09\x09\x09{{range\x20.List}}\x0a\x09\x09\x09\x09\x09\x09\x09<tr>\x0a\x09\x09\x09\x09\x09\x09\x09\x09{{if\x20eq\x20.RootType\x20\"GOPATH\"}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09{{if\x20$.DirFlat}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09{{if\x20.HasPkg}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09<td\x20class=\"pkg-name\">\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09<a\x20href=\"{{html\x20.Path}}/{{modeQueryString\x20$.Mode\x20|\x20html}}\">{{html\x20.Path}}</a>\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09</td>\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09{{else}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09<td\x20class=\"pkg-name\"\x20style=\"padding-left:\x20{{multiply\x20.Depth\x2020}}px;\">\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09<a\x20href=\"{{html\x20.Path}}/{{modeQueryString\x20$.Mode\x20|\x20html}}\">{{html\x20.Name}}</a>\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09</td>\x0a\x09\x09\x09\x09\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09<td\x20class=\"pkg-synopsis\">\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09{{html\x20.Synopsis}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09</td>\x0a\x09\x09\x09\x09\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09\x09\x09\x09</tr>\x0a\x09\x09\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09\x09</table>\x0a\x09\x09\x09\x09</div>\x20<!--\x20.pkg-dir\x20-->\x0a\x09\x09\x09</div>\x20<!--\x20.expanded\x20-->\x0a\x09\x09</div>\x20<!--\x20#stdlib\x20.toggleVisible\x20-->\x0a\x09{{end}}\x0a\x0a\x09<h2\x20id=\"other\">Other\x20packages</h2>\x0a\x09<h3\x20id=\"subrepo\">Sub-repositories</h3>\x0a\x09<p>\x0a\x09These\x20packages\x20are\x20part\x20of\x20the\x20Go\x20Project\x20but\x20outside\x20the\x20main\x20Go\x20tree.\x0a\x09They\x20are\x20developed\x20under\x20looser\x20<a\x20href=\"/doc/go1compat\">compatibility\x20requirements</a>\x20than\x20the\x20Go\x20core.\x0a\x09Install\x20them\x20with\x20\"<a\x20href=\"/cmd/go/#hdr-Download_and_install_packages_and_dependencies\">go\x20get</a>\".\x0a\x09</p>\x0a\x09<ul>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/benchmarks\">benchmarks</a>\x20\xe2\x80\x94\x20benchmarks\x20to\x20measure\x20Go\x20as\x20it\x20is\x20developed.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/blog\">blog</a>\x20\xe2\x80\x94\x20<a\x20href=\"//blog.golang.org\">blog.golang.org</a>'s\x20implementation.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/build\">build</a>\x20\xe2\x80\x94\x20<a\x20href=\"//build.golang.org\">build.golang.org</a>'s\x20implementation.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/crypto\">crypto</a>\x20\xe2\x80\x94\x20additional\x20cryptography\x20packages.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/debug\">debug</a>\x20\xe2\x80\x94\x20an\x20experimental\x20debugger\x20for\x20Go.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/image\">image</a>\x20\xe2\x80\x94\x20additional\x20imaging\x20packages.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/mobile\">mobile</a>\x20\xe2\x80\x94\x20experimental\x20support\x20for\x20Go\x20on\x20mobile\x20platforms.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/net\">net</a>\x20\xe2\x80\x94\x20additional\x20networking\x20packages.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/perf\">perf</a>\x20\xe2\x80\x94\x20packages\x20and\x20tools\x20for\x20performance\x20measurement,\x20storage,\x20and\x20analysis.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/pkgsite\">pkgsite</a>\x20\xe2\x80\x94\x20home\x20of\x20the\x20pkg.go.dev\x20website.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/review\">review</a>\x20\xe2\x80\x94\x20a\x20tool\x20for\x20working\x20with\x20Gerrit\x20code\x20reviews.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/sync\">sync</a>\x20\xe2\x80\x94\x20additional\x20concurrency\x20primitives.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/sys\">sys</a>\x20\xe2\x80\x94\x20packages\x20for\x20making\x20system\x20calls.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/text\">text</a>\x20\xe2\x80\x94\x20packages\x20for\x20working\x20with\x20text.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/time\">time</a>\x20\xe2\x80\x94\x20additional\x20time\x20packages.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/tools\">tools</a>\x20\xe2\x80\x94\x20godoc,\x20goimports,\x20gorename,\x20and\x20other\x20tools.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/tour\">tour</a>\x20\xe2\x80\x94\x20<a\x20href=\"//tour.golang.org\">tour.golang.org</a>'s\x20implementation.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/exp\">exp</a>\x20\xe2\x80\x94\x20experimental\x20and\x20deprecated\x20packages\x20(handle\x20with\x20care;\x20may\x20change\x20without\x20warning).</li>\x0a\x09</ul>\x0a\x0a\x09<h3\x20id=\"community\">Community</h3>\x0a\x09<p>\x0a\x09These\x20services\x20can\x20help\x20you\x20find\x20Open\x20Source\x20packages\x20provided\x20by\x20the\x20community.\x0a\x09</p>\x0a\x09<ul>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev\">Pkg.go.dev</a>\x20-\x20the\x20Go\x20package\x20discovery\x20site.</li>\x0a\x09\x09<li><a\x20href=\"/wiki/Projects\">Projects\x20at\x20the\x20Go\x20Wiki</a>\x20-\x20a\x20curated\x20list\x20of\x20Go\x20projects.</li>\x0a\x09</ul>\x0a{{end}}\x0a",
+	"packageroot.html": "<!--\x0a\x09Copyright\x202018\x20The\x20Go\x20Authors.\x20All\x20rights\x20reserved.\x0a\x09Use\x20of\x20this\x20source\x20code\x20is\x20governed\x20by\x20a\x20BSD-style\x0a\x09license\x20that\x20can\x20be\x20found\x20in\x20the\x20LICENSE\x20file.\x0a-->\x0a<!--\x0a\x09Note:\x20Static\x20(i.e.,\x20not\x20template-generated)\x20href\x20and\x20id\x0a\x09attributes\x20start\x20with\x20\"pkg-\"\x20to\x20make\x20it\x20impossible\x20for\x0a\x09them\x20to\x20conflict\x20with\x20generated\x20attributes\x20(some\x20of\x20which\x0a\x09correspond\x20to\x20Go\x20identifiers).\x0a-->\x0a{{with\x20.PAst}}\x0a\x09{{range\x20$filename,\x20$ast\x20:=\x20.}}\x0a\x09\x09<a\x20href=\"{{$filename|srcLink|html}}\">{{$filename|filename|html}}</a>:<pre>{{node_html\x20$\x20$ast\x20false}}</pre>\x0a\x09{{end}}\x0a{{end}}\x0a\x0a{{with\x20.Dirs}}\x0a\x09{{/*\x20DirList\x20entries\x20are\x20numbers\x20and\x20strings\x20-\x20no\x20need\x20for\x20FSet\x20*/}}\x0a\x09{{if\x20$.PDoc}}\x0a\x09\x09<h2\x20id=\"pkg-subdirectories\">Subdirectories</h2>\x0a\x09{{end}}\x0a\x09\x09<div\x20id=\"manual-nav\">\x0a\x09\x09\x09<dl>\x0a\x09\x09\x09\x09<dt><a\x20href=\"#stdlib\">Standard\x20library</a></dt>\x0a\x09\x09\x09\x09{{if\x20hasThirdParty\x20.List\x20}}\x0a\x09\x09\x09\x09\x09<dt><a\x20href=\"#thirdparty\">Third\x20party</a></dt>\x0a\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09<dt><a\x20href=\"#other\">Other\x20packages</a></dt>\x0a\x09\x09\x09\x09<dd><a\x20href=\"#subrepo\">Sub-repositories</a></dd>\x0a\x09\x09\x09\x09<dd><a\x20href=\"#community\">Community</a></dd>\x0a\x09\x09\x09</dl>\x0a\x09\x09</div>\x0a\x0a\x09\x09<div\x20id=\"stdlib\"\x20class=\"toggleVisible\">\x0a\x09\x09\x09<div\x20class=\"collapsed\">\x0a\x09\x09\x09\x09<h2\x20class=\"toggleButton\"\x20title=\"Click\x20to\x20show\x20Standard\x20library\x20section\">Standard\x20library\x20\xe2\x96\xb9</h2>\x0a\x09\x09\x09</div>\x0a\x09\x09\x09<div\x20class=\"expanded\">\x0a\x09\x09\x09\x09<h2\x20class=\"toggleButton\"\x20title=\"Click\x20to\x20hide\x20Standard\x20library\x20section\">Standard\x20library\x20\xe2\x96\xbe</h2>\x0a\x09\x09\x09\x09<img\x20alt=\"\"\x20class=\"gopher\"\x20src=\"https://golang.org/doc/gopher/pkg.png\"/>\x0a\x09\x09\x09\x09<div\x20class=\"pkg-dir\">\x0a\x09\x09\x09\x09\x09<table>\x0a\x09\x09\x09\x09\x09\x09<tr>\x0a\x09\x09\x09\x09\x09\x09\x09<th\x20class=\"pkg-name\">Name</th>\x0a\x09\x09\x09\x09\x09\x09\x09<th\x20class=\"pkg-synopsis\">Synopsis</th>\x0a\x09\x09\x09\x09\x09\x09</tr>\x0a\x0a\x09\x09\x09\x09\x09\x09{{range\x20.List}}\x0a\x09\x09\x09\x09\x09\x09\x09<tr>\x0a\x09\x09\x09\x09\x09\x09\x09{{if\x20eq\x20.RootType\x20\"GOROOT\"}}\x0a\x09\x09\x09\x09\x09\x09\x09{{if\x20$.DirFlat}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09{{if\x20.HasPkg}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09<td\x20class=\"pkg-name\">\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09<a\x20href=\"{{html\x20.Path}}/{{modeQueryString\x20$.Mode\x20|\x20html}}\">{{html\x20.Path}}</a>\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09</td>\x0a\x09\x09\x09\x09\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09\x09\x09\x09{{else}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09<td\x20class=\"pkg-name\"\x20style=\"padding-left:\x20{{multiply\x20.Depth\x2020}}px;\">\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09<a\x20href=\"{{html\x20.Path}}/{{modeQueryString\x20$.Mode\x20|\x20html}}\">{{html\x20.Name}}</a>\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09</td>\x0a\x09\x09\x09\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09<td\x20class=\"pkg-synopsis\">\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09{{html\x20.Synopsis}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09</td>\x0a\x09\x09\x09\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09\x09\x09\x09</tr>\x0a\x09\x09\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09\x09</table>\x0a\x09\x09\x09\x09</div>\x20<!--\x20.pkg-dir\x20-->\x0a\x09\x09\x09</div>\x20<!--\x20.expanded\x20-->\x0a\x09\x09</div>\x20<!--\x20#stdlib\x20.toggleVisible\x20-->\x0a\x0a\x09{{if\x20hasThirdParty\x20.List\x20}}\x0a\x09\x09<div\x20id=\"thirdparty\"\x20class=\"toggleVisible\">\x0a\x09\x09\x09<div\x20class=\"collapsed\">\x0a\x09\x09\x09\x09<h2\x20class=\"toggleButton\"\x20title=\"Click\x20to\x20show\x20Third\x20party\x20section\">Third\x20party\x20\xe2\x96\xb9</h2>\x0a\x09\x09\x09</div>\x0a\x09\x09\x09<div\x20class=\"expanded\">\x0a\x09\x09\x09\x09<h2\x20class=\"toggleButton\"\x20title=\"Click\x20to\x20hide\x20Third\x20party\x20section\">Third\x20party\x20\xe2\x96\xbe</h2>\x0a\x09\x09\x09\x09<div\x20class=\"pkg-dir\">\x0a\x09\x09\x09\x09\x09<table>\x0a\x09\x09\x09\x09\x09\x09<tr>\x0a\x09\x09\x09\x09\x09\x09\x09<th\x20class=\"pkg-name\">Name</th>\x0a\x09\x09\x09\x09\x09\x09\x09<th\x20class=\"pkg-synopsis\">Synopsis</th>\x0a\x09\x09\x09\x09\x09\x09</tr>\x0a\x0a\x09\x09\x09\x09\x09\x09{{range\x20.List}}\x0a\x09\x09\x09\x09\x09\x09\x09<tr>\x0a\x09\x09\x09\x09\x09\x09\x09\x09{{if\x20eq\x20.RootType\x20\"GOPATH\"}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09{{if\x20$.DirFlat}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09{{if\x20.HasPkg}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09<td\x20class=\"pkg-name\">\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09<a\x20href=\"{{html\x20.Path}}/{{modeQueryString\x20$.Mode\x20|\x20html}}\">{{html\x20.Path}}</a>\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09</td>\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09{{else}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09<td\x20class=\"pkg-name\"\x20style=\"padding-left:\x20{{multiply\x20.Depth\x2020}}px;\">\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09<a\x20href=\"{{html\x20.Path}}/{{modeQueryString\x20$.Mode\x20|\x20html}}\">{{html\x20.Name}}</a>\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09</td>\x0a\x09\x09\x09\x09\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09<td\x20class=\"pkg-synopsis\">\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09{{html\x20.Synopsis}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09</td>\x0a\x09\x09\x09\x09\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09\x09\x09\x09</tr>\x0a\x09\x09\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09\x09</table>\x0a\x09\x09\x09\x09</div>\x20<!--\x20.pkg-dir\x20-->\x0a\x09\x09\x09</div>\x20<!--\x20.expanded\x20-->\x0a\x09\x09</div>\x20<!--\x20#stdlib\x20.toggleVisible\x20-->\x0a\x09{{end}}\x0a\x0a\x09<h2\x20id=\"other\">Other\x20packages</h2>\x0a\x09<h3\x20id=\"subrepo\">Sub-repositories</h3>\x0a\x09<p>\x0a\x09These\x20packages\x20are\x20part\x20of\x20the\x20Go\x20Project\x20but\x20outside\x20the\x20main\x20Go\x20tree.\x0a\x09They\x20are\x20developed\x20under\x20looser\x20<a\x20href=\"https://golang.org/doc/go1compat\">compatibility\x20requirements</a>\x20than\x20the\x20Go\x20core.\x0a\x09Install\x20them\x20with\x20\"<a\x20href=\"/cmd/go/#hdr-Download_and_install_packages_and_dependencies\">go\x20get</a>\".\x0a\x09</p>\x0a\x09<ul>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/benchmarks\">benchmarks</a>\x20\xe2\x80\x94\x20benchmarks\x20to\x20measure\x20Go\x20as\x20it\x20is\x20developed.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/blog\">blog</a>\x20\xe2\x80\x94\x20<a\x20href=\"//blog.golang.org\">blog.golang.org</a>'s\x20implementation.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/build\">build</a>\x20\xe2\x80\x94\x20<a\x20href=\"//build.golang.org\">build.golang.org</a>'s\x20implementation.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/crypto\">crypto</a>\x20\xe2\x80\x94\x20additional\x20cryptography\x20packages.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/debug\">debug</a>\x20\xe2\x80\x94\x20an\x20experimental\x20debugger\x20for\x20Go.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/image\">image</a>\x20\xe2\x80\x94\x20additional\x20imaging\x20packages.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/mobile\">mobile</a>\x20\xe2\x80\x94\x20experimental\x20support\x20for\x20Go\x20on\x20mobile\x20platforms.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/net\">net</a>\x20\xe2\x80\x94\x20additional\x20networking\x20packages.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/perf\">perf</a>\x20\xe2\x80\x94\x20packages\x20and\x20tools\x20for\x20performance\x20measurement,\x20storage,\x20and\x20analysis.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/pkgsite\">pkgsite</a>\x20\xe2\x80\x94\x20home\x20of\x20the\x20pkg.go.dev\x20website.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/review\">review</a>\x20\xe2\x80\x94\x20a\x20tool\x20for\x20working\x20with\x20Gerrit\x20code\x20reviews.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/sync\">sync</a>\x20\xe2\x80\x94\x20additional\x20concurrency\x20primitives.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/sys\">sys</a>\x20\xe2\x80\x94\x20packages\x20for\x20making\x20system\x20calls.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/text\">text</a>\x20\xe2\x80\x94\x20packages\x20for\x20working\x20with\x20text.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/time\">time</a>\x20\xe2\x80\x94\x20additional\x20time\x20packages.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/tools\">tools</a>\x20\xe2\x80\x94\x20godoc,\x20goimports,\x20gorename,\x20and\x20other\x20tools.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/tour\">tour</a>\x20\xe2\x80\x94\x20<a\x20href=\"//tour.golang.org\">tour.golang.org</a>'s\x20implementation.</li>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev/golang.org/x/exp\">exp</a>\x20\xe2\x80\x94\x20experimental\x20and\x20deprecated\x20packages\x20(handle\x20with\x20care;\x20may\x20change\x20without\x20warning).</li>\x0a\x09</ul>\x0a\x0a\x09<h3\x20id=\"community\">Community</h3>\x0a\x09<p>\x0a\x09These\x20services\x20can\x20help\x20you\x20find\x20Open\x20Source\x20packages\x20provided\x20by\x20the\x20community.\x0a\x09</p>\x0a\x09<ul>\x0a\x09\x09<li><a\x20href=\"//pkg.go.dev\">Pkg.go.dev</a>\x20-\x20the\x20Go\x20package\x20discovery\x20site.</li>\x0a\x09\x09<li><a\x20href=\"/wiki/Projects\">Projects\x20at\x20the\x20Go\x20Wiki</a>\x20-\x20a\x20curated\x20list\x20of\x20Go\x20projects.</li>\x0a\x09</ul>\x0a{{end}}\x0a",
 
 	"play.js": "//\x20Copyright\x202012\x20The\x20Go\x20Authors.\x20All\x20rights\x20reserved.\x0a//\x20Use\x20of\x20this\x20source\x20code\x20is\x20governed\x20by\x20a\x20BSD-style\x0a//\x20license\x20that\x20can\x20be\x20found\x20in\x20the\x20LICENSE\x20file.\x0a\x0afunction\x20initPlayground(transport)\x20{\x0a\x20\x20'use\x20strict';\x0a\x0a\x20\x20function\x20text(node)\x20{\x0a\x20\x20\x20\x20var\x20s\x20=\x20'';\x0a\x20\x20\x20\x20for\x20(var\x20i\x20=\x200;\x20i\x20<\x20node.childNodes.length;\x20i++)\x20{\x0a\x20\x20\x20\x20\x20\x20var\x20n\x20=\x20node.childNodes[i];\x0a\x20\x20\x20\x20\x20\x20if\x20(n.nodeType\x20===\x201)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20if\x20(n.tagName\x20===\x20'BUTTON')\x20continue;\x0a\x20\x20\x20\x20\x20\x20\x20\x20if\x20(n.tagName\x20===\x20'SPAN'\x20&&\x20n.className\x20===\x20'number')\x20continue;\x0a\x20\x20\x20\x20\x20\x20\x20\x20if\x20(n.tagName\x20===\x20'DIV'\x20||\x20n.tagName\x20===\x20'BR'\x20||\x20n.tagName\x20===\x20'PRE')\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20s\x20+=\x20'\\n';\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20s\x20+=\x20text(n);\x0a\x20\x20\x20\x20\x20\x20\x20\x20continue;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20if\x20(n.nodeType\x20===\x203)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20s\x20+=\x20n.nodeValue;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20return\x20s.replace('\\xA0',\x20'\x20');\x20//\x20replace\x20non-breaking\x20spaces\x0a\x20\x20}\x0a\x0a\x20\x20//\x20When\x20presenter\x20notes\x20are\x20enabled,\x20the\x20index\x20passed\x0a\x20\x20//\x20here\x20will\x20identify\x20the\x20playground\x20to\x20be\x20synced\x0a\x20\x20function\x20init(code,\x20index)\x20{\x0a\x20\x20\x20\x20var\x20output\x20=\x20document.createElement('div');\x0a\x20\x20\x20\x20var\x20outpre\x20=\x20document.createElement('pre');\x0a\x20\x20\x20\x20var\x20running;\x0a\x0a\x20\x20\x20\x20if\x20($\x20&&\x20$(output).resizable)\x20{\x0a\x20\x20\x20\x20\x20\x20$(output).resizable({\x0a\x20\x20\x20\x20\x20\x20\x20\x20handles:\x20'n,w,nw',\x0a\x20\x20\x20\x20\x20\x20\x20\x20minHeight:\x2027,\x0a\x20\x20\x20\x20\x20\x20\x20\x20minWidth:\x20135,\x0a\x20\x20\x20\x20\x20\x20\x20\x20maxHeight:\x20608,\x0a\x20\x20\x20\x20\x20\x20\x20\x20maxWidth:\x20990,\x0a\x20\x20\x20\x20\x20\x20});\x0a\x20\x20\x20\x20}\x0a\x0a\x20\x20\x20\x20function\x20onKill()\x20{\x0a\x20\x20\x20\x20\x20\x20if\x20(running)\x20running.Kill();\x0a\x20\x20\x20\x20\x20\x20if\x20(window.notesEnabled)\x20updatePlayStorage('onKill',\x20index);\x0a\x20\x20\x20\x20}\x0a\x0a\x20\x20\x20\x20function\x20onRun(e)\x20{\x0a\x20\x20\x20\x20\x20\x20var\x20sk\x20=\x20e.shiftKey\x20||\x20localStorage.getItem('play-shiftKey')\x20===\x20'true';\x0a\x20\x20\x20\x20\x20\x20if\x20(running)\x20running.Kill();\x0a\x20\x20\x20\x20\x20\x20output.style.display\x20=\x20'block';\x0a\x20\x20\x20\x20\x20\x20outpre.textContent\x20=\x20'';\x0a\x20\x20\x20\x20\x20\x20run1.style.display\x20=\x20'none';\x0a\x20\x20\x20\x20\x20\x20var\x20options\x20=\x20{\x20Race:\x20sk\x20};\x0a\x20\x20\x20\x20\x20\x20running\x20=\x20transport.Run(text(code),\x20PlaygroundOutput(outpre),\x20options);\x0a\x20\x20\x20\x20\x20\x20if\x20(window.notesEnabled)\x20updatePlayStorage('onRun',\x20index,\x20e);\x0a\x20\x20\x20\x20}\x0a\x0a\x20\x20\x20\x20function\x20onClose()\x20{\x0a\x20\x20\x20\x20\x20\x20if\x20(running)\x20running.Kill();\x0a\x20\x20\x20\x20\x20\x20output.style.display\x20=\x20'none';\x0a\x20\x20\x20\x20\x20\x20run1.style.display\x20=\x20'inline-block';\x0a\x20\x20\x20\x20\x20\x20if\x20(window.notesEnabled)\x20updatePlayStorage('onClose',\x20index);\x0a\x20\x20\x20\x20}\x0a\x0a\x20\x20\x20\x20if\x20(window.notesEnabled)\x20{\x0a\x20\x20\x20\x20\x20\x20playgroundHandlers.onRun.push(onRun);\x0a\x20\x20\x20\x20\x20\x20playgroundHandlers.onClose.push(onClose);\x0a\x20\x20\x20\x20\x20\x20playgroundHandlers.onKill.push(onKill);\x0a\x20\x20\x20\x20}\x0a\x0a\x20\x20\x20\x20var\x20run1\x20=\x20document.createElement('button');\x0a\x20\x20\x20\x20run1.textContent\x20=\x20'Run';\x0a\x20\x20\x20\x20run1.className\x20=\x20'run';\x0a\x20\x20\x20\x20run1.addEventListener('click',\x20onRun,\x20false);\x0a\x20\x20\x20\x20var\x20run2\x20=\x20document.createElement('button');\x0a\x20\x20\x20\x20run2.className\x20=\x20'run';\x0a\x20\x20\x20\x20run2.textContent\x20=\x20'Run';\x0a\x20\x20\x20\x20run2.addEventListener('click',\x20onRun,\x20false);\x0a\x20\x20\x20\x20var\x20kill\x20=\x20document.createElement('button');\x0a\x20\x20\x20\x20kill.className\x20=\x20'kill';\x0a\x20\x20\x20\x20kill.textContent\x20=\x20'Kill';\x0a\x20\x20\x20\x20kill.addEventListener('click',\x20onKill,\x20false);\x0a\x20\x20\x20\x20var\x20close\x20=\x20document.createElement('button');\x0a\x20\x20\x20\x20close.className\x20=\x20'close';\x0a\x20\x20\x20\x20close.textContent\x20=\x20'Close';\x0a\x20\x20\x20\x20close.addEventListener('click',\x20onClose,\x20false);\x0a\x0a\x20\x20\x20\x20var\x20button\x20=\x20document.createElement('div');\x0a\x20\x20\x20\x20button.classList.add('buttons');\x0a\x20\x20\x20\x20button.appendChild(run1);\x0a\x20\x20\x20\x20//\x20Hack\x20to\x20simulate\x20insertAfter\x0a\x20\x20\x20\x20code.parentNode.insertBefore(button,\x20code.nextSibling);\x0a\x0a\x20\x20\x20\x20var\x20buttons\x20=\x20document.createElement('div');\x0a\x20\x20\x20\x20buttons.classList.add('buttons');\x0a\x20\x20\x20\x20buttons.appendChild(run2);\x0a\x20\x20\x20\x20buttons.appendChild(kill);\x0a\x20\x20\x20\x20buttons.appendChild(close);\x0a\x0a\x20\x20\x20\x20output.classList.add('output');\x0a\x20\x20\x20\x20output.appendChild(buttons);\x0a\x20\x20\x20\x20output.appendChild(outpre);\x0a\x20\x20\x20\x20output.style.display\x20=\x20'none';\x0a\x20\x20\x20\x20code.parentNode.insertBefore(output,\x20button.nextSibling);\x0a\x20\x20}\x0a\x0a\x20\x20var\x20play\x20=\x20document.querySelectorAll('div.playground');\x0a\x20\x20for\x20(var\x20i\x20=\x200;\x20i\x20<\x20play.length;\x20i++)\x20{\x0a\x20\x20\x20\x20init(play[i],\x20i);\x0a\x20\x20}\x0a}\x0a",
 
@@ -95,5 +97,5 @@
 
 	"searchtxt.html": "<!--\x0a\x09Copyright\x202009\x20The\x20Go\x20Authors.\x20All\x20rights\x20reserved.\x0a\x09Use\x20of\x20this\x20source\x20code\x20is\x20governed\x20by\x20a\x20BSD-style\x0a\x09license\x20that\x20can\x20be\x20found\x20in\x20the\x20LICENSE\x20file.\x0a-->\x0a{{$query_url\x20:=\x20urlquery\x20.Query}}\x0a{{with\x20.Textual}}\x0a\x09{{if\x20$.Complete}}\x0a\x09\x09<h2\x20id=\"Textual\">{{html\x20$.Found}}\x20textual\x20occurrences</h2>\x0a\x09{{else}}\x0a\x09\x09<h2\x20id=\"Textual\">More\x20than\x20{{html\x20$.Found}}\x20textual\x20occurrences</h2>\x0a\x09\x09<p>\x0a\x09\x09<span\x20class=\"alert\"\x20style=\"font-size:120%\">Not\x20all\x20files\x20or\x20lines\x20containing\x20\"{{html\x20$.Query}}\"\x20are\x20shown.</span>\x0a\x09\x09</p>\x0a\x09{{end}}\x0a\x09<p>\x0a\x09<table\x20class=\"layout\">\x0a\x09{{range\x20.}}\x0a\x09\x09{{$file\x20:=\x20.Filename}}\x0a\x09\x09<tr>\x0a\x09\x09<td\x20align=\"left\"\x20valign=\"top\">\x0a\x09\x09<a\x20href=\"{{queryLink\x20$file\x20$query_url\x200}}\">{{$file}}</a>:\x0a\x09\x09</td>\x0a\x09\x09<td\x20align=\"left\"\x20width=\"4\"></td>\x0a\x09\x09<th\x20align=\"left\"\x20valign=\"top\">{{len\x20.Lines}}</th>\x0a\x09\x09<td\x20align=\"left\"\x20width=\"4\"></td>\x0a\x09\x09<td\x20align=\"left\">\x0a\x09\x09{{range\x20.Lines}}\x0a\x09\x09\x09<a\x20href=\"{{queryLink\x20$file\x20$query_url\x20.}}\">{{html\x20.}}</a>\x0a\x09\x09{{end}}\x0a\x09\x09{{if\x20not\x20$.Complete}}\x0a\x09\x09\x09...\x0a\x09\x09{{end}}\x0a\x09\x09</td>\x0a\x09\x09</tr>\x0a\x09{{end}}\x0a\x09{{if\x20not\x20$.Complete}}\x0a\x09\x09<tr><td\x20align=\"left\">...</td></tr>\x0a\x09{{end}}\x0a\x09</table>\x0a\x09</p>\x0a{{end}}\x0a",
 
-	"style.css": "body\x20{\x0a\x20\x20margin:\x200;\x0a\x20\x20font-family:\x20Arial,\x20sans-serif;\x0a\x20\x20background-color:\x20#fff;\x0a\x20\x20line-height:\x201.3;\x0a\x20\x20text-align:\x20center;\x0a\x20\x20color:\x20#222;\x0a}\x0atextarea\x20{\x0a\x20\x20/*\x20Inherit\x20text\x20color\x20from\x20body\x20avoiding\x20illegible\x20text\x20in\x20the\x20case\x20where\x20the\x0a\x20\x09*\x20user\x20has\x20inverted\x20the\x20browsers\x20custom\x20text\x20and\x20background\x20colors.\x20*/\x0a\x20\x20color:\x20inherit;\x0a}\x0apre,\x0acode\x20{\x0a\x20\x20font-family:\x20Menlo,\x20monospace;\x0a\x20\x20font-size:\x200.875rem;\x0a}\x0apre\x20{\x0a\x20\x20line-height:\x201.4;\x0a\x20\x20overflow-x:\x20auto;\x0a}\x0apre\x20.comment\x20{\x0a\x20\x20color:\x20#006600;\x0a}\x0apre\x20.highlight,\x0apre\x20.highlight-comment,\x0apre\x20.selection-highlight,\x0apre\x20.selection-highlight-comment\x20{\x0a\x20\x20background:\x20#ffff00;\x0a}\x0apre\x20.selection,\x0apre\x20.selection-comment\x20{\x0a\x20\x20background:\x20#ff9632;\x0a}\x0apre\x20.ln\x20{\x0a\x20\x20color:\x20#999;\x0a\x20\x20background:\x20#efefef;\x0a}\x0a.ln\x20{\x0a\x20\x20-webkit-user-select:\x20none;\x0a\x20\x20-moz-user-select:\x20none;\x0a\x20\x20-ms-user-select:\x20none;\x0a\x20\x20user-select:\x20none;\x0a\x0a\x20\x20/*\x20Ensure\x208\x20characters\x20in\x20the\x20document\x20-\x20which\x20due\x20to\x20floating\x0a\x20\x20\x20*\x20point\x20rendering\x20issues,\x20might\x20have\x20a\x20width\x20of\x20less\x20than\x201\x20each\x20-\x20are\x208\x0a\x20\x20\x20*\x20characters\x20wide,\x20so\x20a\x20tab\x20in\x20the\x209th\x20position\x20indents\x20properly.\x20See\x0a\x20\x20\x20*\x20https://github.com/webcompat/web-bugs/issues/17530#issuecomment-402675091\x0a\x20\x20\x20*\x20for\x20more\x20information.\x20*/\x0a\x20\x20display:\x20inline-block;\x0a\x20\x20width:\x208ch;\x0a}\x0a\x0a.search-nav\x20{\x0a\x20\x20margin-left:\x201.25rem;\x0a\x20\x20font-size:\x200.875rem;\x0a\x20\x20column-gap:\x201.25rem;\x0a\x20\x20column-fill:\x20auto;\x0a\x20\x20column-width:\x2014rem;\x0a}\x0a\x0a.search-nav\x20.indent\x20{\x0a\x20\x20margin-left:\x201.25rem;\x0a}\x0a\x0aa,\x0a.exampleHeading\x20.text,\x0a.expandAll\x20{\x0a\x20\x20color:\x20#375eab;\x0a\x20\x20text-decoration:\x20none;\x0a}\x0aa:hover,\x0a.exampleHeading\x20.text:hover,\x0a.expandAll:hover\x20{\x0a\x20\x20text-decoration:\x20underline;\x0a}\x0a.article\x20a\x20{\x0a\x20\x20text-decoration:\x20underline;\x0a}\x0a.article\x20.title\x20a\x20{\x0a\x20\x20text-decoration:\x20none;\x0a}\x0a\x0a.permalink\x20{\x0a\x20\x20display:\x20none;\x0a}\x0a:hover\x20>\x20.permalink\x20{\x0a\x20\x20display:\x20inline;\x0a}\x0a\x0ap,\x0ali\x20{\x0a\x20\x20max-width:\x2050rem;\x0a\x20\x20word-wrap:\x20break-word;\x0a}\x0ap,\x0apre,\x0aul,\x0aol\x20{\x0a\x20\x20margin:\x201.25rem;\x0a}\x0apre\x20{\x0a\x20\x20background:\x20#efefef;\x0a\x20\x20padding:\x200.625rem;\x0a\x20\x20border-radius:\x200.3125rem;\x0a}\x0a\x0ah1,\x0ah2,\x0ah3,\x0ah4,\x0a.rootHeading\x20{\x0a\x20\x20margin:\x201.25rem\x200\x201.25rem;\x0a\x20\x20padding:\x200;\x0a\x20\x20color:\x20#375eab;\x0a\x20\x20font-weight:\x20bold;\x0a}\x0ah1\x20{\x0a\x20\x20font-size:\x201.75rem;\x0a\x20\x20line-height:\x201;\x0a}\x0ah1\x20.text-muted\x20{\x0a\x20\x20color:\x20#777;\x0a}\x0ah2\x20{\x0a\x20\x20font-size:\x201.25rem;\x0a\x20\x20background:\x20#e0ebf5;\x0a\x20\x20padding:\x200.5rem;\x0a\x20\x20line-height:\x201.25;\x0a\x20\x20font-weight:\x20normal;\x0a\x20\x20overflow:\x20auto;\x0a\x20\x20overflow-wrap:\x20break-word;\x0a}\x0ah2\x20a\x20{\x0a\x20\x20font-weight:\x20bold;\x0a}\x0ah3\x20{\x0a\x20\x20font-size:\x201.25rem;\x0a\x20\x20line-height:\x201.25;\x0a\x20\x20overflow:\x20auto;\x0a\x20\x20overflow-wrap:\x20break-word;\x0a}\x0ah3,\x0ah4\x20{\x0a\x20\x20margin:\x201.25rem\x200.3125rem;\x0a}\x0ah4\x20{\x0a\x20\x20font-size:\x201rem;\x0a}\x0a.rootHeading\x20{\x0a\x20\x20font-size:\x201.25rem;\x0a\x20\x20margin:\x200;\x0a}\x0a\x0ah2\x20>\x20span,\x0ah3\x20>\x20span\x20{\x0a\x20\x20float:\x20right;\x0a\x20\x20margin:\x200\x2025px\x200\x200;\x0a\x20\x20font-weight:\x20normal;\x0a\x20\x20color:\x20#5279c7;\x0a}\x0a\x0adl\x20{\x0a\x20\x20margin:\x201.25rem;\x0a}\x0add\x20{\x0a\x20\x20margin:\x200\x200\x200\x201.25rem;\x0a}\x0adl,\x0add\x20{\x0a\x20\x20font-size:\x200.875rem;\x0a}\x0adiv#nav\x20table\x20td\x20{\x0a\x20\x20vertical-align:\x20top;\x0a}\x0a\x0a#pkg-index\x20h3\x20{\x0a\x20\x20font-size:\x201rem;\x0a}\x0a.pkg-dir\x20{\x0a\x20\x20padding:\x200\x200.625rem;\x0a}\x0a.pkg-dir\x20table\x20{\x0a\x20\x20border-collapse:\x20collapse;\x0a\x20\x20border-spacing:\x200;\x0a}\x0a.pkg-name\x20{\x0a\x20\x20padding-right:\x200.625rem;\x0a}\x0a.alert\x20{\x0a\x20\x20color:\x20#aa0000;\x0a}\x0a\x0a.top-heading\x20{\x0a\x20\x20float:\x20left;\x0a\x20\x20padding:\x201.313rem\x200;\x0a\x20\x20font-size:\x201.25rem;\x0a\x20\x20font-weight:\x20normal;\x0a}\x0a.top-heading\x20a\x20{\x0a\x20\x20color:\x20#222;\x0a\x20\x20text-decoration:\x20none;\x0a}\x0a\x0a#pkg-examples\x20h3\x20{\x0a\x20\x20float:\x20left;\x0a}\x0a\x0a#pkg-examples\x20dl\x20{\x0a\x20\x20clear:\x20both;\x0a}\x0a\x0a.expandAll\x20{\x0a\x20\x20cursor:\x20pointer;\x0a\x20\x20float:\x20left;\x0a\x20\x20margin:\x201.25rem\x200;\x0a}\x0a\x0adiv#topbar\x20{\x0a\x20\x20background:\x20#e0ebf5;\x0a\x20\x20height:\x204rem;\x0a\x20\x20overflow:\x20hidden;\x0a}\x0a\x0adiv#page\x20{\x0a\x20\x20width:\x20100%;\x0a}\x0adiv#page\x20>\x20.container,\x0adiv#topbar\x20>\x20.container\x20{\x0a\x20\x20text-align:\x20left;\x0a\x20\x20margin-left:\x20auto;\x0a\x20\x20margin-right:\x20auto;\x0a\x20\x20padding:\x200\x201.25rem;\x0a}\x0adiv#topbar\x20>\x20.container,\x0adiv#page\x20>\x20.container\x20{\x0a\x20\x20max-width:\x2059.38rem;\x0a}\x0adiv#page.wide\x20>\x20.container,\x0adiv#topbar.wide\x20>\x20.container\x20{\x0a\x20\x20max-width:\x20none;\x0a}\x0adiv#plusone\x20{\x0a\x20\x20float:\x20right;\x0a\x20\x20clear:\x20right;\x0a\x20\x20margin-top:\x200.3125rem;\x0a}\x0a\x0adiv#footer\x20{\x0a\x20\x20text-align:\x20center;\x0a\x20\x20color:\x20#666;\x0a\x20\x20font-size:\x200.875rem;\x0a\x20\x20margin:\x202.5rem\x200;\x0a}\x0a\x0adiv#menu\x20>\x20a,\x0ainput#search,\x0adiv#learn\x20.buttons\x20a,\x0adiv.play\x20.buttons\x20a,\x0adiv#blog\x20.read\x20a,\x0a#menu-button\x20{\x0a\x20\x20padding:\x200.625rem;\x0a\x0a\x20\x20text-decoration:\x20none;\x0a\x20\x20font-size:\x201rem;\x0a\x20\x20border-radius:\x200.3125rem;\x0a}\x0adiv#playground\x20.buttons\x20a,\x0adiv#menu\x20>\x20a,\x0ainput#search,\x0a#menu-button\x20{\x0a\x20\x20border:\x200.0625rem\x20solid\x20#375eab;\x0a}\x0adiv#playground\x20.buttons\x20a,\x0adiv#menu\x20>\x20a,\x0a#menu-button\x20{\x0a\x20\x20color:\x20white;\x0a\x20\x20background:\x20#375eab;\x0a}\x0a#playgroundButton.active\x20{\x0a\x20\x20background:\x20white;\x0a\x20\x20color:\x20#375eab;\x0a}\x0aa#start,\x0adiv#learn\x20.buttons\x20a,\x0adiv.play\x20.buttons\x20a,\x0adiv#blog\x20.read\x20a\x20{\x0a\x20\x20color:\x20#222;\x0a\x20\x20border:\x200.0625rem\x20solid\x20#375eab;\x0a\x20\x20background:\x20#e0ebf5;\x0a}\x0a.download\x20{\x0a\x20\x20width:\x209.375rem;\x0a}\x0a\x0adiv#menu\x20{\x0a\x20\x20text-align:\x20right;\x0a\x20\x20padding:\x200.625rem;\x0a\x20\x20white-space:\x20nowrap;\x0a\x20\x20max-height:\x200;\x0a\x20\x20-moz-transition:\x20max-height\x200.25s\x20linear;\x0a\x20\x20transition:\x20max-height\x200.25s\x20linear;\x0a\x20\x20width:\x20100%;\x0a}\x0adiv#menu.menu-visible\x20{\x0a\x20\x20max-height:\x2031.25rem;\x0a}\x0adiv#menu\x20>\x20a,\x0a#menu-button\x20{\x0a\x20\x20margin:\x200.625rem\x200.125rem;\x0a\x20\x20padding:\x200.625rem;\x0a}\x0a::-webkit-input-placeholder\x20{\x0a\x20\x20color:\x20#7f7f7f;\x0a\x20\x20opacity:\x201;\x0a}\x0a::placeholder\x20{\x0a\x20\x20color:\x20#7f7f7f;\x0a\x20\x20opacity:\x201;\x0a}\x0a#menu\x20.search-box\x20{\x0a\x20\x20display:\x20inline-flex;\x0a\x20\x20width:\x208.75rem;\x0a}\x0ainput#search\x20{\x0a\x20\x20background:\x20white;\x0a\x20\x20color:\x20#222;\x0a\x20\x20box-sizing:\x20border-box;\x0a\x20\x20-webkit-appearance:\x20none;\x0a\x20\x20border-top-right-radius:\x200;\x0a\x20\x20border-bottom-right-radius:\x200;\x0a\x20\x20border-right:\x200;\x0a\x20\x20margin-right:\x200;\x0a\x20\x20flex-grow:\x201;\x0a\x20\x20max-width:\x20100%;\x0a\x20\x20min-width:\x205.625rem;\x0a}\x0ainput#search:-webkit-search-decoration\x20{\x0a\x20\x20-webkit-appearance:\x20none;\x0a}\x0ainput#search:-moz-ui-invalid\x20{\x0a\x20\x20box-shadow:\x20unset;\x0a}\x0ainput#search\x20+\x20button\x20{\x0a\x20\x20display:\x20inline;\x0a\x20\x20font-size:\x201em;\x0a\x20\x20background-color:\x20#375eab;\x0a\x20\x20color:\x20white;\x0a\x20\x20border:\x200.0625rem\x20solid\x20#375eab;\x0a\x20\x20border-top-left-radius:\x200;\x0a\x20\x20border-top-right-radius:\x200.3125rem;\x0a\x20\x20border-bottom-left-radius:\x200;\x0a\x20\x20border-bottom-right-radius:\x200.3125rem;\x0a\x20\x20margin-left:\x200;\x0a\x20\x20cursor:\x20pointer;\x0a}\x0ainput#search\x20+\x20button\x20span\x20{\x0a\x20\x20display:\x20flex;\x0a}\x0ainput#search\x20+\x20button\x20svg\x20{\x0a\x20\x20fill:\x20white;\x0a}\x0a\x0a#menu-button\x20{\x0a\x20\x20display:\x20none;\x0a\x20\x20position:\x20absolute;\x0a\x20\x20right:\x200.3125rem;\x0a\x20\x20top:\x200;\x0a\x20\x20margin-right:\x200.3125rem;\x0a}\x0a#menu-button-arrow\x20{\x0a\x20\x20display:\x20inline-block;\x0a}\x0a.vertical-flip\x20{\x0a\x20\x20transform:\x20rotate(-180deg);\x0a}\x0a\x0adiv.left\x20{\x0a\x20\x20float:\x20left;\x0a\x20\x20clear:\x20left;\x0a\x20\x20margin-right:\x202.5%;\x0a}\x0adiv.right\x20{\x0a\x20\x20float:\x20right;\x0a\x20\x20clear:\x20right;\x0a\x20\x20margin-left:\x202.5%;\x0a}\x0adiv.left,\x0adiv.right\x20{\x0a\x20\x20width:\x2045%;\x0a}\x0a\x0adiv#learn,\x0adiv#about\x20{\x0a\x20\x20padding-top:\x201.25rem;\x0a}\x0adiv#learn\x20h2,\x0adiv#about\x20{\x0a\x20\x20margin:\x200;\x0a}\x0adiv#about\x20{\x0a\x20\x20font-size:\x201.25rem;\x0a\x20\x20margin:\x200\x20auto\x201.875rem;\x0a}\x0adiv#gopher\x20{\x0a\x20\x20background:\x20url(/doc/gopher/frontpage.png)\x20no-repeat;\x0a\x20\x20background-position:\x20center\x20top;\x0a\x20\x20height:\x209.688rem;\x0a\x20\x20max-height:\x20200px;\x20/*\x20Setting\x20in\x20px\x20to\x20prevent\x20the\x20gopher\x20from\x20blowing\x20up\x20in\x20very\x20high\x20default\x20font-sizes\x20*/\x0a}\x0aa#start\x20{\x0a\x20\x20display:\x20block;\x0a\x20\x20padding:\x200.625rem;\x0a\x0a\x20\x20text-align:\x20center;\x0a\x20\x20text-decoration:\x20none;\x0a\x20\x20border-radius:\x200.3125rem;\x0a}\x0aa#start\x20.big\x20{\x0a\x20\x20display:\x20block;\x0a\x20\x20font-weight:\x20bold;\x0a\x20\x20font-size:\x201.25rem;\x0a}\x0aa#start\x20.desc\x20{\x0a\x20\x20display:\x20block;\x0a\x20\x20font-size:\x200.875rem;\x0a\x20\x20font-weight:\x20normal;\x0a\x20\x20margin-top:\x200.3125rem;\x0a}\x0a\x0adiv#learn\x20.popout\x20{\x0a\x20\x20float:\x20right;\x0a\x20\x20display:\x20block;\x0a\x20\x20cursor:\x20pointer;\x0a\x20\x20font-size:\x200.75rem;\x0a\x20\x20background:\x20url(/doc/share.png)\x20no-repeat;\x0a\x20\x20background-position:\x20right\x20center;\x0a\x20\x20padding:\x200.375rem\x201.688rem;\x0a}\x0adiv#learn\x20pre,\x0adiv#learn\x20textarea\x20{\x0a\x20\x20padding:\x200;\x0a\x20\x20margin:\x200;\x0a\x20\x20font-family:\x20Menlo,\x20monospace;\x0a\x20\x20font-size:\x200.875rem;\x0a}\x0adiv#learn\x20.input\x20{\x0a\x20\x20padding:\x200.625rem;\x0a\x20\x20margin-top:\x200.625rem;\x0a\x20\x20height:\x209.375rem;\x0a\x0a\x20\x20border-top-left-radius:\x200.3125rem;\x0a\x20\x20border-top-right-radius:\x200.3125rem;\x0a}\x0adiv#learn\x20.input\x20textarea\x20{\x0a\x20\x20width:\x20100%;\x0a\x20\x20height:\x20100%;\x0a\x20\x20border:\x20none;\x0a\x20\x20outline:\x20none;\x0a\x20\x20resize:\x20none;\x0a}\x0adiv#learn\x20.output\x20{\x0a\x20\x20border-top:\x20none\x20!important;\x0a\x0a\x20\x20padding:\x200.625rem;\x0a\x20\x20height:\x203.688rem;\x0a\x20\x20overflow:\x20auto;\x0a\x0a\x20\x20border-bottom-right-radius:\x200.3125rem;\x0a\x20\x20border-bottom-left-radius:\x200.3125rem;\x0a}\x0adiv#learn\x20.output\x20pre\x20{\x0a\x20\x20padding:\x200;\x0a\x20\x20border-radius:\x200;\x0a}\x0adiv#learn\x20.input,\x0adiv#learn\x20.input\x20textarea,\x0adiv#learn\x20.output,\x0adiv#learn\x20.output\x20pre\x20{\x0a\x20\x20background:\x20#ffffd8;\x0a}\x0adiv#learn\x20.input,\x0adiv#learn\x20.output\x20{\x0a\x20\x20border:\x200.0625rem\x20solid\x20#375eab;\x0a}\x0adiv#learn\x20.buttons\x20{\x0a\x20\x20float:\x20right;\x0a\x20\x20padding:\x201.25rem\x200\x200.625rem\x200;\x0a\x20\x20text-align:\x20right;\x0a}\x0adiv#learn\x20.buttons\x20a\x20{\x0a\x20\x20height:\x201rem;\x0a\x20\x20margin-left:\x200.3125rem;\x0a\x20\x20padding:\x200.625rem;\x0a}\x0adiv#learn\x20.toys\x20{\x0a\x20\x20margin-top:\x200.5rem;\x0a}\x0adiv#learn\x20.toys\x20select\x20{\x0a\x20\x20font-size:\x200.875rem;\x0a\x20\x20border:\x200.0625rem\x20solid\x20#375eab;\x0a\x20\x20margin:\x200;\x0a}\x0adiv#learn\x20.output\x20.exit\x20{\x0a\x20\x20display:\x20none;\x0a}\x0a\x0adiv#video\x20{\x0a\x20\x20max-width:\x20100%;\x0a}\x0adiv#blog,\x0adiv#video\x20{\x0a\x20\x20margin-top:\x202.5rem;\x0a}\x0adiv#blog\x20>\x20a,\x0adiv#blog\x20>\x20div,\x0adiv#blog\x20>\x20h2,\x0adiv#video\x20>\x20a,\x0adiv#video\x20>\x20div,\x0adiv#video\x20>\x20h2\x20{\x0a\x20\x20margin-bottom:\x200.625rem;\x0a}\x0adiv#blog\x20.title,\x0adiv#video\x20.title\x20{\x0a\x20\x20display:\x20block;\x0a\x20\x20font-size:\x201.25rem;\x0a}\x0adiv#blog\x20.when\x20{\x0a\x20\x20color:\x20#666;\x0a\x20\x20font-size:\x200.875rem;\x0a}\x0adiv#blog\x20.read\x20{\x0a\x20\x20text-align:\x20right;\x0a}\x0a\x0a@supports\x20(--c:\x200)\x20{\x0a\x20\x20[style*='--aspect-ratio-padding:']\x20{\x0a\x20\x20\x20\x20position:\x20relative;\x0a\x20\x20\x20\x20overflow:\x20hidden;\x0a\x20\x20\x20\x20padding-top:\x20var(--aspect-ratio-padding);\x0a\x20\x20}\x0a\x0a\x20\x20[style*='--aspect-ratio-padding:']\x20>\x20*\x20{\x0a\x20\x20\x20\x20position:\x20absolute;\x0a\x20\x20\x20\x20top:\x200;\x0a\x20\x20\x20\x20left:\x200;\x0a\x20\x20\x20\x20width:\x20100%;\x0a\x20\x20\x20\x20height:\x20100%;\x0a\x20\x20}\x0a}\x0a\x0a.toggleButton\x20{\x0a\x20\x20cursor:\x20pointer;\x0a}\x0a.toggle\x20>\x20.collapsed\x20{\x0a\x20\x20display:\x20block;\x0a}\x0a.toggle\x20>\x20.expanded\x20{\x0a\x20\x20display:\x20none;\x0a}\x0a.toggleVisible\x20>\x20.collapsed\x20{\x0a\x20\x20display:\x20none;\x0a}\x0a.toggleVisible\x20>\x20.expanded\x20{\x0a\x20\x20display:\x20block;\x0a}\x0a\x0atable.codetable\x20{\x0a\x20\x20margin-left:\x20auto;\x0a\x20\x20margin-right:\x20auto;\x0a\x20\x20border-style:\x20none;\x0a}\x0atable.codetable\x20td\x20{\x0a\x20\x20padding-right:\x200.625rem;\x0a}\x0ahr\x20{\x0a\x20\x20border-style:\x20none;\x0a\x20\x20border-top:\x200.0625rem\x20solid\x20black;\x0a}\x0a\x0aimg.gopher\x20{\x0a\x20\x20float:\x20right;\x0a\x20\x20margin-left:\x200.625rem;\x0a\x20\x20margin-bottom:\x200.625rem;\x0a\x20\x20z-index:\x20-1;\x0a}\x0ah2\x20{\x0a\x20\x20clear:\x20right;\x0a}\x0a\x0a/*\x20example\x20and\x20drop-down\x20playground\x20*/\x0adiv.play\x20{\x0a\x20\x20padding:\x200\x201.25rem\x202.5rem\x201.25rem;\x0a}\x0adiv.play\x20pre,\x0adiv.play\x20textarea,\x0adiv.play\x20.lines\x20{\x0a\x20\x20padding:\x200;\x0a\x20\x20margin:\x200;\x0a\x20\x20font-family:\x20Menlo,\x20monospace;\x0a\x20\x20font-size:\x200.875rem;\x0a}\x0adiv.play\x20.input\x20{\x0a\x20\x20padding:\x200.625rem;\x0a\x20\x20margin-top:\x200.625rem;\x0a\x0a\x20\x20border-top-left-radius:\x200.3125rem;\x0a\x20\x20border-top-right-radius:\x200.3125rem;\x0a\x0a\x20\x20overflow:\x20hidden;\x0a}\x0adiv.play\x20.input\x20textarea\x20{\x0a\x20\x20width:\x20100%;\x0a\x20\x20height:\x20100%;\x0a\x20\x20border:\x20none;\x0a\x20\x20outline:\x20none;\x0a\x20\x20resize:\x20none;\x0a\x0a\x20\x20overflow:\x20hidden;\x0a}\x0adiv#playground\x20.input\x20textarea\x20{\x0a\x20\x20overflow:\x20auto;\x0a\x20\x20resize:\x20auto;\x0a}\x0adiv.play\x20.output\x20{\x0a\x20\x20border-top:\x20none\x20!important;\x0a\x0a\x20\x20padding:\x200.625rem;\x0a\x20\x20max-height:\x2012.5rem;\x0a\x20\x20overflow:\x20auto;\x0a\x0a\x20\x20border-bottom-right-radius:\x200.3125rem;\x0a\x20\x20border-bottom-left-radius:\x200.3125rem;\x0a}\x0adiv.play\x20.output\x20pre\x20{\x0a\x20\x20padding:\x200;\x0a\x20\x20border-radius:\x200;\x0a}\x0adiv.play\x20.input,\x0adiv.play\x20.input\x20textarea,\x0adiv.play\x20.output,\x0adiv.play\x20.output\x20pre\x20{\x0a\x20\x20background:\x20#ffffd8;\x0a}\x0adiv.play\x20.input,\x0adiv.play\x20.output\x20{\x0a\x20\x20border:\x200.0625rem\x20solid\x20#375eab;\x0a}\x0adiv.play\x20.buttons\x20{\x0a\x20\x20float:\x20right;\x0a\x20\x20padding:\x201.25rem\x200\x200.625rem\x200;\x0a\x20\x20text-align:\x20right;\x0a}\x0adiv.play\x20.buttons\x20a\x20{\x0a\x20\x20height:\x201rem;\x0a\x20\x20margin-left:\x200.3125rem;\x0a\x20\x20padding:\x200.625rem;\x0a\x20\x20cursor:\x20pointer;\x0a}\x0a.output\x20.stderr\x20{\x0a\x20\x20color:\x20#933;\x0a}\x0a.output\x20.system\x20{\x0a\x20\x20color:\x20#999;\x0a}\x0a\x0a/*\x20drop-down\x20playground\x20*/\x0adiv#playground\x20{\x0a\x20\x20/*\x20start\x20hidden;\x20revealed\x20by\x20javascript\x20*/\x0a\x20\x20display:\x20none;\x0a}\x0adiv#playground\x20{\x0a\x20\x20position:\x20absolute;\x0a\x20\x20top:\x203.938rem;\x0a\x20\x20right:\x201.25rem;\x0a\x20\x20padding:\x200\x200.625rem\x200.625rem\x200.625rem;\x0a\x20\x20z-index:\x201;\x0a\x20\x20text-align:\x20left;\x0a\x20\x20background:\x20#e0ebf5;\x0a\x0a\x20\x20border:\x200.0625rem\x20solid\x20#b0bbc5;\x0a\x20\x20border-top:\x20none;\x0a\x0a\x20\x20border-bottom-left-radius:\x200.3125rem;\x0a\x20\x20border-bottom-right-radius:\x200.3125rem;\x0a}\x0adiv#playground\x20.code\x20{\x0a\x20\x20width:\x2032.5rem;\x0a\x20\x20height:\x2012.5rem;\x0a}\x0adiv#playground\x20.output\x20{\x0a\x20\x20height:\x206.25rem;\x0a}\x0a\x0a/*\x20Inline\x20runnable\x20snippets\x20(play.js/initPlayground)\x20*/\x0a#content\x20.code\x20pre,\x0a#content\x20.playground\x20pre,\x0a#content\x20.output\x20pre\x20{\x0a\x20\x20margin:\x200;\x0a\x20\x20padding:\x200;\x0a\x20\x20background:\x20none;\x0a\x20\x20border:\x20none;\x0a\x20\x20outline:\x200\x20solid\x20transparent;\x0a\x20\x20overflow:\x20auto;\x0a}\x0a#content\x20.playground\x20.number,\x0a#content\x20.code\x20.number\x20{\x0a\x20\x20color:\x20#999;\x0a}\x0a#content\x20.code,\x0a#content\x20.playground,\x0a#content\x20.output\x20{\x0a\x20\x20width:\x20auto;\x0a\x20\x20margin:\x201.25rem;\x0a\x20\x20padding:\x200.625rem;\x0a\x20\x20border-radius:\x200.3125rem;\x0a}\x0a#content\x20.code,\x0a#content\x20.playground\x20{\x0a\x20\x20background:\x20#e9e9e9;\x0a}\x0a#content\x20.output\x20{\x0a\x20\x20background:\x20#202020;\x0a}\x0a#content\x20.output\x20.stdout,\x0a#content\x20.output\x20pre\x20{\x0a\x20\x20color:\x20#e6e6e6;\x0a}\x0a#content\x20.output\x20.stderr,\x0a#content\x20.output\x20.error\x20{\x0a\x20\x20color:\x20rgb(244,\x2074,\x2063);\x0a}\x0a#content\x20.output\x20.system,\x0a#content\x20.output\x20.exit\x20{\x0a\x20\x20color:\x20rgb(255,\x20209,\x2077);\x0a}\x0a#content\x20.buttons\x20{\x0a\x20\x20position:\x20relative;\x0a\x20\x20float:\x20right;\x0a\x20\x20top:\x20-3.125rem;\x0a\x20\x20right:\x201.875rem;\x0a}\x0a#content\x20.output\x20.buttons\x20{\x0a\x20\x20top:\x20-3.75rem;\x0a\x20\x20right:\x200;\x0a\x20\x20height:\x200;\x0a}\x0a#content\x20.buttons\x20.kill\x20{\x0a\x20\x20display:\x20none;\x0a\x20\x20visibility:\x20hidden;\x0a}\x0aa.error\x20{\x0a\x20\x20font-weight:\x20bold;\x0a\x20\x20color:\x20white;\x0a\x20\x20background-color:\x20darkred;\x0a\x20\x20border-bottom-left-radius:\x200.25rem;\x0a\x20\x20border-bottom-right-radius:\x200.25rem;\x0a\x20\x20border-top-left-radius:\x200.25rem;\x0a\x20\x20border-top-right-radius:\x200.25rem;\x0a\x20\x20padding:\x200.125rem\x200.25rem\x200.125rem\x200.25rem;\x20/*\x20TRBL\x20*/\x0a}\x0a\x0a#heading-narrow\x20{\x0a\x20\x20display:\x20none;\x0a}\x0a\x0a.downloading\x20{\x0a\x20\x20background:\x20#f9f9be;\x0a\x20\x20padding:\x200.625rem;\x0a\x20\x20text-align:\x20center;\x0a\x20\x20border-radius:\x200.3125rem;\x0a}\x0a\x0a@media\x20(max-width:\x2058.125em)\x20{\x0a\x20\x20#heading-wide\x20{\x0a\x20\x20\x20\x20display:\x20none;\x0a\x20\x20}\x0a\x20\x20#heading-narrow\x20{\x0a\x20\x20\x20\x20display:\x20block;\x0a\x20\x20}\x0a}\x0a\x0a@media\x20(max-width:\x2047.5em)\x20{\x0a\x20\x20.container\x20.left,\x0a\x20\x20.container\x20.right\x20{\x0a\x20\x20\x20\x20width:\x20auto;\x0a\x20\x20\x20\x20float:\x20none;\x0a\x20\x20}\x0a\x0a\x20\x20div#about\x20{\x0a\x20\x20\x20\x20max-width:\x2031.25rem;\x0a\x20\x20\x20\x20text-align:\x20center;\x0a\x20\x20}\x0a}\x0a\x0a@media\x20(min-width:\x2043.75em)\x20and\x20(max-width:\x2062.5em)\x20{\x0a\x20\x20div#menu\x20>\x20a\x20{\x0a\x20\x20\x20\x20margin:\x200.3125rem\x200;\x0a\x20\x20\x20\x20font-size:\x200.875rem;\x0a\x20\x20}\x0a\x0a\x20\x20input#search\x20{\x0a\x20\x20\x20\x20font-size:\x200.875rem;\x0a\x20\x20}\x0a}\x0a\x0a@media\x20(max-width:\x2043.75em)\x20{\x0a\x20\x20body\x20{\x0a\x20\x20\x20\x20font-size:\x200.9375rem;\x0a\x20\x20}\x0a\x0a\x20\x20div#playground\x20{\x0a\x20\x20\x20\x20left:\x200;\x0a\x20\x20\x20\x20right:\x200;\x0a\x20\x20}\x0a\x0a\x20\x20pre,\x0a\x20\x20code\x20{\x0a\x20\x20\x20\x20font-size:\x200.866rem;\x0a\x20\x20}\x0a\x0a\x20\x20div#page\x20>\x20.container\x20{\x0a\x20\x20\x20\x20padding:\x200\x200.625rem;\x0a\x20\x20}\x0a\x0a\x20\x20div#topbar\x20{\x0a\x20\x20\x20\x20height:\x20auto;\x0a\x20\x20\x20\x20padding:\x200.625rem;\x0a\x20\x20}\x0a\x0a\x20\x20div#topbar\x20>\x20.container\x20{\x0a\x20\x20\x20\x20padding:\x200;\x0a\x20\x20}\x0a\x0a\x20\x20#heading-wide\x20{\x0a\x20\x20\x20\x20display:\x20block;\x0a\x20\x20}\x0a\x20\x20#heading-narrow\x20{\x0a\x20\x20\x20\x20display:\x20none;\x0a\x20\x20}\x0a\x0a\x20\x20.top-heading\x20{\x0a\x20\x20\x20\x20float:\x20none;\x0a\x20\x20\x20\x20display:\x20inline-block;\x0a\x20\x20\x20\x20padding:\x200.75rem;\x0a\x20\x20}\x0a\x0a\x20\x20div#menu\x20{\x0a\x20\x20\x20\x20padding:\x200;\x0a\x20\x20\x20\x20min-width:\x200;\x0a\x20\x20\x20\x20text-align:\x20left;\x0a\x20\x20\x20\x20float:\x20left;\x0a\x20\x20}\x0a\x0a\x20\x20div#menu\x20>\x20a\x20{\x0a\x20\x20\x20\x20display:\x20block;\x0a\x20\x20\x20\x20margin-left:\x200;\x0a\x20\x20\x20\x20margin-right:\x200;\x0a\x20\x20}\x0a\x0a\x20\x20#menu\x20.search-box\x20{\x0a\x20\x20\x20\x20display:\x20flex;\x0a\x20\x20\x20\x20width:\x20100%;\x0a\x20\x20}\x0a\x0a\x20\x20#menu-button\x20{\x0a\x20\x20\x20\x20display:\x20inline-block;\x0a\x20\x20}\x0a\x0a\x20\x20p,\x0a\x20\x20pre,\x0a\x20\x20ul,\x0a\x20\x20ol\x20{\x0a\x20\x20\x20\x20margin:\x200.625rem;\x0a\x20\x20}\x0a\x0a\x20\x20.pkg-synopsis\x20{\x0a\x20\x20\x20\x20display:\x20none;\x0a\x20\x20}\x0a\x0a\x20\x20img.gopher\x20{\x0a\x20\x20\x20\x20display:\x20none;\x0a\x20\x20}\x0a}\x0a\x0a@media\x20(max-width:\x2030em)\x20{\x0a\x20\x20#heading-wide\x20{\x0a\x20\x20\x20\x20display:\x20none;\x0a\x20\x20}\x0a\x20\x20#heading-narrow\x20{\x0a\x20\x20\x20\x20display:\x20block;\x0a\x20\x20}\x0a}\x0a\x0a@media\x20print\x20{\x0a\x20\x20pre\x20{\x0a\x20\x20\x20\x20background:\x20#fff;\x0a\x20\x20\x20\x20border:\x200.0625rem\x20solid\x20#bbb;\x0a\x20\x20\x20\x20white-space:\x20pre-wrap;\x0a\x20\x20}\x0a}\x0a",
+	"style.css": "body\x20{\x0a\x20\x20margin:\x200;\x0a\x20\x20font-family:\x20Arial,\x20sans-serif;\x0a\x20\x20background-color:\x20#fff;\x0a\x20\x20line-height:\x201.3;\x0a\x20\x20text-align:\x20center;\x0a\x20\x20color:\x20#222;\x0a}\x0atextarea\x20{\x0a\x20\x20/*\x20Inherit\x20text\x20color\x20from\x20body\x20avoiding\x20illegible\x20text\x20in\x20the\x20case\x20where\x20the\x0a\x20\x09*\x20user\x20has\x20inverted\x20the\x20browsers\x20custom\x20text\x20and\x20background\x20colors.\x20*/\x0a\x20\x20color:\x20inherit;\x0a}\x0apre,\x0acode\x20{\x0a\x20\x20font-family:\x20Menlo,\x20monospace;\x0a\x20\x20font-size:\x200.875rem;\x0a}\x0apre\x20{\x0a\x20\x20line-height:\x201.4;\x0a\x20\x20overflow-x:\x20auto;\x0a}\x0apre\x20.comment\x20{\x0a\x20\x20color:\x20#006600;\x0a}\x0apre\x20.highlight,\x0apre\x20.highlight-comment,\x0apre\x20.selection-highlight,\x0apre\x20.selection-highlight-comment\x20{\x0a\x20\x20background:\x20#ffff00;\x0a}\x0apre\x20.selection,\x0apre\x20.selection-comment\x20{\x0a\x20\x20background:\x20#ff9632;\x0a}\x0apre\x20.ln\x20{\x0a\x20\x20color:\x20#999;\x0a\x20\x20background:\x20#efefef;\x0a}\x0a.ln\x20{\x0a\x20\x20-webkit-user-select:\x20none;\x0a\x20\x20-moz-user-select:\x20none;\x0a\x20\x20-ms-user-select:\x20none;\x0a\x20\x20user-select:\x20none;\x0a\x0a\x20\x20/*\x20Ensure\x208\x20characters\x20in\x20the\x20document\x20-\x20which\x20due\x20to\x20floating\x0a\x20\x20\x20*\x20point\x20rendering\x20issues,\x20might\x20have\x20a\x20width\x20of\x20less\x20than\x201\x20each\x20-\x20are\x208\x0a\x20\x20\x20*\x20characters\x20wide,\x20so\x20a\x20tab\x20in\x20the\x209th\x20position\x20indents\x20properly.\x20See\x0a\x20\x20\x20*\x20https://github.com/webcompat/web-bugs/issues/17530#issuecomment-402675091\x0a\x20\x20\x20*\x20for\x20more\x20information.\x20*/\x0a\x20\x20display:\x20inline-block;\x0a\x20\x20width:\x208ch;\x0a}\x0a\x0a.search-nav\x20{\x0a\x20\x20margin-left:\x201.25rem;\x0a\x20\x20font-size:\x200.875rem;\x0a\x20\x20column-gap:\x201.25rem;\x0a\x20\x20column-fill:\x20auto;\x0a\x20\x20column-width:\x2014rem;\x0a}\x0a\x0a.search-nav\x20.indent\x20{\x0a\x20\x20margin-left:\x201.25rem;\x0a}\x0a\x0aa,\x0a.exampleHeading\x20.text,\x0a.expandAll\x20{\x0a\x20\x20color:\x20#375eab;\x0a\x20\x20text-decoration:\x20none;\x0a}\x0aa:hover,\x0a.exampleHeading\x20.text:hover,\x0a.expandAll:hover\x20{\x0a\x20\x20text-decoration:\x20underline;\x0a}\x0a.article\x20a\x20{\x0a\x20\x20text-decoration:\x20underline;\x0a}\x0a.article\x20.title\x20a\x20{\x0a\x20\x20text-decoration:\x20none;\x0a}\x0a\x0a.permalink\x20{\x0a\x20\x20display:\x20none;\x0a}\x0a:hover\x20>\x20.permalink\x20{\x0a\x20\x20display:\x20inline;\x0a}\x0a\x0ap,\x0ali\x20{\x0a\x20\x20max-width:\x2050rem;\x0a\x20\x20word-wrap:\x20break-word;\x0a}\x0ap,\x0apre,\x0aul,\x0aol\x20{\x0a\x20\x20margin:\x201.25rem;\x0a}\x0apre\x20{\x0a\x20\x20background:\x20#efefef;\x0a\x20\x20padding:\x200.625rem;\x0a\x20\x20border-radius:\x200.3125rem;\x0a}\x0a\x0ah1,\x0ah2,\x0ah3,\x0ah4,\x0a.rootHeading\x20{\x0a\x20\x20margin:\x201.25rem\x200\x201.25rem;\x0a\x20\x20padding:\x200;\x0a\x20\x20color:\x20#375eab;\x0a\x20\x20font-weight:\x20bold;\x0a}\x0ah1\x20{\x0a\x20\x20font-size:\x201.75rem;\x0a\x20\x20line-height:\x201;\x0a}\x0ah1\x20.text-muted\x20{\x0a\x20\x20color:\x20#777;\x0a}\x0ah2\x20{\x0a\x20\x20font-size:\x201.25rem;\x0a\x20\x20background:\x20#e0ebf5;\x0a\x20\x20padding:\x200.5rem;\x0a\x20\x20line-height:\x201.25;\x0a\x20\x20font-weight:\x20normal;\x0a\x20\x20overflow:\x20auto;\x0a\x20\x20overflow-wrap:\x20break-word;\x0a}\x0ah2\x20a\x20{\x0a\x20\x20font-weight:\x20bold;\x0a}\x0ah3\x20{\x0a\x20\x20font-size:\x201.25rem;\x0a\x20\x20line-height:\x201.25;\x0a\x20\x20overflow:\x20auto;\x0a\x20\x20overflow-wrap:\x20break-word;\x0a}\x0ah3,\x0ah4\x20{\x0a\x20\x20margin:\x201.25rem\x200.3125rem;\x0a}\x0ah4\x20{\x0a\x20\x20font-size:\x201rem;\x0a}\x0a.rootHeading\x20{\x0a\x20\x20font-size:\x201.25rem;\x0a\x20\x20margin:\x200;\x0a}\x0a\x0ah2\x20>\x20span,\x0ah3\x20>\x20span\x20{\x0a\x20\x20float:\x20right;\x0a\x20\x20margin:\x200\x2025px\x200\x200;\x0a\x20\x20font-weight:\x20normal;\x0a\x20\x20color:\x20#5279c7;\x0a}\x0a\x0adl\x20{\x0a\x20\x20margin:\x201.25rem;\x0a}\x0add\x20{\x0a\x20\x20margin:\x200\x200\x200\x201.25rem;\x0a}\x0adl,\x0add\x20{\x0a\x20\x20font-size:\x200.875rem;\x0a}\x0adiv#nav\x20table\x20td\x20{\x0a\x20\x20vertical-align:\x20top;\x0a}\x0a\x0a#pkg-index\x20h3\x20{\x0a\x20\x20font-size:\x201rem;\x0a}\x0a.pkg-dir\x20{\x0a\x20\x20padding:\x200\x200.625rem;\x0a}\x0a.pkg-dir\x20table\x20{\x0a\x20\x20border-collapse:\x20collapse;\x0a\x20\x20border-spacing:\x200;\x0a}\x0a.pkg-name\x20{\x0a\x20\x20padding-right:\x200.625rem;\x0a}\x0a.alert\x20{\x0a\x20\x20color:\x20#aa0000;\x0a}\x0a\x0a.top-heading\x20{\x0a\x20\x20float:\x20left;\x0a\x20\x20padding:\x201.313rem\x200;\x0a\x20\x20font-size:\x201.25rem;\x0a\x20\x20font-weight:\x20normal;\x0a}\x0a.top-heading\x20a\x20{\x0a\x20\x20color:\x20#222;\x0a\x20\x20text-decoration:\x20none;\x0a}\x0a\x0a#pkg-examples\x20h3\x20{\x0a\x20\x20float:\x20left;\x0a}\x0a\x0a#pkg-examples\x20dl\x20{\x0a\x20\x20clear:\x20both;\x0a}\x0a\x0a.expandAll\x20{\x0a\x20\x20cursor:\x20pointer;\x0a\x20\x20float:\x20left;\x0a\x20\x20margin:\x201.25rem\x200;\x0a}\x0a\x0adiv#topbar\x20{\x0a\x20\x20background:\x20#e0ebf5;\x0a\x20\x20height:\x204rem;\x0a\x20\x20overflow:\x20hidden;\x0a}\x0a\x0adiv#page\x20{\x0a\x20\x20width:\x20100%;\x0a}\x0adiv#page\x20>\x20.container,\x0adiv#topbar\x20>\x20.container\x20{\x0a\x20\x20text-align:\x20left;\x0a\x20\x20margin-left:\x20auto;\x0a\x20\x20margin-right:\x20auto;\x0a\x20\x20padding:\x200\x201.25rem;\x0a}\x0adiv#topbar\x20>\x20.container,\x0adiv#page\x20>\x20.container\x20{\x0a\x20\x20max-width:\x2059.38rem;\x0a}\x0adiv#page.wide\x20>\x20.container,\x0adiv#topbar.wide\x20>\x20.container\x20{\x0a\x20\x20max-width:\x20none;\x0a}\x0adiv#plusone\x20{\x0a\x20\x20float:\x20right;\x0a\x20\x20clear:\x20right;\x0a\x20\x20margin-top:\x200.3125rem;\x0a}\x0a\x0adiv#footer\x20{\x0a\x20\x20text-align:\x20center;\x0a\x20\x20color:\x20#666;\x0a\x20\x20font-size:\x200.875rem;\x0a\x20\x20margin:\x202.5rem\x200;\x0a}\x0a\x0adiv#menu\x20>\x20a,\x0ainput#search,\x0adiv#learn\x20.buttons\x20a,\x0adiv.play\x20.buttons\x20a,\x0adiv#blog\x20.read\x20a,\x0a#menu-button\x20{\x0a\x20\x20padding:\x200.625rem;\x0a\x0a\x20\x20text-decoration:\x20none;\x0a\x20\x20font-size:\x201rem;\x0a\x20\x20border-radius:\x200.3125rem;\x0a}\x0adiv#playground\x20.buttons\x20a,\x0adiv#menu\x20>\x20a,\x0ainput#search,\x0a#menu-button\x20{\x0a\x20\x20border:\x200.0625rem\x20solid\x20#375eab;\x0a}\x0adiv#playground\x20.buttons\x20a,\x0adiv#menu\x20>\x20a,\x0a#menu-button\x20{\x0a\x20\x20color:\x20white;\x0a\x20\x20background:\x20#375eab;\x0a}\x0a#playgroundButton.active\x20{\x0a\x20\x20background:\x20white;\x0a\x20\x20color:\x20#375eab;\x0a}\x0aa#start,\x0adiv#learn\x20.buttons\x20a,\x0adiv.play\x20.buttons\x20a,\x0adiv#blog\x20.read\x20a\x20{\x0a\x20\x20color:\x20#222;\x0a\x20\x20border:\x200.0625rem\x20solid\x20#375eab;\x0a\x20\x20background:\x20#e0ebf5;\x0a}\x0a.download\x20{\x0a\x20\x20width:\x209.375rem;\x0a}\x0a\x0adiv#menu\x20{\x0a\x20\x20text-align:\x20right;\x0a\x20\x20padding:\x200.625rem;\x0a\x20\x20white-space:\x20nowrap;\x0a\x20\x20max-height:\x200;\x0a\x20\x20-moz-transition:\x20max-height\x200.25s\x20linear;\x0a\x20\x20transition:\x20max-height\x200.25s\x20linear;\x0a\x20\x20width:\x20100%;\x0a}\x0adiv#menu.menu-visible\x20{\x0a\x20\x20max-height:\x2031.25rem;\x0a}\x0adiv#menu\x20>\x20a,\x0a#menu-button\x20{\x0a\x20\x20margin:\x200.625rem\x200.125rem;\x0a\x20\x20padding:\x200.625rem;\x0a}\x0a::-webkit-input-placeholder\x20{\x0a\x20\x20color:\x20#7f7f7f;\x0a\x20\x20opacity:\x201;\x0a}\x0a::placeholder\x20{\x0a\x20\x20color:\x20#7f7f7f;\x0a\x20\x20opacity:\x201;\x0a}\x0a#menu\x20.search-box\x20{\x0a\x20\x20display:\x20inline-flex;\x0a\x20\x20width:\x208.75rem;\x0a}\x0ainput#search\x20{\x0a\x20\x20background:\x20white;\x0a\x20\x20color:\x20#222;\x0a\x20\x20box-sizing:\x20border-box;\x0a\x20\x20-webkit-appearance:\x20none;\x0a\x20\x20border-top-right-radius:\x200;\x0a\x20\x20border-bottom-right-radius:\x200;\x0a\x20\x20border-right:\x200;\x0a\x20\x20margin-right:\x200;\x0a\x20\x20flex-grow:\x201;\x0a\x20\x20max-width:\x20100%;\x0a\x20\x20min-width:\x205.625rem;\x0a}\x0ainput#search:-webkit-search-decoration\x20{\x0a\x20\x20-webkit-appearance:\x20none;\x0a}\x0ainput#search:-moz-ui-invalid\x20{\x0a\x20\x20box-shadow:\x20unset;\x0a}\x0ainput#search\x20+\x20button\x20{\x0a\x20\x20display:\x20inline;\x0a\x20\x20font-size:\x201em;\x0a\x20\x20background-color:\x20#375eab;\x0a\x20\x20color:\x20white;\x0a\x20\x20border:\x200.0625rem\x20solid\x20#375eab;\x0a\x20\x20border-top-left-radius:\x200;\x0a\x20\x20border-top-right-radius:\x200.3125rem;\x0a\x20\x20border-bottom-left-radius:\x200;\x0a\x20\x20border-bottom-right-radius:\x200.3125rem;\x0a\x20\x20margin-left:\x200;\x0a\x20\x20cursor:\x20pointer;\x0a}\x0ainput#search\x20+\x20button\x20span\x20{\x0a\x20\x20display:\x20flex;\x0a}\x0ainput#search\x20+\x20button\x20svg\x20{\x0a\x20\x20fill:\x20white;\x0a}\x0a\x0a#menu-button\x20{\x0a\x20\x20display:\x20none;\x0a\x20\x20position:\x20absolute;\x0a\x20\x20right:\x200.3125rem;\x0a\x20\x20top:\x200;\x0a\x20\x20margin-right:\x200.3125rem;\x0a}\x0a#menu-button-arrow\x20{\x0a\x20\x20display:\x20inline-block;\x0a}\x0a.vertical-flip\x20{\x0a\x20\x20transform:\x20rotate(-180deg);\x0a}\x0a\x0adiv.left\x20{\x0a\x20\x20float:\x20left;\x0a\x20\x20clear:\x20left;\x0a\x20\x20margin-right:\x202.5%;\x0a}\x0adiv.right\x20{\x0a\x20\x20float:\x20right;\x0a\x20\x20clear:\x20right;\x0a\x20\x20margin-left:\x202.5%;\x0a}\x0adiv.left,\x0adiv.right\x20{\x0a\x20\x20width:\x2045%;\x0a}\x0a\x0adiv#learn,\x0adiv#about\x20{\x0a\x20\x20padding-top:\x201.25rem;\x0a}\x0adiv#learn\x20h2,\x0adiv#about\x20{\x0a\x20\x20margin:\x200;\x0a}\x0adiv#about\x20{\x0a\x20\x20font-size:\x201.25rem;\x0a\x20\x20margin:\x200\x20auto\x201.875rem;\x0a}\x0adiv#gopher\x20{\x0a\x20\x20background:\x20url(https://golang.org/doc/gopher/frontpage.png)\x20no-repeat;\x0a\x20\x20background-position:\x20center\x20top;\x0a\x20\x20height:\x209.688rem;\x0a\x20\x20max-height:\x20200px;\x20/*\x20Setting\x20in\x20px\x20to\x20prevent\x20the\x20gopher\x20from\x20blowing\x20up\x20in\x20very\x20high\x20default\x20font-sizes\x20*/\x0a}\x0aa#start\x20{\x0a\x20\x20display:\x20block;\x0a\x20\x20padding:\x200.625rem;\x0a\x0a\x20\x20text-align:\x20center;\x0a\x20\x20text-decoration:\x20none;\x0a\x20\x20border-radius:\x200.3125rem;\x0a}\x0aa#start\x20.big\x20{\x0a\x20\x20display:\x20block;\x0a\x20\x20font-weight:\x20bold;\x0a\x20\x20font-size:\x201.25rem;\x0a}\x0aa#start\x20.desc\x20{\x0a\x20\x20display:\x20block;\x0a\x20\x20font-size:\x200.875rem;\x0a\x20\x20font-weight:\x20normal;\x0a\x20\x20margin-top:\x200.3125rem;\x0a}\x0a\x0adiv#learn\x20.popout\x20{\x0a\x20\x20float:\x20right;\x0a\x20\x20display:\x20block;\x0a\x20\x20cursor:\x20pointer;\x0a\x20\x20font-size:\x200.75rem;\x0a\x20\x20background:\x20url(/doc/share.png)\x20no-repeat;\x0a\x20\x20background-position:\x20right\x20center;\x0a\x20\x20padding:\x200.375rem\x201.688rem;\x0a}\x0adiv#learn\x20pre,\x0adiv#learn\x20textarea\x20{\x0a\x20\x20padding:\x200;\x0a\x20\x20margin:\x200;\x0a\x20\x20font-family:\x20Menlo,\x20monospace;\x0a\x20\x20font-size:\x200.875rem;\x0a}\x0adiv#learn\x20.input\x20{\x0a\x20\x20padding:\x200.625rem;\x0a\x20\x20margin-top:\x200.625rem;\x0a\x20\x20height:\x209.375rem;\x0a\x0a\x20\x20border-top-left-radius:\x200.3125rem;\x0a\x20\x20border-top-right-radius:\x200.3125rem;\x0a}\x0adiv#learn\x20.input\x20textarea\x20{\x0a\x20\x20width:\x20100%;\x0a\x20\x20height:\x20100%;\x0a\x20\x20border:\x20none;\x0a\x20\x20outline:\x20none;\x0a\x20\x20resize:\x20none;\x0a}\x0adiv#learn\x20.output\x20{\x0a\x20\x20border-top:\x20none\x20!important;\x0a\x0a\x20\x20padding:\x200.625rem;\x0a\x20\x20height:\x203.688rem;\x0a\x20\x20overflow:\x20auto;\x0a\x0a\x20\x20border-bottom-right-radius:\x200.3125rem;\x0a\x20\x20border-bottom-left-radius:\x200.3125rem;\x0a}\x0adiv#learn\x20.output\x20pre\x20{\x0a\x20\x20padding:\x200;\x0a\x20\x20border-radius:\x200;\x0a}\x0adiv#learn\x20.input,\x0adiv#learn\x20.input\x20textarea,\x0adiv#learn\x20.output,\x0adiv#learn\x20.output\x20pre\x20{\x0a\x20\x20background:\x20#ffffd8;\x0a}\x0adiv#learn\x20.input,\x0adiv#learn\x20.output\x20{\x0a\x20\x20border:\x200.0625rem\x20solid\x20#375eab;\x0a}\x0adiv#learn\x20.buttons\x20{\x0a\x20\x20float:\x20right;\x0a\x20\x20padding:\x201.25rem\x200\x200.625rem\x200;\x0a\x20\x20text-align:\x20right;\x0a}\x0adiv#learn\x20.buttons\x20a\x20{\x0a\x20\x20height:\x201rem;\x0a\x20\x20margin-left:\x200.3125rem;\x0a\x20\x20padding:\x200.625rem;\x0a}\x0adiv#learn\x20.toys\x20{\x0a\x20\x20margin-top:\x200.5rem;\x0a}\x0adiv#learn\x20.toys\x20select\x20{\x0a\x20\x20font-size:\x200.875rem;\x0a\x20\x20border:\x200.0625rem\x20solid\x20#375eab;\x0a\x20\x20margin:\x200;\x0a}\x0adiv#learn\x20.output\x20.exit\x20{\x0a\x20\x20display:\x20none;\x0a}\x0a\x0adiv#video\x20{\x0a\x20\x20max-width:\x20100%;\x0a}\x0adiv#blog,\x0adiv#video\x20{\x0a\x20\x20margin-top:\x202.5rem;\x0a}\x0adiv#blog\x20>\x20a,\x0adiv#blog\x20>\x20div,\x0adiv#blog\x20>\x20h2,\x0adiv#video\x20>\x20a,\x0adiv#video\x20>\x20div,\x0adiv#video\x20>\x20h2\x20{\x0a\x20\x20margin-bottom:\x200.625rem;\x0a}\x0adiv#blog\x20.title,\x0adiv#video\x20.title\x20{\x0a\x20\x20display:\x20block;\x0a\x20\x20font-size:\x201.25rem;\x0a}\x0adiv#blog\x20.when\x20{\x0a\x20\x20color:\x20#666;\x0a\x20\x20font-size:\x200.875rem;\x0a}\x0adiv#blog\x20.read\x20{\x0a\x20\x20text-align:\x20right;\x0a}\x0a\x0a@supports\x20(--c:\x200)\x20{\x0a\x20\x20[style*='--aspect-ratio-padding:']\x20{\x0a\x20\x20\x20\x20position:\x20relative;\x0a\x20\x20\x20\x20overflow:\x20hidden;\x0a\x20\x20\x20\x20padding-top:\x20var(--aspect-ratio-padding);\x0a\x20\x20}\x0a\x0a\x20\x20[style*='--aspect-ratio-padding:']\x20>\x20*\x20{\x0a\x20\x20\x20\x20position:\x20absolute;\x0a\x20\x20\x20\x20top:\x200;\x0a\x20\x20\x20\x20left:\x200;\x0a\x20\x20\x20\x20width:\x20100%;\x0a\x20\x20\x20\x20height:\x20100%;\x0a\x20\x20}\x0a}\x0a\x0a.toggleButton\x20{\x0a\x20\x20cursor:\x20pointer;\x0a}\x0a.toggle\x20>\x20.collapsed\x20{\x0a\x20\x20display:\x20block;\x0a}\x0a.toggle\x20>\x20.expanded\x20{\x0a\x20\x20display:\x20none;\x0a}\x0a.toggleVisible\x20>\x20.collapsed\x20{\x0a\x20\x20display:\x20none;\x0a}\x0a.toggleVisible\x20>\x20.expanded\x20{\x0a\x20\x20display:\x20block;\x0a}\x0a\x0atable.codetable\x20{\x0a\x20\x20margin-left:\x20auto;\x0a\x20\x20margin-right:\x20auto;\x0a\x20\x20border-style:\x20none;\x0a}\x0atable.codetable\x20td\x20{\x0a\x20\x20padding-right:\x200.625rem;\x0a}\x0ahr\x20{\x0a\x20\x20border-style:\x20none;\x0a\x20\x20border-top:\x200.0625rem\x20solid\x20black;\x0a}\x0a\x0aimg.gopher\x20{\x0a\x20\x20float:\x20right;\x0a\x20\x20margin-left:\x200.625rem;\x0a\x20\x20margin-bottom:\x200.625rem;\x0a\x20\x20z-index:\x20-1;\x0a}\x0ah2\x20{\x0a\x20\x20clear:\x20right;\x0a}\x0a\x0a/*\x20example\x20and\x20drop-down\x20playground\x20*/\x0adiv.play\x20{\x0a\x20\x20padding:\x200\x201.25rem\x202.5rem\x201.25rem;\x0a}\x0adiv.play\x20pre,\x0adiv.play\x20textarea,\x0adiv.play\x20.lines\x20{\x0a\x20\x20padding:\x200;\x0a\x20\x20margin:\x200;\x0a\x20\x20font-family:\x20Menlo,\x20monospace;\x0a\x20\x20font-size:\x200.875rem;\x0a}\x0adiv.play\x20.input\x20{\x0a\x20\x20padding:\x200.625rem;\x0a\x20\x20margin-top:\x200.625rem;\x0a\x0a\x20\x20border-top-left-radius:\x200.3125rem;\x0a\x20\x20border-top-right-radius:\x200.3125rem;\x0a\x0a\x20\x20overflow:\x20hidden;\x0a}\x0adiv.play\x20.input\x20textarea\x20{\x0a\x20\x20width:\x20100%;\x0a\x20\x20height:\x20100%;\x0a\x20\x20border:\x20none;\x0a\x20\x20outline:\x20none;\x0a\x20\x20resize:\x20none;\x0a\x0a\x20\x20overflow:\x20hidden;\x0a}\x0adiv#playground\x20.input\x20textarea\x20{\x0a\x20\x20overflow:\x20auto;\x0a\x20\x20resize:\x20auto;\x0a}\x0adiv.play\x20.output\x20{\x0a\x20\x20border-top:\x20none\x20!important;\x0a\x0a\x20\x20padding:\x200.625rem;\x0a\x20\x20max-height:\x2012.5rem;\x0a\x20\x20overflow:\x20auto;\x0a\x0a\x20\x20border-bottom-right-radius:\x200.3125rem;\x0a\x20\x20border-bottom-left-radius:\x200.3125rem;\x0a}\x0adiv.play\x20.output\x20pre\x20{\x0a\x20\x20padding:\x200;\x0a\x20\x20border-radius:\x200;\x0a}\x0adiv.play\x20.input,\x0adiv.play\x20.input\x20textarea,\x0adiv.play\x20.output,\x0adiv.play\x20.output\x20pre\x20{\x0a\x20\x20background:\x20#ffffd8;\x0a}\x0adiv.play\x20.input,\x0adiv.play\x20.output\x20{\x0a\x20\x20border:\x200.0625rem\x20solid\x20#375eab;\x0a}\x0adiv.play\x20.buttons\x20{\x0a\x20\x20float:\x20right;\x0a\x20\x20padding:\x201.25rem\x200\x200.625rem\x200;\x0a\x20\x20text-align:\x20right;\x0a}\x0adiv.play\x20.buttons\x20a\x20{\x0a\x20\x20height:\x201rem;\x0a\x20\x20margin-left:\x200.3125rem;\x0a\x20\x20padding:\x200.625rem;\x0a\x20\x20cursor:\x20pointer;\x0a}\x0a.output\x20.stderr\x20{\x0a\x20\x20color:\x20#933;\x0a}\x0a.output\x20.system\x20{\x0a\x20\x20color:\x20#999;\x0a}\x0a\x0a/*\x20drop-down\x20playground\x20*/\x0adiv#playground\x20{\x0a\x20\x20/*\x20start\x20hidden;\x20revealed\x20by\x20javascript\x20*/\x0a\x20\x20display:\x20none;\x0a}\x0adiv#playground\x20{\x0a\x20\x20position:\x20absolute;\x0a\x20\x20top:\x203.938rem;\x0a\x20\x20right:\x201.25rem;\x0a\x20\x20padding:\x200\x200.625rem\x200.625rem\x200.625rem;\x0a\x20\x20z-index:\x201;\x0a\x20\x20text-align:\x20left;\x0a\x20\x20background:\x20#e0ebf5;\x0a\x0a\x20\x20border:\x200.0625rem\x20solid\x20#b0bbc5;\x0a\x20\x20border-top:\x20none;\x0a\x0a\x20\x20border-bottom-left-radius:\x200.3125rem;\x0a\x20\x20border-bottom-right-radius:\x200.3125rem;\x0a}\x0adiv#playground\x20.code\x20{\x0a\x20\x20width:\x2032.5rem;\x0a\x20\x20height:\x2012.5rem;\x0a}\x0adiv#playground\x20.output\x20{\x0a\x20\x20height:\x206.25rem;\x0a}\x0a\x0a/*\x20Inline\x20runnable\x20snippets\x20(play.js/initPlayground)\x20*/\x0a#content\x20.code\x20pre,\x0a#content\x20.playground\x20pre,\x0a#content\x20.output\x20pre\x20{\x0a\x20\x20margin:\x200;\x0a\x20\x20padding:\x200;\x0a\x20\x20background:\x20none;\x0a\x20\x20border:\x20none;\x0a\x20\x20outline:\x200\x20solid\x20transparent;\x0a\x20\x20overflow:\x20auto;\x0a}\x0a#content\x20.playground\x20.number,\x0a#content\x20.code\x20.number\x20{\x0a\x20\x20color:\x20#999;\x0a}\x0a#content\x20.code,\x0a#content\x20.playground,\x0a#content\x20.output\x20{\x0a\x20\x20width:\x20auto;\x0a\x20\x20margin:\x201.25rem;\x0a\x20\x20padding:\x200.625rem;\x0a\x20\x20border-radius:\x200.3125rem;\x0a}\x0a#content\x20.code,\x0a#content\x20.playground\x20{\x0a\x20\x20background:\x20#e9e9e9;\x0a}\x0a#content\x20.output\x20{\x0a\x20\x20background:\x20#202020;\x0a}\x0a#content\x20.output\x20.stdout,\x0a#content\x20.output\x20pre\x20{\x0a\x20\x20color:\x20#e6e6e6;\x0a}\x0a#content\x20.output\x20.stderr,\x0a#content\x20.output\x20.error\x20{\x0a\x20\x20color:\x20rgb(244,\x2074,\x2063);\x0a}\x0a#content\x20.output\x20.system,\x0a#content\x20.output\x20.exit\x20{\x0a\x20\x20color:\x20rgb(255,\x20209,\x2077);\x0a}\x0a#content\x20.buttons\x20{\x0a\x20\x20position:\x20relative;\x0a\x20\x20float:\x20right;\x0a\x20\x20top:\x20-3.125rem;\x0a\x20\x20right:\x201.875rem;\x0a}\x0a#content\x20.output\x20.buttons\x20{\x0a\x20\x20top:\x20-3.75rem;\x0a\x20\x20right:\x200;\x0a\x20\x20height:\x200;\x0a}\x0a#content\x20.buttons\x20.kill\x20{\x0a\x20\x20display:\x20none;\x0a\x20\x20visibility:\x20hidden;\x0a}\x0aa.error\x20{\x0a\x20\x20font-weight:\x20bold;\x0a\x20\x20color:\x20white;\x0a\x20\x20background-color:\x20darkred;\x0a\x20\x20border-bottom-left-radius:\x200.25rem;\x0a\x20\x20border-bottom-right-radius:\x200.25rem;\x0a\x20\x20border-top-left-radius:\x200.25rem;\x0a\x20\x20border-top-right-radius:\x200.25rem;\x0a\x20\x20padding:\x200.125rem\x200.25rem\x200.125rem\x200.25rem;\x20/*\x20TRBL\x20*/\x0a}\x0a\x0a#heading-narrow\x20{\x0a\x20\x20display:\x20none;\x0a}\x0a\x0a.downloading\x20{\x0a\x20\x20background:\x20#f9f9be;\x0a\x20\x20padding:\x200.625rem;\x0a\x20\x20text-align:\x20center;\x0a\x20\x20border-radius:\x200.3125rem;\x0a}\x0a\x0a@media\x20(max-width:\x2058.125em)\x20{\x0a\x20\x20#heading-wide\x20{\x0a\x20\x20\x20\x20display:\x20none;\x0a\x20\x20}\x0a\x20\x20#heading-narrow\x20{\x0a\x20\x20\x20\x20display:\x20block;\x0a\x20\x20}\x0a}\x0a\x0a@media\x20(max-width:\x2047.5em)\x20{\x0a\x20\x20.container\x20.left,\x0a\x20\x20.container\x20.right\x20{\x0a\x20\x20\x20\x20width:\x20auto;\x0a\x20\x20\x20\x20float:\x20none;\x0a\x20\x20}\x0a\x0a\x20\x20div#about\x20{\x0a\x20\x20\x20\x20max-width:\x2031.25rem;\x0a\x20\x20\x20\x20text-align:\x20center;\x0a\x20\x20}\x0a}\x0a\x0a@media\x20(min-width:\x2043.75em)\x20and\x20(max-width:\x2062.5em)\x20{\x0a\x20\x20div#menu\x20>\x20a\x20{\x0a\x20\x20\x20\x20margin:\x200.3125rem\x200;\x0a\x20\x20\x20\x20font-size:\x200.875rem;\x0a\x20\x20}\x0a\x0a\x20\x20input#search\x20{\x0a\x20\x20\x20\x20font-size:\x200.875rem;\x0a\x20\x20}\x0a}\x0a\x0a@media\x20(max-width:\x2043.75em)\x20{\x0a\x20\x20body\x20{\x0a\x20\x20\x20\x20font-size:\x200.9375rem;\x0a\x20\x20}\x0a\x0a\x20\x20div#playground\x20{\x0a\x20\x20\x20\x20left:\x200;\x0a\x20\x20\x20\x20right:\x200;\x0a\x20\x20}\x0a\x0a\x20\x20pre,\x0a\x20\x20code\x20{\x0a\x20\x20\x20\x20font-size:\x200.866rem;\x0a\x20\x20}\x0a\x0a\x20\x20div#page\x20>\x20.container\x20{\x0a\x20\x20\x20\x20padding:\x200\x200.625rem;\x0a\x20\x20}\x0a\x0a\x20\x20div#topbar\x20{\x0a\x20\x20\x20\x20height:\x20auto;\x0a\x20\x20\x20\x20padding:\x200.625rem;\x0a\x20\x20}\x0a\x0a\x20\x20div#topbar\x20>\x20.container\x20{\x0a\x20\x20\x20\x20padding:\x200;\x0a\x20\x20}\x0a\x0a\x20\x20#heading-wide\x20{\x0a\x20\x20\x20\x20display:\x20block;\x0a\x20\x20}\x0a\x20\x20#heading-narrow\x20{\x0a\x20\x20\x20\x20display:\x20none;\x0a\x20\x20}\x0a\x0a\x20\x20.top-heading\x20{\x0a\x20\x20\x20\x20float:\x20none;\x0a\x20\x20\x20\x20display:\x20inline-block;\x0a\x20\x20\x20\x20padding:\x200.75rem;\x0a\x20\x20}\x0a\x0a\x20\x20div#menu\x20{\x0a\x20\x20\x20\x20padding:\x200;\x0a\x20\x20\x20\x20min-width:\x200;\x0a\x20\x20\x20\x20text-align:\x20left;\x0a\x20\x20\x20\x20float:\x20left;\x0a\x20\x20}\x0a\x0a\x20\x20div#menu\x20>\x20a\x20{\x0a\x20\x20\x20\x20display:\x20block;\x0a\x20\x20\x20\x20margin-left:\x200;\x0a\x20\x20\x20\x20margin-right:\x200;\x0a\x20\x20}\x0a\x0a\x20\x20#menu\x20.search-box\x20{\x0a\x20\x20\x20\x20display:\x20flex;\x0a\x20\x20\x20\x20width:\x20100%;\x0a\x20\x20}\x0a\x0a\x20\x20#menu-button\x20{\x0a\x20\x20\x20\x20display:\x20inline-block;\x0a\x20\x20}\x0a\x0a\x20\x20p,\x0a\x20\x20pre,\x0a\x20\x20ul,\x0a\x20\x20ol\x20{\x0a\x20\x20\x20\x20margin:\x200.625rem;\x0a\x20\x20}\x0a\x0a\x20\x20.pkg-synopsis\x20{\x0a\x20\x20\x20\x20display:\x20none;\x0a\x20\x20}\x0a\x0a\x20\x20img.gopher\x20{\x0a\x20\x20\x20\x20display:\x20none;\x0a\x20\x20}\x0a}\x0a\x0a@media\x20(max-width:\x2030em)\x20{\x0a\x20\x20#heading-wide\x20{\x0a\x20\x20\x20\x20display:\x20none;\x0a\x20\x20}\x0a\x20\x20#heading-narrow\x20{\x0a\x20\x20\x20\x20display:\x20block;\x0a\x20\x20}\x0a}\x0a\x0a@media\x20print\x20{\x0a\x20\x20pre\x20{\x0a\x20\x20\x20\x20background:\x20#fff;\x0a\x20\x20\x20\x20border:\x200.0625rem\x20solid\x20#bbb;\x0a\x20\x20\x20\x20white-space:\x20pre-wrap;\x0a\x20\x20}\x0a}\x0a",
 }
diff --git a/godoc/static/style.css b/godoc/static/style.css
index c495bad..9e04825 100644
--- a/godoc/static/style.css
+++ b/godoc/static/style.css
@@ -404,7 +404,7 @@
   margin: 0 auto 1.875rem;
 }
 div#gopher {
-  background: url(/doc/gopher/frontpage.png) no-repeat;
+  background: url(https://golang.org/doc/gopher/frontpage.png) no-repeat;
   background-position: center top;
   height: 9.688rem;
   max-height: 200px; /* Setting in px to prevent the gopher from blowing up in very high default font-sizes */
diff --git a/gopls/doc/commands.md b/gopls/doc/commands.md
index 1d7aa58..c9cc41a 100644
--- a/gopls/doc/commands.md
+++ b/gopls/doc/commands.md
@@ -286,4 +286,9 @@
 }
 ```
 
+### ****
+Identifier: `gopls.workspace_metadata`
+
+
+
 <!-- END Commands: DO NOT MANUALLY EDIT THIS SECTION -->
diff --git a/gopls/doc/emacs.md b/gopls/doc/emacs.md
index 471dbf1..486f493 100644
--- a/gopls/doc/emacs.md
+++ b/gopls/doc/emacs.md
@@ -121,9 +121,9 @@
 See [settings] for information about available gopls settings.
 
 LSP server settings are controlled by the `eglot-workspace-configuration`
-variable, which can be set either globally in `.emacs` (as below) or in a
-`.dir-locals.el` file in the project root.
+variable, which can be set either globally in `.emacs` or in a `.dir-locals.el` file in the project root.
 
+`.emacs`:
 ```elisp
 (setq-default eglot-workspace-configuration
     '((:gopls .
@@ -131,6 +131,12 @@
          (matcher . "CaseSensitive")))))
 ```
 
+`.dir-locals.el`:
+```elisp
+((nil (eglot-workspace-configuration . ((gopls . ((staticcheck . t)
+						  (matcher . "CaseSensitive")))))))
+```
+
 ### Organizing imports with Eglot
 
 `gopls` provides the import-organizing functionality of `goimports` as an LSP
diff --git a/gopls/doc/settings.md b/gopls/doc/settings.md
index f48dc3f..f0e7314 100644
--- a/gopls/doc/settings.md
+++ b/gopls/doc/settings.md
@@ -209,6 +209,15 @@
 * `"Fuzzy"`
 Default: `"Fuzzy"`.
 
+##### **experimentalPostfixCompletions** *bool*
+
+**This setting is experimental and may be deleted.**
+
+experimentalPostfixCompletions enables artifical method snippets
+such as "someSlice.sort!".
+
+Default: `false`.
+
 #### Diagnostic
 
 ##### **analyses** *map[string]bool*
diff --git a/gopls/go.mod b/gopls/go.mod
index 1cb1f87..e26a512 100644
--- a/gopls/go.mod
+++ b/gopls/go.mod
@@ -8,9 +8,11 @@
 	github.com/sergi/go-diff v1.1.0
 	golang.org/x/mod v0.4.1
 	golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c
-	golang.org/x/tools v0.1.1-0.20210319172145-bda8f5cee399
+	golang.org/x/tools v0.1.1-0.20210408020845-b261fe96097f
 	golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1
-	honnef.co/go/tools v0.1.1
-	mvdan.cc/gofumpt v0.1.0
+	honnef.co/go/tools v0.1.3
+	mvdan.cc/gofumpt v0.1.1
 	mvdan.cc/xurls/v2 v2.2.0
 )
+
+replace golang.org/x/tools => ../
diff --git a/gopls/go.sum b/gopls/go.sum
index 0a53270..87e9da3 100644
--- a/gopls/go.sum
+++ b/gopls/go.sum
@@ -33,32 +33,21 @@
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.1 h1:Kvvh58BN8Y9/lBi7hTekvtMpm07eUZ0ck5pRHpsMWrY=
 golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk=
 golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20210101214203-2dba1e4ea05c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
-golang.org/x/tools v0.1.1-0.20210319172145-bda8f5cee399 h1:O5bm8buX/OaamnfcBrkjn0SPUIU30jFmaS8lP+ikkxs=
-golang.org/x/tools v0.1.1-0.20210319172145-bda8f5cee399/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU=
-golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
@@ -71,9 +60,9 @@
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
 gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-honnef.co/go/tools v0.1.1 h1:EVDuO03OCZwpV2t/tLLxPmPiomagMoBOgfPt0FM+4IY=
-honnef.co/go/tools v0.1.1/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las=
-mvdan.cc/gofumpt v0.1.0 h1:hsVv+Y9UsZ/mFZTxJZuHVI6shSQCtzZ11h1JEFPAZLw=
-mvdan.cc/gofumpt v0.1.0/go.mod h1:yXG1r1WqZVKWbVRtBWKWX9+CxGYfA51nSomhM0woR48=
+honnef.co/go/tools v0.1.3 h1:qTakTkI6ni6LFD5sBwwsdSO+AQqbSIxOauHTTQKZ/7o=
+honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las=
+mvdan.cc/gofumpt v0.1.1 h1:bi/1aS/5W00E2ny5q65w9SnKpWEF/UIOqDYBILpo9rA=
+mvdan.cc/gofumpt v0.1.1/go.mod h1:yXG1r1WqZVKWbVRtBWKWX9+CxGYfA51nSomhM0woR48=
 mvdan.cc/xurls/v2 v2.2.0 h1:NSZPykBXJFCetGZykLAxaL6SIpvbVy/UFEniIfHAa8A=
 mvdan.cc/xurls/v2 v2.2.0/go.mod h1:EV1RMtya9D6G5DMYPGD8zTQzaHet6Jh8gFlRgGRJeO8=
diff --git a/gopls/integration/parse/parse.go b/gopls/integration/parse/parse.go
deleted file mode 100644
index 5f52128..0000000
--- a/gopls/integration/parse/parse.go
+++ /dev/null
@@ -1,230 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package parse provides functions to parse LSP logs.
-// Fully processed logs are returned by ToRLog().
-package parse
-
-import (
-	"bufio"
-	"encoding/json"
-	"errors"
-	"fmt"
-	"log"
-	"os"
-	"regexp"
-	"strings"
-)
-
-// MsgType is the type of message.
-type MsgType int
-
-const (
-	// ClRequest from client to server has method and id
-	ClRequest MsgType = iota
-	// ClResponse from server to client
-	ClResponse
-	// SvRequest from server to client, has method and id
-	SvRequest
-	// SvResponse from client to server
-	SvResponse
-	// ToServer notification has method, but no id
-	ToServer
-	// ToClient notification
-	ToClient
-	// ReportErr is an error message
-	ReportErr // errors have method and id
-)
-
-// Logmsg is the type of a parsed log entry.
-type Logmsg struct {
-	Type    MsgType
-	Method  string
-	ID      string      // for requests/responses. Client and server request ids overlap
-	Elapsed string      // for responses
-	Hdr     string      // header. do we need to keep all these strings?
-	Rest    string      // the unparsed result, with newlines or not
-	Body    interface{} // the parsed result
-}
-
-// ReadLogs from a file. Most users should use ToRlog().
-func ReadLogs(fname string) ([]*Logmsg, error) {
-	byid := make(map[string]int)
-	msgs := []*Logmsg{}
-	fd, err := os.Open(fname)
-	if err != nil {
-		return nil, err
-	}
-	defer fd.Close()
-	logrdr := bufio.NewScanner(fd)
-	logrdr.Buffer(nil, 1<<25) //  a large buffer, for safety
-	logrdr.Split(scanLogs)
-	for i := 0; logrdr.Scan(); i++ {
-		flds := strings.SplitN(logrdr.Text(), "\n", 2)
-		if len(flds) == 1 {
-			flds = append(flds, "") // for Errors
-		}
-		msg, err := parselog(flds[0], flds[1])
-		if err != nil {
-			return nil, fmt.Errorf("failed to parse %q: %v", logrdr.Text(), err)
-		}
-		switch msg.Type {
-		case ClRequest, SvRequest:
-			v, err := msg.unmarshal(Requests(msg.Method))
-			if err != nil {
-				return nil, fmt.Errorf("%v for %s, %T", err, msg.Method, Requests(msg.Method))
-			}
-			msg.Body = v
-		case ClResponse, SvResponse:
-			v, err := msg.doresponse()
-			if err != nil {
-				return nil, fmt.Errorf("%v %s", err, msg.Method)
-			}
-			msg.Body = v
-		case ToServer, ToClient:
-			v, err := msg.unmarshal(Notifs(msg.Method))
-			if err != nil && Notifs(msg.Method) != nil {
-				return nil, fmt.Errorf("%s/%T: %v", msg.Method, Notifs(msg.Method), err)
-			}
-			msg.Body = v
-		case ReportErr:
-			msg.Body = msg.Rest // save cause
-		}
-		byid[msg.ID]++
-		msgs = append(msgs, msg)
-	}
-	if err = logrdr.Err(); err != nil {
-		return msgs, err
-	}
-	return msgs, nil
-}
-
-// parse a single log message, given first line, and the rest
-func parselog(first, rest string) (*Logmsg, error) {
-	if strings.HasPrefix(rest, "Params: ") {
-		rest = rest[8:]
-	} else if strings.HasPrefix(rest, "Result: ") {
-		rest = rest[8:]
-	}
-	msg := &Logmsg{Hdr: first, Rest: rest}
-	fixid := func(s string) string {
-		// emacs does (n)., gopls does (n)'.
-		s = strings.Trim(s, "()'.{)")
-		return s
-	}
-	flds := strings.Fields(first)
-	chk := func(s string, n int) bool { return strings.Contains(first, s) && len(flds) == n }
-	// gopls and emacs differ in how they report elapsed time
-	switch {
-	case chk("Sending request", 9):
-		msg.Type = ClRequest
-		msg.Method = flds[6][1:]
-		msg.ID = fixid(flds[8][:len(flds[8])-2])
-	case chk("Received response", 11):
-		msg.Type = ClResponse
-		msg.Method = flds[6][1:]
-		msg.ID = fixid(flds[8])
-		msg.Elapsed = flds[10]
-	case chk("Received request", 9):
-		msg.Type = SvRequest
-		msg.Method = flds[6][1:]
-		msg.ID = fixid(flds[8])
-	case chk("Sending response", 11), // gopls
-		chk("Sending response", 13): // emacs
-		msg.Type = SvResponse
-		msg.Method = flds[6][1:]
-		msg.ID = fixid(flds[8][:len(flds[8])-1])
-		msg.Elapsed = flds[10]
-	case chk("Sending notification", 7):
-		msg.Type = ToServer
-		msg.Method = strings.Trim(flds[6], ".'")
-		if len(flds) == 9 {
-			log.Printf("len=%d method=%s %q", len(flds), msg.Method, first)
-		}
-	case chk("Received notification", 7):
-		msg.Type = ToClient
-		msg.Method = flds[6][1 : len(flds[6])-2]
-	case strings.HasPrefix(first, "[Error - "):
-		msg.Type = ReportErr
-		both := flds[5]
-		idx := strings.Index(both, "#") // relies on ID.Number
-		msg.Method = both[:idx]
-		msg.ID = fixid(both[idx+1:])
-		msg.Rest = strings.Join(flds[6:], " ")
-		msg.Rest = `"` + msg.Rest + `"`
-	default:
-		return nil, fmt.Errorf("surprise, first=%q with %d flds", first, len(flds))
-	}
-	return msg, nil
-}
-
-// unmarshal into a proposed type
-func (l *Logmsg) unmarshal(p interface{}) (interface{}, error) {
-	r := []byte(l.Rest)
-	if err := json.Unmarshal(r, p); err != nil {
-		// need general alternatives, but for now
-		// if p is *[]foo and rest is {}, return an empty p (or *p?)
-		// or, cheat:
-		if l.Rest == "{}" {
-			return nil, nil
-		}
-		return nil, err
-	}
-	return p, nil
-}
-
-func (l *Logmsg) doresponse() (interface{}, error) {
-	for _, x := range Responses(l.Method) {
-		v, err := l.unmarshal(x)
-		if err == nil {
-			return v, nil
-		}
-		if x == nil {
-			return new(interface{}), nil
-		}
-	}
-	// failure!
-	rr := Responses(l.Method)
-	for _, x := range rr {
-		log.Printf("tried %T", x)
-	}
-	log.Fatalf("(%d) doresponse failed for %s %q", len(rr), l.Method, l.Rest)
-	return nil, nil
-}
-
-// be a little forgiving in separating log records
-var recSep = regexp.MustCompile("\n\n\n|\r\n\r\n\r\n")
-
-// return offset of start of next record, contents of record, error
-func scanLogs(b []byte, atEOF bool) (int, []byte, error) { //bufio.SplitFunc
-	got := recSep.FindIndex(b)
-	if got == nil {
-		if atEOF && len(b) > 0 {
-			return 0, nil, errors.New("malformed log: all logs should end with a separator")
-		}
-		return 0, nil, nil
-	}
-	return got[1], b[:got[0]], nil
-}
-
-// String returns a user-useful versin of a Direction
-func (d MsgType) String() string {
-	switch d {
-	case ClRequest:
-		return "clrequest"
-	case ClResponse:
-		return "clresponse"
-	case SvRequest:
-		return "svrequest"
-	case SvResponse:
-		return "svresponse"
-	case ToServer:
-		return "toserver"
-	case ToClient:
-		return "toclient"
-	case ReportErr:
-		return "reporterr"
-	}
-	return fmt.Sprintf("dirname: %d unknown", d)
-}
diff --git a/gopls/integration/parse/protocol.go b/gopls/integration/parse/protocol.go
deleted file mode 100644
index d1e90ed..0000000
--- a/gopls/integration/parse/protocol.go
+++ /dev/null
@@ -1,320 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package parse
-
-import (
-	"log"
-
-	p "golang.org/x/tools/internal/lsp/protocol"
-)
-
-// Requests and notifications are fixed types
-// Responses may be one of several types
-
-// Requests returns a pointer to a type suitable for Unmarshal
-func Requests(m string) interface{} {
-	// these are in the documentation's order
-	switch m {
-	case "initialize":
-		return new(p.InitializeParams)
-	case "shutdown":
-		return new(struct{})
-	case "window/showMessgeRequest":
-		return new(p.ShowMessageRequestParams)
-	case "client/registerCapability":
-		return new(p.RegistrationParams)
-	case "client/unregisterCapability":
-		return new(p.UnregistrationParams)
-	case "workspace/workspaceFolders":
-		return nil
-	case "workspace/configuration":
-		return new(p.ConfigurationParams)
-	case "workspace/symbol":
-		return new(p.WorkspaceSymbolParams)
-	case "workspace/executeCommand":
-		return new(p.ExecuteCommandParams)
-	case "workspace/applyEdit":
-		return new(p.ApplyWorkspaceEditParams)
-	case "textDocument/willSaveWaitUntil":
-		return new(p.WillSaveTextDocumentParams)
-	case "textDocument/completion":
-		return new(p.CompletionParams)
-	case "completionItem/resolve":
-		return new(p.CompletionItem)
-	case "textDocument/hover":
-		return new(p.TextDocumentPositionParams)
-	case "textDocument/signatureHelp":
-		return new(p.TextDocumentPositionParams)
-	case "textDocument/declaration":
-		return new(p.TextDocumentPositionParams)
-	case "textDocument/definition":
-		return new(p.TextDocumentPositionParams)
-	case "textDocument/typeDefinition":
-		return new(p.TextDocumentPositionParams)
-	case "textDocument/implementation":
-		return new(p.TextDocumentPositionParams)
-	case "textDocument/references":
-		return new(p.ReferenceParams)
-	case "textDocument/documentHighlight":
-		return new(p.TextDocumentPositionParams)
-	case "textDocument/documentSymbol":
-		return new(p.DocumentSymbolParams)
-	case "textDocument/codeAction":
-		return new(p.CodeActionParams)
-	case "textDocument/codeLens":
-		return new(p.CodeLensParams)
-	case "codeLens/resolve":
-		return new(p.CodeLens)
-	case "textDocument/documentLink":
-		return new(p.DocumentLinkParams)
-	case "documentLink/resolve":
-		return new(p.DocumentLink)
-	case "textDocument/documentColor":
-		return new(p.DocumentColorParams)
-	case "textDocument/colorPressentation":
-		return new(p.ColorPresentationParams)
-	case "textDocument/formatting":
-		return new(p.DocumentFormattingParams)
-	case "textDocument/rangeFormatting":
-		return new(p.DocumentRangeFormattingParams)
-	case "textDocument/typeFormatting":
-		return new(p.DocumentOnTypeFormattingParams)
-	case "textDocument/rename":
-		return new(p.RenameParams)
-	case "textDocument/prepareRename":
-		return new(p.TextDocumentPositionParams)
-	case "textDocument/foldingRange":
-		return new(p.FoldingRangeParams)
-	case "textDocument/incomingCalls":
-		return new(p.CallHierarchyIncomingCallsParams)
-	case "textDocument/outgoingCalls":
-		return new(p.CallHierarchyOutgoingCallsParams)
-	}
-	log.Fatalf("request(%s) undefined", m)
-	return ""
-}
-
-// Notifs returns a pointer to a type suitable for Unmarshal
-func Notifs(m string) interface{} {
-	switch m {
-	case "$/cancelRequest":
-		return new(p.CancelParams)
-	case "$/setTraceNotification":
-		return new(struct{ Value string })
-	case "client/registerCapability": // why is this a notification? (serer->client rpc)
-		return new(p.RegistrationParams)
-	case "initialized":
-		return new(p.InitializedParams)
-	case "exit":
-		return nil
-	case "window/showMessage":
-		return new(p.ShowMessageParams)
-	case "window/logMessage":
-		return new(p.LogMessageParams)
-	case "telemetry/event":
-		return new(interface{}) // any
-	case "workspace/didChangeWorkspaceFolders":
-		return new(p.DidChangeWorkspaceFoldersParams)
-	case "workspace/didChangeConfiguration":
-		return new(p.DidChangeConfigurationParams)
-	case "workspace/didChangeWatchedFiles":
-		return new(p.DidChangeWatchedFilesParams)
-	case "textDocument/didOpen":
-		return new(p.DidOpenTextDocumentParams)
-	case "textDocument/didChange":
-		return new(p.DidChangeTextDocumentParams)
-	case "textDocument/willSave":
-		return new(p.WillSaveTextDocumentParams)
-	case "textDocument/didSave":
-		return new(p.DidSaveTextDocumentParams)
-	case "textDocument/didClose":
-		return new(p.DidCloseTextDocumentParams)
-	case "textDocument/willClose":
-		return new(p.DidCloseTextDocumentParams)
-	case "textDocument/publishDiagnostics":
-		return new(p.PublishDiagnosticsParams)
-	}
-	log.Fatalf("notif(%s) undefined", m)
-	return ""
-}
-
-// Responses returns a slice of types, one of which should be
-// suitable for Unmarshal
-func Responses(m string) []interface{} {
-	switch m {
-	case "initialize":
-		return []interface{}{new(p.InitializeResult)}
-	case "shutdown":
-		return []interface{}{nil}
-	case "window/showMessageRequest":
-		return []interface{}{new(p.MessageActionItem), nil}
-	case "client/registerCapability":
-		return []interface{}{nil}
-	case "client/unregisterCapability":
-		return []interface{}{nil}
-	case "workspace/workspaceFolder":
-		return []interface{}{new([]p.WorkspaceFolder), nil}
-	case "workspace/configuration":
-		return []interface{}{new([]interface{}), new(interface{})}
-	case "workspace/symbol":
-		return []interface{}{new([]p.SymbolInformation), nil}
-	case "workspace/executeCommand":
-		return []interface{}{new(interface{}), nil}
-	case "workspace/applyEdit":
-		return []interface{}{new(p.ApplyWorkspaceEditResponse)}
-	case "textDocument/willSaveWaitUntil":
-		return []interface{}{new([]p.TextEdit), nil}
-	case "textDocument/completion":
-		return []interface{}{new(p.CompletionList), new([]p.CompletionItem), nil}
-	case "completionItem/resolve":
-		return []interface{}{new(p.CompletionItem)}
-	case "textDocument/hover":
-		return []interface{}{new(p.Hover), nil}
-	case "textDocument/signatureHelp":
-		return []interface{}{new(p.SignatureHelp), nil}
-	case "textDocument/declaration":
-		return []interface{}{new(p.Location), new([]p.Location), new([]p.LocationLink), nil}
-	case "textDocument/definition":
-		return []interface{}{new([]p.Location), new([]p.Location), new([]p.LocationLink), nil}
-	case "textDocument/typeDefinition":
-		return []interface{}{new([]p.Location), new([]p.LocationLink), new(p.Location), nil}
-	case "textDocument/implementation":
-		return []interface{}{new(p.Location), new([]p.Location), new([]p.LocationLink), nil}
-	case "textDocument/references":
-		return []interface{}{new([]p.Location), nil}
-	case "textDocument/documentHighlight":
-		return []interface{}{new([]p.DocumentHighlight), nil}
-	case "textDocument/documentSymbol":
-		return []interface{}{new([]p.DocumentSymbol), new([]p.SymbolInformation), nil}
-	case "textDocument/codeAction":
-		return []interface{}{new([]p.CodeAction), new(p.Command), nil}
-	case "textDocument/codeLens":
-		return []interface{}{new([]p.CodeLens), nil}
-	case "codelens/resolve":
-		return []interface{}{new(p.CodeLens)}
-	case "textDocument/documentLink":
-		return []interface{}{new([]p.DocumentLink), nil}
-	case "documentLink/resolve":
-		return []interface{}{new(p.DocumentLink)}
-	case "textDocument/documentColor":
-		return []interface{}{new([]p.ColorInformation)}
-	case "textDocument/colorPresentation":
-		return []interface{}{new([]p.ColorPresentation)}
-	case "textDocument/formatting":
-		return []interface{}{new([]p.TextEdit), nil}
-	case "textDocument/rangeFormatting":
-		return []interface{}{new([]p.TextEdit), nil}
-	case "textDocument/onTypeFormatting":
-		return []interface{}{new([]p.TextEdit), nil}
-	case "textDocument/rename":
-		return []interface{}{new(p.WorkspaceEdit), nil}
-	case "textDocument/prepareRename":
-		return []interface{}{new(p.Range), nil}
-	case "textDocument/foldingRange":
-		return []interface{}{new([]p.FoldingRange), nil}
-	case "callHierarchy/incomingCalls":
-		return []interface{}{new([]p.CallHierarchyIncomingCall), nil}
-	case "callHierarchy/outgoingCalls":
-		return []interface{}{new([]p.CallHierarchyOutgoingCall), nil}
-	}
-	log.Fatalf("responses(%q) undefined", m)
-	return nil
-}
-
-// Msgtype given method names. Note that mSrv|mCl is possible
-type Msgtype int
-
-const (
-	// Mnot for notifications
-	Mnot Msgtype = 1
-	// Mreq for requests
-	Mreq Msgtype = 2
-	// Msrv for messages from the server
-	Msrv Msgtype = 4
-	// Mcl for messages from the client
-	Mcl Msgtype = 8
-)
-
-// IsNotify says if the message is a notification
-func IsNotify(msg string) bool {
-	m, ok := fromMethod[msg]
-	if !ok {
-		log.Fatalf("%q", msg)
-	}
-	return m&Mnot != 0
-}
-
-// FromServer says if the message is from the server
-func FromServer(msg string) bool {
-	m, ok := fromMethod[msg]
-	if !ok {
-		log.Fatalf("%q", msg)
-	}
-	return m&Msrv != 0
-}
-
-// FromClient says if the message is from the client
-func FromClient(msg string) bool {
-	m, ok := fromMethod[msg]
-	if !ok {
-		log.Fatalf("%q", msg)
-	}
-	return m&Mcl != 0
-}
-
-// rpc name to message type
-var fromMethod = map[string]Msgtype{
-	"$/cancelRequest":             Mnot | Msrv | Mcl,
-	"initialize":                  Mreq | Msrv,
-	"initialized":                 Mnot | Mcl,
-	"shutdown":                    Mreq | Mcl,
-	"exit":                        Mnot | Mcl,
-	"window/showMessage":          Mreq | Msrv,
-	"window/logMessage":           Mnot | Msrv,
-	"telemetry'event":             Mnot | Msrv,
-	"client/registerCapability":   Mreq | Msrv,
-	"client/unregisterCapability": Mreq | Msrv,
-	"workspace/workspaceFolders":  Mreq | Msrv,
-	"workspace/workspaceDidChangeWorkspaceFolders": Mnot | Mcl,
-	"workspace/didChangeConfiguration":             Mnot | Mcl,
-	"workspace/configuration":                      Mreq | Msrv,
-	"workspace/didChangeWatchedFiles":              Mnot | Mcl,
-	"workspace/symbol":                             Mreq | Mcl,
-	"workspace/executeCommand":                     Mreq | Mcl,
-	"workspace/applyEdit":                          Mreq | Msrv,
-	"textDocument/didOpen":                         Mnot | Mcl,
-	"textDocument/didChange":                       Mnot | Mcl,
-	"textDocument/willSave":                        Mnot | Mcl,
-	"textDocument/willSaveWaitUntil":               Mreq | Mcl,
-	"textDocument/didSave":                         Mnot | Mcl,
-	"textDocument/didClose":                        Mnot | Mcl,
-	"textDocument/publishDiagnostics":              Mnot | Msrv,
-	"textDocument/completion":                      Mreq | Mcl,
-	"completionItem/resolve":                       Mreq | Mcl,
-	"textDocument/hover":                           Mreq | Mcl,
-	"textDocument/signatureHelp":                   Mreq | Mcl,
-	"textDocument/declaration":                     Mreq | Mcl,
-	"textDocument/definition":                      Mreq | Mcl,
-	"textDocument/typeDefinition":                  Mreq | Mcl,
-	"textDocument/implementation":                  Mreq | Mcl,
-	"textDocument/references":                      Mreq | Mcl,
-	"textDocument/documentHighlight":               Mreq | Mcl,
-	"textDocument/documentSymbol":                  Mreq | Mcl,
-	"textDocument/codeAction":                      Mreq | Mcl,
-	"textDocument/codeLens":                        Mreq | Mcl,
-	"codeLens/resolve":                             Mreq | Mcl,
-	"textDocument/documentLink":                    Mreq | Mcl,
-	"documentLink/resolve":                         Mreq | Mcl,
-	"textDocument/documentColor":                   Mreq | Mcl,
-	"textDocument/colorPresentation":               Mreq | Mcl,
-	"textDocument/formatting":                      Mreq | Mcl,
-	"textDocument/rangeFormatting":                 Mreq | Mcl,
-	"textDocument/onTypeFormatting":                Mreq | Mcl,
-	"textDocument/rename":                          Mreq | Mcl,
-	"textDocument/prepareRename":                   Mreq | Mcl,
-	"textDocument/foldingRange":                    Mreq | Mcl,
-	"callHierarchy/incomingCalls":                  Mreq | Mcl,
-	"callHierarchy/outgoingCalls":                  Mreq | Mcl,
-}
diff --git a/gopls/integration/parse/rlog.go b/gopls/integration/parse/rlog.go
deleted file mode 100644
index aebb1e2..0000000
--- a/gopls/integration/parse/rlog.go
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package parse
-
-import (
-	"fmt"
-	"log"
-	"strings"
-)
-
-// Rlog contains the processed logs
-type Rlog struct {
-	Logs         []*Logmsg          // In the order in the log file
-	ServerCall   map[string]*Logmsg // ID->Request, client->server
-	ServerReply  map[string]*Logmsg // ID->Response, server->client (includes Errors)
-	ClientCall   map[string]*Logmsg
-	ClientReply  map[string]*Logmsg
-	ClientNotifs []*Logmsg
-	ServerNotifs []*Logmsg
-	Histogram    *LogHist
-}
-
-func newRlog(x []*Logmsg) *Rlog {
-	return &Rlog{Logs: x,
-		ServerCall:   make(map[string]*Logmsg),
-		ServerReply:  make(map[string]*Logmsg),
-		ClientCall:   make(map[string]*Logmsg),
-		ClientReply:  make(map[string]*Logmsg),
-		ClientNotifs: []*Logmsg{},
-		ServerNotifs: []*Logmsg{},
-		Histogram:    &LogHist{},
-	}
-}
-
-// Counts returns a one-line summary of an Rlog
-func (r *Rlog) Counts() string {
-	return fmt.Sprintf("logs:%d srvC:%d srvR:%d clC:%d clR:%d clN:%d srvN:%d",
-		len(r.Logs),
-		len(r.ServerCall), len(r.ServerReply), len(r.ClientCall), len(r.ClientReply),
-		len(r.ClientNotifs), len(r.ServerNotifs))
-}
-
-// ToRlog reads a log file and returns a *Rlog
-func ToRlog(fname string) (*Rlog, error) {
-	x, err := ReadLogs(fname)
-	if err != nil {
-		return nil, err
-	}
-	ans := newRlog(x)
-	for _, l := range x {
-		switch l.Type {
-		case ClRequest:
-			ans.ServerCall[l.ID] = l
-		case ClResponse:
-			ans.ServerReply[l.ID] = l
-			if l.Type != ReportErr {
-				n := 0
-				fmt.Sscanf(l.Elapsed, "%d", &n)
-				ans.Histogram.add(n)
-			}
-		case SvRequest:
-			ans.ClientCall[l.ID] = l
-		case SvResponse:
-			ans.ClientReply[l.ID] = l
-		case ToClient:
-			ans.ClientNotifs = append(ans.ClientNotifs, l)
-		case ToServer:
-			ans.ServerNotifs = append(ans.ServerNotifs, l)
-		case ReportErr:
-			ans.ServerReply[l.ID] = l
-			l.Method = ans.ServerCall[l.ID].Method // Method not in log message
-		default:
-			log.Fatalf("eh? %s/%s (%s)", l.Type, l.Method, l.ID)
-		}
-	}
-	return ans, nil
-}
-
-// LogHist gets ints, and puts them into buckets:
-// <=10, <=30, 100, 300, 1000, ...
-// It produces a historgram of elapsed times in milliseconds
-type LogHist struct {
-	cnts []int
-}
-
-func (l *LogHist) add(n int) {
-	if n < 0 {
-		n = 0
-	}
-	bucket := 0
-	for ; n > 0; n /= 10 {
-		if n < 10 {
-			break
-		}
-		if n < 30 {
-			bucket++
-			break
-		}
-		bucket += 2
-	}
-	if len(l.cnts) <= bucket {
-		for j := len(l.cnts); j < bucket+10; j++ {
-			l.cnts = append(l.cnts, 0)
-		}
-	}
-	l.cnts[bucket]++
-}
-
-// String returns a string describing a histogram
-func (l *LogHist) String() string {
-	top := len(l.cnts) - 1
-	for ; top > 0 && l.cnts[top] == 0; top-- {
-	}
-	labs := []string{"10", "30"}
-	out := strings.Builder{}
-	out.WriteByte('[')
-	for i := 0; i <= top; i++ {
-		label := labs[i%2]
-		labs[i%2] += "0"
-		fmt.Fprintf(&out, "%s:%d ", label, l.cnts[i])
-	}
-	out.WriteByte(']')
-	return out.String()
-}
diff --git a/gopls/integration/replay/README.md b/gopls/integration/replay/README.md
deleted file mode 100644
index 7c32277..0000000
--- a/gopls/integration/replay/README.md
+++ /dev/null
@@ -1,79 +0,0 @@
-# Replaying Logs
-
-The LSP log replayer takes a log from a gopls session, starts up an instance of gopls,
-and tries to replay the session. It produces a log from the replayed session and reports
-some comparative statistics of the two logs.
-
-```replay -log <logfile>```
-
-The `logfile` should be the log produced by gopls. It will have a name like
-`/tmp/gopls-89775` or, on a Mac, `$TMPDIR/gopls-29388`.
-
-If `replay` cannot find a copy of gopls to execute, use `-cmd <path to gopls>`.
-It looks in the same places where `go install` would put its output,
-namely `$GOBIN/gopls`, `$GOPATH/bin/gopls`, `$HOME/go/bin/gopls`.
-
-The log for the replayed session is saved in `/tmp/seen`.
-
-There is also a boolean argument `-cmp` which compares the log file
-with `/tmp/seen` without invoking gopls and rerunning the session.
-
-The output is fairly cryptic, and generated by logging. Ideas for better output would be welcome.
-Here's an example, with intermingled comments:
-
-```
-main.go:50: old 1856, hist:[10:177 30:1 100:0 300:3 1000:4 ]
-```
-This says that the original log had 1856 records in it. The histogram is
-counting how long RPCs took, in milliseconds. In this case 177 took no more
-than 10ms, and 4 took between 300ms and 1000ms.
-```
-main.go:53: calling mimic
-main.go:293: mimic 1856
-```
-This is a reminder that it's replaying in a new session, with a log file
-containing 1856 records
-```
-main.go:61: new 1846, hist:[10:181 30:1 100:1 300:1 1000:1 ]
-```
-The new session produced 1846 log records (that's 10 fewer),
-and a vaguely similar histogram.
-```
-main.go:96: old: clrequest:578 clresponse:185 svrequest:2 svresponse:2 toserver:244 toclient:460 reporterr:385
-main.go:96: new: clrequest:571 clresponse:185 svrequest:2 svresponse:2 toserver:241 toclient:460 reporterr:385
-```
-The first line is for the original log, the second for the new log. The new log has 7 fewer RPC requests
-from the client *clrequest* (578 vs 571), the same number of client responses *clresponse*, 3 fewer
-notifications *toserver* from the client, the same number from the server *toclient* to the client, and
-the same number of errors *reporterr*. (That's mysterious, but a look at the ends of the log files shows
-that the original session ended with several RPCs that don't show up, for whatever reason, in the new session.)
-
-Finally, there are counts of the various notifications seen, in the new log and the old log, and
-which direction they went. (The 3 fewer notifications in the summary above can be seen here to be from cancels
-and a didChange.)
-```
-main.go:107: counts of notifications
-main.go:110:  '$/cancelRequest'. new toserver 1
-main.go:110:  '$/cancelRequest'. old toserver 3
-main.go:110:  'initialized'. new toserver 1
-main.go:110:  'initialized'. old toserver 1
-main.go:110:  'textDocument/didChange'. new toserver 231
-main.go:110:  'textDocument/didChange'. old toserver 232
-main.go:110:  'textDocument/didOpen'. new toserver 1
-main.go:110:  'textDocument/didOpen'. old toserver 1
-main.go:110:  'textDocument/didSave'. new toserver 7
-main.go:110:  'textDocument/didSave'. old toserver 7
-main.go:110:  'textDocument/publishDiagnostics'. new toclient 182
-main.go:110:  'textDocument/publishDiagnostics'. old toclient 182
-main.go:110:  'window/logMessage'. new toclient 278
-main.go:110:  'window/logMessage'. old toclient 278
-```
-### Caveats
-Replay cannot restore the exact environment gopls saw for the original session.
-For instance, the first didOpen message in the new session will see the file
-as it was left by the original session.
-
-Gopls invokes various tools, and the environment they see could have changed too.
-
-Replay will use the gopls it finds (or is given). It has no way of using
-the same version that created the original session.
diff --git a/gopls/integration/replay/main.go b/gopls/integration/replay/main.go
deleted file mode 100644
index 35cd1d5..0000000
--- a/gopls/integration/replay/main.go
+++ /dev/null
@@ -1,292 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Replay logs. See README.md
-package main
-
-import (
-	"bufio"
-	"context"
-	"flag"
-	"fmt"
-	exec "golang.org/x/sys/execabs"
-	"log"
-	"os"
-	"sort"
-	"strconv"
-	"strings"
-
-	"golang.org/x/tools/gopls/integration/parse"
-	"golang.org/x/tools/internal/fakenet"
-	"golang.org/x/tools/internal/jsonrpc2"
-	p "golang.org/x/tools/internal/lsp/protocol"
-)
-
-var (
-	command = flag.String("cmd", "", "location of server to send to, looks for gopls")
-	cmp     = flag.Bool("cmp", false, "only compare log and /tmp/seen")
-	logrdr  *bufio.Scanner
-	msgs    []*parse.Logmsg
-	// requests and responses/errors, by id
-	clreq  = make(map[string]*parse.Logmsg)
-	clresp = make(map[string]*parse.Logmsg)
-	svreq  = make(map[string]*parse.Logmsg)
-	svresp = make(map[string]*parse.Logmsg)
-)
-
-func main() {
-	log.SetFlags(log.Lshortfile)
-	flag.Usage = func() {
-		fmt.Fprintln(flag.CommandLine.Output(), "replay [options] <logfile>")
-		flag.PrintDefaults()
-	}
-	flag.Parse()
-	if flag.NArg() != 1 {
-		flag.Usage()
-		os.Exit(2)
-	}
-	logf := flag.Arg(0)
-
-	orig, err := parse.ToRlog(logf)
-	if err != nil {
-		log.Fatalf("error parsing logfile %q: %v", logf, err)
-	}
-	ctx := context.Background()
-	msgs = orig.Logs
-	log.Printf("old %d, hist:%s", len(msgs), orig.Histogram)
-
-	if !*cmp {
-		log.Print("calling mimic")
-		mimic(ctx)
-	}
-	seen, err := parse.ToRlog("/tmp/seen")
-	if err != nil {
-		log.Fatal(err)
-	}
-	newMsgs := seen.Logs
-	log.Printf("new %d, hist:%s", len(newMsgs), seen.Histogram)
-
-	ok := make(map[string]int)
-	f := func(x []*parse.Logmsg, label string, diags map[p.DocumentURI][]p.Diagnostic) {
-		counts := make(map[parse.MsgType]int)
-		for _, l := range x {
-			if l.Method == "window/logMessage" {
-				// don't care
-				//continue
-			}
-			if l.Method == "textDocument/publishDiagnostics" {
-				v, ok := l.Body.(*p.PublishDiagnosticsParams)
-				if !ok {
-					log.Fatalf("got %T expected PublishDiagnosticsParams", l.Body)
-				}
-				diags[v.URI] = v.Diagnostics
-			}
-			counts[l.Type]++
-			// notifications only
-			if l.Type != parse.ToServer && l.Type != parse.ToClient {
-				continue
-			}
-			s := fmt.Sprintf("%s %s %s", strings.Replace(l.Hdr, "\r", "", -1), label, l.Type)
-			if i := strings.Index(s, "notification"); i != -1 {
-				s = s[i+12:]
-			}
-			if len(s) > 120 {
-				s = s[:120]
-			}
-			ok[s]++
-		}
-		msg := ""
-		for i := parse.ClRequest; i <= parse.ReportErr; i++ {
-			msg += fmt.Sprintf("%s:%d ", i, counts[i])
-		}
-		log.Printf("%s: %s", label, msg)
-	}
-	mdiags := make(map[p.DocumentURI][]p.Diagnostic)
-	f(msgs, "old", mdiags)
-	vdiags := make(map[p.DocumentURI][]p.Diagnostic)
-	f(newMsgs, "new", vdiags)
-	buf := []string{}
-	for k := range ok {
-		buf = append(buf, fmt.Sprintf("%s %d", k, ok[k]))
-	}
-	if len(buf) > 0 {
-		log.Printf("counts of notifications")
-		sort.Strings(buf)
-		for _, k := range buf {
-			log.Print(k)
-		}
-	}
-	buf = buf[0:0]
-	for k, v := range mdiags {
-		va := vdiags[k]
-		if len(v) != len(va) {
-			buf = append(buf, fmt.Sprintf("new has %d, old has %d for %s",
-				len(va), len(v), k))
-		}
-	}
-	for ka := range vdiags {
-		if _, ok := mdiags[ka]; !ok {
-			buf = append(buf, fmt.Sprintf("new diagnostics, but no old ones, for %s",
-				ka))
-		}
-	}
-	if len(buf) > 0 {
-		log.Print("diagnostics differ:")
-		for _, s := range buf {
-			log.Print(s)
-		}
-	}
-}
-
-func send(ctx context.Context, l *parse.Logmsg, stream jsonrpc2.Stream, id *jsonrpc2.ID) {
-	if id == nil {
-		// need to use the number version of ID
-		n, err := strconv.Atoi(l.ID)
-		if err != nil {
-			n = 0
-		}
-		nid := jsonrpc2.NewIntID(int64(n))
-		id = &nid
-	}
-	var msg jsonrpc2.Message
-	var err error
-	switch l.Type {
-	case parse.ClRequest:
-		msg, err = jsonrpc2.NewCall(*id, l.Method, l.Body)
-	case parse.SvResponse:
-		msg, err = jsonrpc2.NewResponse(*id, l.Body, nil)
-	case parse.ToServer:
-		msg, err = jsonrpc2.NewNotification(l.Method, l.Body)
-	default:
-		log.Fatalf("sending %s", l.Type)
-	}
-	if err != nil {
-		log.Fatal(err)
-	}
-	stream.Write(ctx, msg)
-}
-
-func respond(ctx context.Context, c *jsonrpc2.Call, stream jsonrpc2.Stream) {
-	// c is a server request
-	// pick out the id, and look for the response in msgs
-	id := c.ID()
-	idstr := fmt.Sprint(id)
-	for _, l := range msgs {
-		if l.ID == idstr && l.Type == parse.SvResponse {
-			// check that the methods match?
-			// need to send back the same ID we got.
-			send(ctx, l, stream, &id)
-			return
-		}
-	}
-	log.Fatalf("no response found %q %+v %+v", c.Method(), c.ID(), c)
-}
-
-func findgopls() string {
-	totry := [][]string{{"GOBIN", "/gopls"}, {"GOPATH", "/bin/gopls"}, {"HOME", "/go/bin/gopls"}}
-	// looks in the places go install would install:
-	// GOBIN, else GOPATH/bin, else HOME/go/bin
-	ok := func(s string) bool {
-		fd, err := os.Open(s)
-		if err != nil {
-			return false
-		}
-		fi, err := fd.Stat()
-		if err != nil {
-			return false
-		}
-		return fi.Mode()&0111 != 0
-	}
-	for _, t := range totry {
-		g := os.Getenv(t[0])
-		if g != "" && ok(g+t[1]) {
-			gopls := g + t[1]
-			log.Printf("using gopls at %s", gopls)
-			return gopls
-		}
-	}
-	log.Fatal("could not find gopls")
-	return ""
-}
-
-func mimic(ctx context.Context) {
-	log.Printf("mimic %d", len(msgs))
-	if *command == "" {
-		*command = findgopls()
-	}
-	cmd := exec.Command(*command, "-logfile", "/tmp/seen", "-rpc.trace")
-	toServer, err := cmd.StdinPipe()
-	if err != nil {
-		log.Fatal(err)
-	}
-	fromServer, err := cmd.StdoutPipe()
-	if err != nil {
-		log.Fatal(err)
-	}
-	err = cmd.Start()
-	if err != nil {
-		log.Fatal(err)
-	}
-	conn := fakenet.NewConn("stdio", fromServer, toServer)
-	stream := jsonrpc2.NewHeaderStream(conn)
-	rchan := make(chan jsonrpc2.Message, 10) // do we need buffering?
-	rdr := func() {
-		for {
-			msg, _, err := stream.Read(ctx)
-			if err != nil {
-				rchan <- nil // close it instead?
-				return
-			}
-			rchan <- msg
-		}
-	}
-	go rdr()
-	// send as many as possible: all clrequests and toservers up to a clresponse
-	// and loop
-	seenids := make(map[string]bool) // id's that have been responded to:
-big:
-	for _, l := range msgs {
-		switch l.Type {
-		case parse.ToServer: // just send these as we get to them
-			send(ctx, l, stream, nil)
-		case parse.ClRequest:
-			send(ctx, l, stream, nil) // for now, wait for a response, to make sure code is ok
-			fallthrough
-		case parse.ClResponse, parse.ReportErr: // don't go past these until they're received
-			if seenids[l.ID] {
-				break // onward, as it has been received already
-			}
-		done:
-			for {
-				msg := <-rchan
-				if msg == nil {
-					break big
-				}
-				// if it's svrequest, do something
-				// if it's clresponse or reporterr, add to seenids, and if it
-				// is l.id, break out of the loop, and continue the outer loop
-
-				switch msg := msg.(type) {
-				case *jsonrpc2.Call:
-					if parse.FromServer(msg.Method()) {
-						respond(ctx, msg, stream)
-						continue done // still waiting
-					}
-				case *jsonrpc2.Response:
-					id := fmt.Sprint(msg.ID())
-					seenids[id] = true
-					if id == l.ID {
-						break done
-					}
-				}
-			}
-		case parse.SvRequest: // not ours to send
-			continue
-		case parse.SvResponse: // sent by us, if the request arrives
-			continue
-		case parse.ToClient: // we don't send these
-			continue
-		}
-	}
-}
diff --git a/gopls/internal/coverage/coverage.go b/gopls/internal/coverage/coverage.go
new file mode 100644
index 0000000..7bb3640
--- /dev/null
+++ b/gopls/internal/coverage/coverage.go
@@ -0,0 +1,261 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go.1.16
+// +build go.1.16
+
+// Running this program in the tools directory will produce a coverage file /tmp/cover.out
+// and a coverage report for all the packages under internal/lsp, accumulated by all the tests
+// under gopls.
+//
+// -o controls where the coverage file is written, defaulting to /tmp/cover.out
+// -i coverage-file will generate the report from an existing coverage file
+// -v controls verbosity (0: only report coverage, 1: report as each directory is finished,
+//      2: report on each test, 3: more details, 4: too much)
+// -t tests only tests packages in the given comma-separated list of directories in gopls.
+//      The names should start with ., as in ./internal/regtest/bench
+// -run tests. If set, -run tests is passed on to the go test command.
+//
+// Despite gopls' use of goroutines, the counts are almost deterministic.
+package main
+
+import (
+	"bytes"
+	"encoding/json"
+	"flag"
+	"fmt"
+	"log"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"sort"
+	"strings"
+	"time"
+
+	"golang.org/x/tools/cover"
+)
+
+var (
+	proFile = flag.String("i", "", "existing profile file")
+	outFile = flag.String("o", "/tmp/cover.out", "where to write the coverage file")
+	verbose = flag.Int("v", 0, "how much detail to print as tests are running")
+	tests   = flag.String("t", "", "list of tests to run")
+	run     = flag.String("run", "", "value of -run to pass to go test")
+)
+
+func main() {
+	log.SetFlags(log.Lshortfile)
+	flag.Parse()
+
+	if *proFile != "" {
+		report(*proFile)
+		return
+	}
+
+	checkCwd()
+	// find the packages under gopls containing tests
+	tests := listDirs("gopls")
+	tests = onlyTests(tests)
+	tests = realTestName(tests)
+
+	// report coverage for packages under internal/lsp
+	parg := "golang.org/x/tools/internal/lsp/..."
+
+	accum := []string{}
+	seen := make(map[string]bool)
+	now := time.Now()
+	for _, toRun := range tests {
+		if excluded(toRun) {
+			continue
+		}
+		x := runTest(toRun, parg)
+		if *verbose > 0 {
+			fmt.Printf("finished %s %.1fs\n", toRun, time.Since(now).Seconds())
+		}
+		lines := bytes.Split(x, []byte{'\n'})
+		for _, l := range lines {
+			if len(l) == 0 {
+				continue
+			}
+			if !seen[string(l)] {
+				// not accumulating counts, so only works for mode:set
+				seen[string(l)] = true
+				accum = append(accum, string(l))
+			}
+		}
+	}
+	sort.Strings(accum[1:])
+	if err := os.WriteFile(*outFile, []byte(strings.Join(accum, "\n")), 0644); err != nil {
+		log.Print(err)
+	}
+	report(*outFile)
+}
+
+type result struct {
+	Time    time.Time
+	Test    string
+	Action  string
+	Package string
+	Output  string
+	Elapsed float64
+}
+
+func runTest(tName, parg string) []byte {
+	args := []string{"test", "-short", "-coverpkg", parg, "-coverprofile", *outFile,
+		"-json"}
+	if *run != "" {
+		args = append(args, fmt.Sprintf("-run=%s", *run))
+	}
+	args = append(args, tName)
+	cmd := exec.Command("go", args...)
+	cmd.Dir = "./gopls"
+	ans, err := cmd.Output()
+	if *verbose > 1 {
+		got := strings.Split(string(ans), "\n")
+		for _, g := range got {
+			if g == "" {
+				continue
+			}
+			var m result
+			if err := json.Unmarshal([]byte(g), &m); err != nil {
+				log.Printf("%T/%v", err, err) // shouldn't happen
+				continue
+			}
+			maybePrint(m)
+		}
+	}
+	if err != nil {
+		log.Printf("%s: %q, cmd=%s", tName, ans, cmd.String())
+	}
+	buf, err := os.ReadFile(*outFile)
+	if err != nil {
+		log.Fatal(err)
+	}
+	return buf
+}
+
+func report(fn string) {
+	profs, err := cover.ParseProfiles(fn)
+	if err != nil {
+		log.Fatal(err)
+	}
+	for _, p := range profs {
+		statements, counts := 0, 0
+		for _, x := range p.Blocks {
+			statements += x.NumStmt
+			if x.Count != 0 {
+				counts += x.NumStmt // sic: if any were executed, all were
+			}
+		}
+		pc := 100 * float64(counts) / float64(statements)
+		fmt.Printf("%3.0f%% %3d/%3d %s\n", pc, counts, statements, p.FileName)
+	}
+}
+
+var todo []string // tests to run
+
+func excluded(tname string) bool {
+	if *tests == "" { // run all tests
+		return false
+	}
+	if todo == nil {
+		todo = strings.Split(*tests, ",")
+	}
+	for _, nm := range todo {
+		if tname == nm { // run this test
+			return false
+		}
+	}
+	// not in list, skip it
+	return true
+}
+
+// should m.Package be printed sometime?
+func maybePrint(m result) {
+	switch m.Action {
+	case "pass", "fail", "skip":
+		fmt.Printf("%s %s %.3f\n", m.Action, m.Test, m.Elapsed)
+	case "run":
+		if *verbose > 2 {
+			fmt.Printf("%s %s %.3f\n", m.Action, m.Test, m.Elapsed)
+		}
+	case "output":
+		if *verbose > 3 {
+			fmt.Printf("%s %s %q %.3f\n", m.Action, m.Test, m.Output, m.Elapsed)
+		}
+	default:
+		log.Fatalf("unknown action %s\n", m.Action)
+	}
+}
+
+// return only the directories that contain tests
+func onlyTests(s []string) []string {
+	ans := []string{}
+outer:
+	for _, d := range s {
+		files, err := os.ReadDir(d)
+		if err != nil {
+			log.Fatalf("%s: %v", d, err)
+		}
+		for _, de := range files {
+			if strings.Contains(de.Name(), "_test.go") {
+				ans = append(ans, d)
+				continue outer
+			}
+		}
+	}
+	return ans
+}
+
+// replace the prefix gopls/ with ./ as the tests are run in the gopls directory
+func realTestName(p []string) []string {
+	ans := []string{}
+	for _, x := range p {
+		x = x[len("gopls/"):]
+		ans = append(ans, "./"+x)
+	}
+	return ans
+}
+
+// make sure we start in a tools directory
+func checkCwd() {
+	dir, err := os.Getwd()
+	if err != nil {
+		log.Fatal(err)
+	}
+	// we expect to be a the root of golang.org/x/tools
+	cmd := exec.Command("go", "list", "-m", "-f", "{{.Dir}}", "golang.org/x/tools")
+	buf, err := cmd.Output()
+	buf = bytes.Trim(buf, "\n \t") // remove \n at end
+	if err != nil {
+		log.Fatal(err)
+	}
+	if string(buf) != dir {
+		log.Fatalf("wrong directory: in %q, should be in %q", dir, string(buf))
+	}
+	// and we expect gopls and internal/lsp as subdirectories
+	_, err = os.Stat("gopls")
+	if err != nil {
+		log.Fatalf("expected a gopls directory, %v", err)
+	}
+	_, err = os.Stat("internal/lsp")
+	if err != nil {
+		log.Fatalf("expected to see internal/lsp, %v", err)
+	}
+}
+
+func listDirs(dir string) []string {
+	ans := []string{}
+	f := func(path string, dirEntry os.DirEntry, err error) error {
+		if strings.HasSuffix(path, "/testdata") || strings.HasSuffix(path, "/typescript") {
+			return filepath.SkipDir
+		}
+		if dirEntry.IsDir() {
+			ans = append(ans, path)
+		}
+		return nil
+	}
+	filepath.WalkDir(dir, f)
+	return ans
+}
diff --git a/gopls/internal/regtest/codelens/codelens_test.go b/gopls/internal/regtest/codelens/codelens_test.go
index 88d0e04..87d0863 100644
--- a/gopls/internal/regtest/codelens/codelens_test.go
+++ b/gopls/internal/regtest/codelens/codelens_test.go
@@ -275,9 +275,6 @@
 }
 
 func TestGCDetails(t *testing.T) {
-	if testing.Short() {
-		t.Skip("Flaky test -- see golang.org/issue/44099")
-	}
 	testenv.NeedsGo1Point(t, 15)
 	if runtime.GOOS == "android" {
 		t.Skipf("the gc details code lens doesn't work on Android")
diff --git a/gopls/internal/regtest/completion/postfix_snippet_test.go b/gopls/internal/regtest/completion/postfix_snippet_test.go
new file mode 100644
index 0000000..4c59ef9
--- /dev/null
+++ b/gopls/internal/regtest/completion/postfix_snippet_test.go
@@ -0,0 +1,402 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package completion
+
+import (
+	"strings"
+	"testing"
+
+	. "golang.org/x/tools/gopls/internal/regtest"
+	"golang.org/x/tools/internal/lsp/source"
+)
+
+func TestPostfixSnippetCompletion(t *testing.T) {
+	const mod = `
+-- go.mod --
+module mod.com
+
+go 1.12
+`
+
+	cases := []struct {
+		name          string
+		before, after string
+	}{
+		{
+			name: "sort",
+			before: `
+package foo
+
+func _() {
+	var foo []int
+	foo.sort
+}
+`,
+			after: `
+package foo
+
+import "sort"
+
+func _() {
+	var foo []int
+	sort.Slice(foo, func(i, j int) bool {
+	$0
+})
+}
+`,
+		},
+		{
+			name: "sort_renamed_sort_package",
+			before: `
+package foo
+
+import blahsort "sort"
+
+var j int
+
+func _() {
+	var foo []int
+	foo.sort
+}
+`,
+			after: `
+package foo
+
+import blahsort "sort"
+
+var j int
+
+func _() {
+	var foo []int
+	blahsort.Slice(foo, func(i, j2 int) bool {
+	$0
+})
+}
+`,
+		},
+		{
+			name: "last",
+			before: `
+package foo
+
+func _() {
+	var s struct { i []int }
+	s.i.last
+}
+`,
+			after: `
+package foo
+
+func _() {
+	var s struct { i []int }
+	s.i[len(s.i)-1]
+}
+`,
+		},
+		{
+			name: "reverse",
+			before: `
+package foo
+
+func _() {
+	var foo []int
+	foo.reverse
+}
+`,
+			after: `
+package foo
+
+func _() {
+	var foo []int
+	for i, j := 0, len(foo)-1; i < j; i, j = i+1, j-1 {
+	foo[i], foo[j] = foo[j], foo[i]
+}
+
+}
+`,
+		},
+		{
+			name: "slice_range",
+			before: `
+package foo
+
+func _() {
+	type myThing struct{}
+	var foo []myThing
+	foo.range
+}
+`,
+			after: `
+package foo
+
+func _() {
+	type myThing struct{}
+	var foo []myThing
+	for i, mt := range foo {
+	$0
+}
+}
+`,
+		},
+		{
+			name: "append_stmt",
+			before: `
+package foo
+
+func _() {
+	var foo []int
+	foo.append
+}
+`,
+			after: `
+package foo
+
+func _() {
+	var foo []int
+	foo = append(foo, $0)
+}
+`,
+		},
+		{
+			name: "append_expr",
+			before: `
+package foo
+
+func _() {
+	var foo []int
+	var _ []int = foo.append
+}
+`,
+			after: `
+package foo
+
+func _() {
+	var foo []int
+	var _ []int = append(foo, $0)
+}
+`,
+		},
+		{
+			name: "slice_copy",
+			before: `
+package foo
+
+func _() {
+	var foo []int
+	foo.copy
+}
+`,
+			after: `
+package foo
+
+func _() {
+	var foo []int
+	fooCopy := make([]int, len(foo))
+copy(fooCopy, foo)
+
+}
+`,
+		},
+		{
+			name: "map_range",
+			before: `
+package foo
+
+func _() {
+	var foo map[string]int
+	foo.range
+}
+`,
+			after: `
+package foo
+
+func _() {
+	var foo map[string]int
+	for k, v := range foo {
+	$0
+}
+}
+`,
+		},
+		{
+			name: "map_clear",
+			before: `
+package foo
+
+func _() {
+	var foo map[string]int
+	foo.clear
+}
+`,
+			after: `
+package foo
+
+func _() {
+	var foo map[string]int
+	for k := range foo {
+	delete(foo, k)
+}
+
+}
+`,
+		},
+		{
+			name: "map_keys",
+			before: `
+package foo
+
+func _() {
+	var foo map[string]int
+	foo.keys
+}
+`,
+			after: `
+package foo
+
+func _() {
+	var foo map[string]int
+	keys := make([]string, 0, len(foo))
+for k := range foo {
+	keys = append(keys, k)
+}
+
+}
+`,
+		},
+		{
+			name: "var",
+			before: `
+package foo
+
+func foo() (int, error) { return 0, nil }
+
+func _() {
+	foo().var
+}
+`,
+			after: `
+package foo
+
+func foo() (int, error) { return 0, nil }
+
+func _() {
+	i, err := foo()
+}
+`,
+		},
+		{
+			name: "var_single_value",
+			before: `
+package foo
+
+func foo() error { return nil }
+
+func _() {
+	foo().var
+}
+`,
+			after: `
+package foo
+
+func foo() error { return nil }
+
+func _() {
+	err := foo()
+}
+`,
+		},
+		{
+			name: "var_same_type",
+			before: `
+package foo
+
+func foo() (int, int) { return 0, 0 }
+
+func _() {
+	foo().var
+}
+`,
+			after: `
+package foo
+
+func foo() (int, int) { return 0, 0 }
+
+func _() {
+	i, i2 := foo()
+}
+`,
+		},
+		{
+			name: "print_scalar",
+			before: `
+package foo
+
+func _() {
+	var foo int
+	foo.print
+}
+`,
+			after: `
+package foo
+
+import "fmt"
+
+func _() {
+	var foo int
+	fmt.Printf("foo: %v\n", foo)
+}
+`,
+		},
+		{
+			name: "print_multi",
+			before: `
+package foo
+
+func foo() (int, error) { return 0, nil }
+
+func _() {
+	foo().print
+}
+`,
+			after: `
+package foo
+
+import "fmt"
+
+func foo() (int, error) { return 0, nil }
+
+func _() {
+	fmt.Println(foo())
+}
+`,
+		},
+	}
+
+	r := WithOptions(Options(func(o *source.Options) {
+		o.ExperimentalPostfixCompletions = true
+	}))
+	r.Run(t, mod, func(t *testing.T, env *Env) {
+		for _, c := range cases {
+			t.Run(c.name, func(t *testing.T) {
+				c.before = strings.Trim(c.before, "\n")
+				c.after = strings.Trim(c.after, "\n")
+
+				env.CreateBuffer("foo.go", c.before)
+
+				pos := env.RegexpSearch("foo.go", "\n}")
+				completions := env.Completion("foo.go", pos)
+				if len(completions.Items) != 1 {
+					t.Fatalf("expected one completion, got %v", completions.Items)
+				}
+
+				env.AcceptCompletion("foo.go", pos, completions.Items[0])
+
+				if buf := env.Editor.BufferText("foo.go"); buf != c.after {
+					t.Errorf("\nGOT:\n%s\nEXPECTED:\n%s", buf, c.after)
+				}
+			})
+		}
+	})
+}
diff --git a/gopls/internal/regtest/diagnostics/diagnostics_test.go b/gopls/internal/regtest/diagnostics/diagnostics_test.go
index 1d7cb09..3a4beee 100644
--- a/gopls/internal/regtest/diagnostics/diagnostics_test.go
+++ b/gopls/internal/regtest/diagnostics/diagnostics_test.go
@@ -572,12 +572,8 @@
 			WithOptions(EditorConfig{
 				Env: map[string]string{"GO111MODULE": go111module},
 			}).Run(t, files, func(t *testing.T, env *Env) {
-				env.OpenFile("hello.txt")
 				env.Await(
-					OnceMet(
-						env.DoneWithOpen(),
-						NoShowMessage(),
-					),
+					NoOutstandingWork(),
 				)
 			})
 		})
@@ -603,7 +599,14 @@
 	fmt.Println("")
 }
 `
-	WithOptions(InGOPATH()).Run(t, collision, func(t *testing.T, env *Env) {
+	WithOptions(
+		InGOPATH(),
+		EditorConfig{
+			Env: map[string]string{
+				"GO111MODULE": "off",
+			},
+		},
+	).Run(t, collision, func(t *testing.T, env *Env) {
 		env.OpenFile("x/x.go")
 		env.Await(
 			env.DiagnosticAtRegexpWithMessage("x/x.go", `^`, "found packages main (main.go) and x (x.go)"),
@@ -898,24 +901,6 @@
 	})
 }
 
-// Reproduces golang/go#40825.
-func TestEmptyGOPATHXTest_40825(t *testing.T) {
-	const files = `
--- x.go --
-package x
--- x_test.go --
-`
-
-	WithOptions(InGOPATH()).Run(t, files, func(t *testing.T, env *Env) {
-		env.OpenFile("x_test.go")
-		env.EditBuffer("x_test.go", fake.NewEdit(0, 0, 0, 0, "pack"))
-		env.Await(
-			env.DoneWithChange(),
-			NoShowMessage(),
-		)
-	})
-}
-
 func TestIgnoredFiles(t *testing.T) {
 	const ws = `
 -- go.mod --
@@ -1491,6 +1476,11 @@
 	WithOptions(
 		ProxyFiles(proxy),
 		InGOPATH(),
+		EditorConfig{
+			Env: map[string]string{
+				"GO111MODULE": "off",
+			},
+		},
 	).Run(t, contents, func(t *testing.T, env *Env) {
 		// Simulate typing character by character.
 		env.OpenFile("foo/foo_test.go")
@@ -1863,6 +1853,29 @@
 	})
 }
 
+func TestInitialization(t *testing.T) {
+	const files = `
+-- go.mod --
+module mod.com
+
+go 1.16
+-- main.go --
+package main
+`
+	Run(t, files, func(t *testing.T, env *Env) {
+		env.OpenFile("go.mod")
+		env.Await(env.DoneWithOpen())
+		env.RegexpReplace("go.mod", "module", "modul")
+		env.SaveBufferWithoutActions("go.mod")
+		env.Await(
+			OnceMet(
+				env.DoneWithSave(),
+				NoLogMatching(protocol.Error, "initial workspace load failed"),
+			),
+		)
+	})
+}
+
 // Tests golang/go#45075, a panic in fillreturns breaks diagnostics.
 func TestFillReturnsPanic(t *testing.T) {
 	// At tip, the panic no longer reproduces.
diff --git a/gopls/internal/regtest/env.go b/gopls/internal/regtest/env.go
index 322799d..3c41066 100644
--- a/gopls/internal/regtest/env.go
+++ b/gopls/internal/regtest/env.go
@@ -282,8 +282,9 @@
 		e.mu.Unlock()
 		return
 	case Unmeetable:
+		failure := fmt.Sprintf("unmeetable expectations:\n%s\nstate:\n%v", summary, e.state)
 		e.mu.Unlock()
-		e.T.Fatalf("unmeetable expectations:\n%s\nstate:\n%v", summary, e.state)
+		e.T.Fatal(failure)
 	}
 	cond := &condition{
 		expectations: expectations,
diff --git a/gopls/internal/regtest/expectation.go b/gopls/internal/regtest/expectation.go
index 02e00dd..f86bcb6 100644
--- a/gopls/internal/regtest/expectation.go
+++ b/gopls/internal/regtest/expectation.go
@@ -582,8 +582,9 @@
 	return DiagnosticExpectation{path: name, message: msg, present: false}
 }
 
-// GoSum asserts that a "go.sum is out of sync" diagnostic for the given module
-// (as formatted in a go.mod file, e.g. "example.com v1.0.0") is present.
+// GoSumDiagnostic asserts that a "go.sum is out of sync" diagnostic for the
+// given module (as formatted in a go.mod file, e.g. "example.com v1.0.0") is
+// present.
 func (e *Env) GoSumDiagnostic(name, module string) Expectation {
 	e.T.Helper()
 	// In 1.16, go.sum diagnostics should appear on the relevant module. Earlier
diff --git a/gopls/internal/regtest/misc/fix_test.go b/gopls/internal/regtest/misc/fix_test.go
index 395bfd8..9225a83 100644
--- a/gopls/internal/regtest/misc/fix_test.go
+++ b/gopls/internal/regtest/misc/fix_test.go
@@ -81,6 +81,25 @@
 			env.DiagnosticAtRegexpWithMessage("main.go", `return`, "wrong number of return values"),
 			ReadDiagnostics("main.go", &d),
 		))
+		codeActions := env.CodeAction("main.go", d.Diagnostics)
+		if len(codeActions) != 2 {
+			t.Fatalf("expected 2 code actions, got %v", len(codeActions))
+		}
+		var foundQuickFix, foundFixAll bool
+		for _, a := range codeActions {
+			if a.Kind == protocol.QuickFix {
+				foundQuickFix = true
+			}
+			if a.Kind == protocol.SourceFixAll {
+				foundFixAll = true
+			}
+		}
+		if !foundQuickFix {
+			t.Fatalf("expected quickfix code action, got none")
+		}
+		if !foundFixAll {
+			t.Fatalf("expected fixall code action, got none")
+		}
 		env.ApplyQuickFixes("main.go", d.Diagnostics)
 		env.Await(EmptyDiagnostics("main.go"))
 	})
diff --git a/gopls/internal/regtest/misc/highlight_test.go b/gopls/internal/regtest/misc/highlight_test.go
new file mode 100644
index 0000000..56e6116
--- /dev/null
+++ b/gopls/internal/regtest/misc/highlight_test.go
@@ -0,0 +1,151 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package misc
+
+import (
+	"sort"
+	"testing"
+
+	. "golang.org/x/tools/gopls/internal/regtest"
+	"golang.org/x/tools/internal/lsp/fake"
+	"golang.org/x/tools/internal/lsp/protocol"
+)
+
+func TestWorkspacePackageHighlight(t *testing.T) {
+	const mod = `
+-- go.mod --
+module mod.com
+
+go 1.12
+-- main.go --
+package main
+
+func main() {
+	var A string = "A"
+	x := "x-" + A
+	println(A, x)
+}`
+
+	Run(t, mod, func(t *testing.T, env *Env) {
+		const file = "main.go"
+		env.OpenFile(file)
+		_, pos := env.GoToDefinition(file, env.RegexpSearch(file, `var (A) string`))
+
+		checkHighlights(env, file, pos, 3)
+	})
+}
+
+func TestStdPackageHighlight_Issue43511(t *testing.T) {
+	const mod = `
+-- go.mod --
+module mod.com
+
+go 1.12
+-- main.go --
+package main
+
+import "fmt"
+
+func main() {
+	fmt.Printf()
+}`
+
+	Run(t, mod, func(t *testing.T, env *Env) {
+		env.OpenFile("main.go")
+		file, _ := env.GoToDefinition("main.go", env.RegexpSearch("main.go", `fmt\.(Printf)`))
+		pos := env.RegexpSearch(file, `func Printf\((format) string`)
+
+		checkHighlights(env, file, pos, 2)
+	})
+}
+
+func TestThirdPartyPackageHighlight_Issue43511(t *testing.T) {
+	const proxy = `
+-- example.com@v1.2.3/go.mod --
+module example.com
+
+go 1.12
+-- example.com@v1.2.3/global/global.go --
+package global
+
+const A = 1
+
+func foo() {
+	_ = A
+}
+
+func bar() int {
+	return A + A
+}
+-- example.com@v1.2.3/local/local.go --
+package local
+
+func foo() int {
+	const b = 2
+
+	return b * b * (b+1) + b
+}`
+
+	const mod = `
+-- go.mod --
+module mod.com
+
+go 1.12
+
+require example.com v1.2.3
+-- go.sum --
+example.com v1.2.3 h1:WFzrgiQJwEDJNLDUOV1f9qlasQkvzXf2UNLaNIqbWsI=
+example.com v1.2.3/go.mod h1:Y2Rc5rVWjWur0h3pd9aEvK5Pof8YKDANh9gHA2Maujo=
+-- main.go --
+package main
+
+import (
+	_ "example.com/global"
+	_ "example.com/local"
+)
+
+func main() {}`
+
+	WithOptions(
+		ProxyFiles(proxy),
+	).Run(t, mod, func(t *testing.T, env *Env) {
+		env.OpenFile("main.go")
+
+		file, _ := env.GoToDefinition("main.go", env.RegexpSearch("main.go", `"example.com/global"`))
+		pos := env.RegexpSearch(file, `const (A)`)
+		checkHighlights(env, file, pos, 4)
+
+		file, _ = env.GoToDefinition("main.go", env.RegexpSearch("main.go", `"example.com/local"`))
+		pos = env.RegexpSearch(file, `const (b)`)
+		checkHighlights(env, file, pos, 5)
+	})
+}
+
+func checkHighlights(env *Env, file string, pos fake.Pos, highlightCount int) {
+	t := env.T
+	t.Helper()
+
+	highlights := env.DocumentHighlight(file, pos)
+	if len(highlights) != highlightCount {
+		t.Fatalf("expected %v highlight(s), got %v", highlightCount, len(highlights))
+	}
+
+	references := env.References(file, pos)
+	if len(highlights) != len(references) {
+		t.Fatalf("number of highlights and references is expected to be equal: %v != %v", len(highlights), len(references))
+	}
+
+	sort.Slice(highlights, func(i, j int) bool {
+		return protocol.CompareRange(highlights[i].Range, highlights[j].Range) < 0
+	})
+	sort.Slice(references, func(i, j int) bool {
+		return protocol.CompareRange(references[i].Range, references[j].Range) < 0
+	})
+	for i := range highlights {
+		if highlights[i].Range != references[i].Range {
+			t.Errorf("highlight and reference ranges are expected to be equal: %v != %v", highlights[i].Range, references[i].Range)
+		}
+	}
+}
diff --git a/gopls/internal/regtest/misc/imports_test.go b/gopls/internal/regtest/misc/imports_test.go
index 9a95208..2a666c4 100644
--- a/gopls/internal/regtest/misc/imports_test.go
+++ b/gopls/internal/regtest/misc/imports_test.go
@@ -74,7 +74,7 @@
 	Run(t, "", func(t *testing.T, env *Env) {
 		env.CreateBuffer("main.go", vim1)
 		env.OrganizeImports("main.go")
-		actions := env.CodeAction("main.go")
+		actions := env.CodeAction("main.go", nil)
 		if len(actions) > 0 {
 			got := env.Editor.BufferText("main.go")
 			t.Errorf("unexpected actions %#v", actions)
@@ -107,7 +107,7 @@
 	Run(t, "", func(t *testing.T, env *Env) {
 		env.CreateBuffer("main.go", vim2)
 		env.OrganizeImports("main.go")
-		actions := env.CodeAction("main.go")
+		actions := env.CodeAction("main.go", nil)
 		if len(actions) > 0 {
 			t.Errorf("unexpected actions %#v", actions)
 		}
diff --git a/gopls/internal/regtest/runner.go b/gopls/internal/regtest/runner.go
index a029b9c..cfa64af 100644
--- a/gopls/internal/regtest/runner.go
+++ b/gopls/internal/regtest/runner.go
@@ -70,19 +70,21 @@
 }
 
 type runConfig struct {
-	editor    fake.EditorConfig
-	sandbox   fake.SandboxConfig
-	modes     Mode
-	timeout   time.Duration
-	debugAddr string
-	skipLogs  bool
-	skipHooks bool
+	editor      fake.EditorConfig
+	sandbox     fake.SandboxConfig
+	modes       Mode
+	timeout     time.Duration
+	debugAddr   string
+	skipLogs    bool
+	skipHooks   bool
+	optionsHook func(*source.Options)
 }
 
 func (r *Runner) defaultConfig() *runConfig {
 	return &runConfig{
-		modes:   r.DefaultModes,
-		timeout: r.Timeout,
+		modes:       r.DefaultModes,
+		timeout:     r.Timeout,
+		optionsHook: hooks.Options,
 	}
 }
 
@@ -118,6 +120,19 @@
 	})
 }
 
+// Options configures the various server and user options.
+func Options(hook func(*source.Options)) RunOption {
+	return optionSetter(func(opts *runConfig) {
+		old := opts.optionsHook
+		opts.optionsHook = func(o *source.Options) {
+			if old != nil {
+				old(o)
+			}
+			hook(o)
+		}
+	})
+}
+
 func SendPID() RunOption {
 	return optionSetter(func(opts *runConfig) {
 		opts.editor.SendPID = true
@@ -216,7 +231,7 @@
 	tests := []struct {
 		name      string
 		mode      Mode
-		getServer func(context.Context, *testing.T) jsonrpc2.StreamServer
+		getServer func(context.Context, *testing.T, func(*source.Options)) jsonrpc2.StreamServer
 	}{
 		{"singleton", Singleton, singletonServer},
 		{"forwarded", Forwarded, r.forwardedServer},
@@ -268,7 +283,7 @@
 			// better solution to ensure that all Go processes started by gopls have
 			// exited before we clean up.
 			r.AddCloser(sandbox)
-			ss := tc.getServer(ctx, t)
+			ss := tc.getServer(ctx, t, config.optionsHook)
 			framer := jsonrpc2.NewRawStream
 			ls := &loggingFramer{}
 			if !config.skipLogs {
@@ -367,38 +382,38 @@
 	fmt.Fprintf(os.Stderr, "#### End Gopls Test Logs for %q\n", testname)
 }
 
-func singletonServer(ctx context.Context, t *testing.T) jsonrpc2.StreamServer {
-	return lsprpc.NewStreamServer(cache.New(ctx, hooks.Options), false)
+func singletonServer(ctx context.Context, t *testing.T, optsHook func(*source.Options)) jsonrpc2.StreamServer {
+	return lsprpc.NewStreamServer(cache.New(optsHook), false)
 }
 
-func experimentalWorkspaceModule(ctx context.Context, t *testing.T) jsonrpc2.StreamServer {
+func experimentalWorkspaceModule(_ context.Context, t *testing.T, optsHook func(*source.Options)) jsonrpc2.StreamServer {
 	options := func(o *source.Options) {
-		hooks.Options(o)
+		optsHook(o)
 		o.ExperimentalWorkspaceModule = true
 	}
-	return lsprpc.NewStreamServer(cache.New(ctx, options), false)
+	return lsprpc.NewStreamServer(cache.New(options), false)
 }
 
-func (r *Runner) forwardedServer(ctx context.Context, t *testing.T) jsonrpc2.StreamServer {
-	ts := r.getTestServer()
+func (r *Runner) forwardedServer(ctx context.Context, t *testing.T, optsHook func(*source.Options)) jsonrpc2.StreamServer {
+	ts := r.getTestServer(optsHook)
 	return lsprpc.NewForwarder("tcp", ts.Addr)
 }
 
 // getTestServer gets the shared test server instance to connect to, or creates
 // one if it doesn't exist.
-func (r *Runner) getTestServer() *servertest.TCPServer {
+func (r *Runner) getTestServer(optsHook func(*source.Options)) *servertest.TCPServer {
 	r.mu.Lock()
 	defer r.mu.Unlock()
 	if r.ts == nil {
 		ctx := context.Background()
 		ctx = debug.WithInstance(ctx, "", "off")
-		ss := lsprpc.NewStreamServer(cache.New(ctx, hooks.Options), false)
+		ss := lsprpc.NewStreamServer(cache.New(optsHook), false)
 		r.ts = servertest.NewTCPServer(ctx, ss, nil)
 	}
 	return r.ts
 }
 
-func (r *Runner) separateProcessServer(ctx context.Context, t *testing.T) jsonrpc2.StreamServer {
+func (r *Runner) separateProcessServer(ctx context.Context, t *testing.T, optsHook func(*source.Options)) jsonrpc2.StreamServer {
 	// TODO(rfindley): can we use the autostart behavior here, instead of
 	// pre-starting the remote?
 	socket := r.getRemoteSocket(t)
diff --git a/gopls/internal/regtest/watch/watch_test.go b/gopls/internal/regtest/watch/watch_test.go
index ae43bea..9cc9d0a 100644
--- a/gopls/internal/regtest/watch/watch_test.go
+++ b/gopls/internal/regtest/watch/watch_test.go
@@ -617,6 +617,11 @@
 `
 	WithOptions(
 		InGOPATH(),
+		EditorConfig{
+			Env: map[string]string{
+				"GO111MODULE": "auto",
+			},
+		},
 		Modes(Experimental), // module is in a subdirectory
 	).Run(t, files, func(t *testing.T, env *Env) {
 		env.OpenFile("foo/main.go")
@@ -624,12 +629,6 @@
 		if err := env.Sandbox.RunGoCommand(env.Ctx, "foo", "mod", []string{"init", "mod.com"}); err != nil {
 			t.Fatal(err)
 		}
-		env.Await(
-			OnceMet(
-				env.DoneWithChangeWatchedFiles(),
-				env.DiagnosticAtRegexp("foo/main.go", `"blah"`),
-			),
-		)
 		env.RegexpReplace("foo/main.go", `"blah"`, `"mod.com/blah"`)
 		env.Await(
 			EmptyDiagnostics("foo/main.go"),
@@ -661,6 +660,11 @@
 `
 	WithOptions(
 		InGOPATH(),
+		EditorConfig{
+			Env: map[string]string{
+				"GO111MODULE": "auto",
+			},
+		},
 	).Run(t, files, func(t *testing.T, env *Env) {
 		env.OpenFile("foo/main.go")
 		env.RemoveWorkspaceFile("foo/go.mod")
diff --git a/gopls/internal/regtest/workspace/workspace_test.go b/gopls/internal/regtest/workspace/workspace_test.go
index f0128d8..21e33b6 100644
--- a/gopls/internal/regtest/workspace/workspace_test.go
+++ b/gopls/internal/regtest/workspace/workspace_test.go
@@ -5,15 +5,16 @@
 package workspace
 
 import (
+	"encoding/json"
 	"fmt"
 	"io/ioutil"
-	"os"
 	"path/filepath"
 	"strings"
 	"testing"
 
 	. "golang.org/x/tools/gopls/internal/regtest"
 
+	"golang.org/x/tools/internal/lsp/command"
 	"golang.org/x/tools/internal/lsp/fake"
 	"golang.org/x/tools/internal/lsp/protocol"
 	"golang.org/x/tools/internal/testenv"
@@ -647,10 +648,19 @@
 		Modes(Experimental),
 		SendPID(),
 	).Run(t, multiModule, func(t *testing.T, env *Env) {
-		pid := os.Getpid()
+		params := &protocol.ExecuteCommandParams{
+			Command:   command.WorkspaceMetadata.ID(),
+			Arguments: []json.RawMessage{json.RawMessage("{}")},
+		}
+		var result command.WorkspaceMetadataResult
+		env.ExecuteCommand(params, &result)
+
+		if n := len(result.Workspaces); n != 1 {
+			env.T.Fatalf("got %d workspaces, want 1", n)
+		}
 		// Don't factor this out of Server.addFolders. vscode-go expects this
 		// directory.
-		modPath := filepath.Join(os.TempDir(), fmt.Sprintf("gopls-%d.workspace", pid), "go.mod")
+		modPath := filepath.Join(result.Workspaces[0].ModuleDir, "go.mod")
 		gotb, err := ioutil.ReadFile(modPath)
 		if err != nil {
 			t.Fatalf("reading expected workspace modfile: %v", err)
diff --git a/gopls/internal/regtest/wrappers.go b/gopls/internal/regtest/wrappers.go
index c77de5b..2038849 100644
--- a/gopls/internal/regtest/wrappers.go
+++ b/gopls/internal/regtest/wrappers.go
@@ -5,6 +5,7 @@
 package regtest
 
 import (
+	"encoding/json"
 	"io"
 	"path"
 	"testing"
@@ -229,6 +230,15 @@
 	return links
 }
 
+func (e *Env) DocumentHighlight(name string, pos fake.Pos) []protocol.DocumentHighlight {
+	e.T.Helper()
+	highlights, err := e.Editor.DocumentHighlight(e.Ctx, name, pos)
+	if err != nil {
+		e.T.Fatal(err)
+	}
+	return highlights
+}
+
 func checkIsFatal(t *testing.T, err error) {
 	t.Helper()
 	if err != nil && !errors.Is(err, io.EOF) && !errors.Is(err, io.ErrClosedPipe) {
@@ -312,6 +322,7 @@
 // ExecuteCodeLensCommand executes the command for the code lens matching the
 // given command name.
 func (e *Env) ExecuteCodeLensCommand(path string, cmd command.Command) {
+	e.T.Helper()
 	lenses := e.CodeLens(path)
 	var lens protocol.CodeLens
 	var found bool
@@ -324,10 +335,32 @@
 	if !found {
 		e.T.Fatalf("found no command with the ID %s", cmd.ID())
 	}
-	if _, err := e.Editor.ExecuteCommand(e.Ctx, &protocol.ExecuteCommandParams{
+	e.ExecuteCommand(&protocol.ExecuteCommandParams{
 		Command:   lens.Command.Command,
 		Arguments: lens.Command.Arguments,
-	}); err != nil {
+	}, nil)
+}
+
+func (e *Env) ExecuteCommand(params *protocol.ExecuteCommandParams, result interface{}) {
+	e.T.Helper()
+	response, err := e.Editor.ExecuteCommand(e.Ctx, params)
+	if err != nil {
+		e.T.Fatal(err)
+	}
+	if result == nil {
+		return
+	}
+	// Hack: The result of an executeCommand request will be unmarshaled into
+	// maps. Re-marshal and unmarshal into the type we expect.
+	//
+	// This could be improved by generating a jsonrpc2 command client from the
+	// command.Interface, but that should only be done if we're consolidating
+	// this part of the tsprotocol generation.
+	data, err := json.Marshal(response)
+	if err != nil {
+		e.T.Fatal(err)
+	}
+	if err := json.Unmarshal(data, result); err != nil {
 		e.T.Fatal(err)
 	}
 }
@@ -364,9 +397,9 @@
 
 // CodeAction calls testDocument/codeAction for the given path, and calls
 // t.Fatal if there are errors.
-func (e *Env) CodeAction(path string) []protocol.CodeAction {
+func (e *Env) CodeAction(path string, diagnostics []protocol.Diagnostic) []protocol.CodeAction {
 	e.T.Helper()
-	actions, err := e.Editor.CodeAction(e.Ctx, path, nil)
+	actions, err := e.Editor.CodeAction(e.Ctx, path, nil, diagnostics)
 	if err != nil {
 		e.T.Fatal(err)
 	}
diff --git a/internal/event/label/label.go b/internal/event/label/label.go
index b55c12e..0f526e1 100644
--- a/internal/event/label/label.go
+++ b/internal/event/label/label.go
@@ -96,6 +96,8 @@
 // access should be done with the From method of the key.
 func (t Label) Unpack64() uint64 { return t.packed }
 
+type stringptr unsafe.Pointer
+
 // OfString creates a new label from a key and a string.
 // This method is for implementing new key types, label creation should
 // normally be done with the Of method of the key.
@@ -104,7 +106,7 @@
 	return Label{
 		key:     k,
 		packed:  uint64(hdr.Len),
-		untyped: unsafe.Pointer(hdr.Data),
+		untyped: stringptr(hdr.Data),
 	}
 }
 
@@ -115,9 +117,9 @@
 func (t Label) UnpackString() string {
 	var v string
 	hdr := (*reflect.StringHeader)(unsafe.Pointer(&v))
-	hdr.Data = uintptr(t.untyped.(unsafe.Pointer))
+	hdr.Data = uintptr(t.untyped.(stringptr))
 	hdr.Len = int(t.packed)
-	return *(*string)(unsafe.Pointer(hdr))
+	return v
 }
 
 // Valid returns true if the Label is a valid one (it has a key).
diff --git a/internal/event/label/label_test.go b/internal/event/label/label_test.go
index ea34ff7..a2b5818 100644
--- a/internal/event/label/label_test.go
+++ b/internal/event/label/label_test.go
@@ -7,7 +7,9 @@
 import (
 	"bytes"
 	"fmt"
+	"runtime"
 	"testing"
+	"unsafe"
 
 	"golang.org/x/tools/internal/event/keys"
 	"golang.org/x/tools/internal/event/label"
@@ -267,3 +269,17 @@
 	}
 	return buf.String()
 }
+
+func TestAttemptedStringCorruption(t *testing.T) {
+	defer func() {
+		r := recover()
+		if _, ok := r.(*runtime.TypeAssertionError); !ok {
+			t.Fatalf("wanted to recover TypeAssertionError, got %T", r)
+		}
+	}()
+
+	var x uint64 = 12390
+	p := unsafe.Pointer(&x)
+	l := label.OfValue(AKey, p)
+	_ = l.UnpackString()
+}
diff --git a/internal/jsonrpc2_v2/conn.go b/internal/jsonrpc2_v2/conn.go
new file mode 100644
index 0000000..6d92c0c
--- /dev/null
+++ b/internal/jsonrpc2_v2/conn.go
@@ -0,0 +1,486 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package jsonrpc2
+
+import (
+	"context"
+	"encoding/json"
+	"fmt"
+	"io"
+	"sync/atomic"
+
+	"golang.org/x/tools/internal/event"
+	"golang.org/x/tools/internal/event/label"
+	"golang.org/x/tools/internal/lsp/debug/tag"
+	errors "golang.org/x/xerrors"
+)
+
+// Binder builds a connection configuration.
+// This may be used in servers to generate a new configuration per connection.
+// ConnectionOptions itself implements Binder returning itself unmodified, to
+// allow for the simple cases where no per connection information is needed.
+type Binder interface {
+	// Bind is invoked when creating a new connection.
+	// The connection is not ready to use when Bind is called.
+	Bind(context.Context, *Connection) (ConnectionOptions, error)
+}
+
+// ConnectionOptions holds the options for new connections.
+type ConnectionOptions struct {
+	// Framer allows control over the message framing and encoding.
+	// If nil, HeaderFramer will be used.
+	Framer Framer
+	// Preempter allows registration of a pre-queue message handler.
+	// If nil, no messages will be preempted.
+	Preempter Preempter
+	// Handler is used as the queued message handler for inbound messages.
+	// If nil, all responses will be ErrNotHandled.
+	Handler Handler
+}
+
+// Connection manages the jsonrpc2 protocol, connecting responses back to their
+// calls.
+// Connection is bidirectional; it does not have a designated server or client
+// end.
+type Connection struct {
+	seq         int64 // must only be accessed using atomic operations
+	closer      io.Closer
+	writerBox   chan Writer
+	outgoingBox chan map[ID]chan<- *Response
+	incomingBox chan map[ID]*incoming
+	async       async
+}
+
+type AsyncCall struct {
+	id        ID
+	response  chan *Response // the channel a response will be delivered on
+	resultBox chan asyncResult
+	endSpan   func() // close the tracing span when all processing for the message is complete
+}
+
+type asyncResult struct {
+	result []byte
+	err    error
+}
+
+// incoming is used to track an incoming request as it is being handled
+type incoming struct {
+	request   *Request        // the request being processed
+	baseCtx   context.Context // a base context for the message processing
+	done      func()          // a function called when all processing for the message is complete
+	handleCtx context.Context // the context for handling the message, child of baseCtx
+	cancel    func()          // a function that cancels the handling context
+}
+
+// Bind returns the options unmodified.
+func (o ConnectionOptions) Bind(context.Context, *Connection) (ConnectionOptions, error) {
+	return o, nil
+}
+
+// newConnection creates a new connection and runs it.
+// This is used by the Dial and Serve functions to build the actual connection.
+func newConnection(ctx context.Context, rwc io.ReadWriteCloser, binder Binder) (*Connection, error) {
+	c := &Connection{
+		closer:      rwc,
+		writerBox:   make(chan Writer, 1),
+		outgoingBox: make(chan map[ID]chan<- *Response, 1),
+		incomingBox: make(chan map[ID]*incoming, 1),
+	}
+
+	options, err := binder.Bind(ctx, c)
+	if err != nil {
+		return nil, err
+	}
+	if options.Framer == nil {
+		options.Framer = HeaderFramer()
+	}
+	if options.Preempter == nil {
+		options.Preempter = defaultHandler{}
+	}
+	if options.Handler == nil {
+		options.Handler = defaultHandler{}
+	}
+	c.outgoingBox <- make(map[ID]chan<- *Response)
+	c.incomingBox <- make(map[ID]*incoming)
+	c.async.init()
+	// the goroutines started here will continue until the underlying stream is closed
+	reader := options.Framer.Reader(rwc)
+	readToQueue := make(chan *incoming)
+	queueToDeliver := make(chan *incoming)
+	go c.readIncoming(ctx, reader, readToQueue)
+	go c.manageQueue(ctx, options.Preempter, readToQueue, queueToDeliver)
+	go c.deliverMessages(ctx, options.Handler, queueToDeliver)
+	// releaseing the writer must be the last thing we do in case any requests
+	// are blocked waiting for the connection to be ready
+	c.writerBox <- options.Framer.Writer(rwc)
+	return c, nil
+}
+
+// Notify invokes the target method but does not wait for a response.
+// The params will be marshaled to JSON before sending over the wire, and will
+// be handed to the method invoked.
+func (c *Connection) Notify(ctx context.Context, method string, params interface{}) error {
+	notify, err := NewNotification(method, params)
+	if err != nil {
+		return errors.Errorf("marshaling notify parameters: %v", err)
+	}
+	ctx, done := event.Start(ctx, method,
+		tag.Method.Of(method),
+		tag.RPCDirection.Of(tag.Outbound),
+	)
+	event.Metric(ctx, tag.Started.Of(1))
+	err = c.write(ctx, notify)
+	switch {
+	case err != nil:
+		event.Label(ctx, tag.StatusCode.Of("ERROR"))
+	default:
+		event.Label(ctx, tag.StatusCode.Of("OK"))
+	}
+	done()
+	return err
+}
+
+// Call invokes the target method and returns an object that can be used to await the response.
+// The params will be marshaled to JSON before sending over the wire, and will
+// be handed to the method invoked.
+// You do not have to wait for the response, it can just be ignored if not needed.
+// If sending the call failed, the response will be ready and have the error in it.
+func (c *Connection) Call(ctx context.Context, method string, params interface{}) *AsyncCall {
+	result := &AsyncCall{
+		id:        Int64ID(atomic.AddInt64(&c.seq, 1)),
+		resultBox: make(chan asyncResult, 1),
+	}
+	// generate a new request identifier
+	call, err := NewCall(result.id, method, params)
+	if err != nil {
+		//set the result to failed
+		result.resultBox <- asyncResult{err: errors.Errorf("marshaling call parameters: %w", err)}
+		return result
+	}
+	ctx, endSpan := event.Start(ctx, method,
+		tag.Method.Of(method),
+		tag.RPCDirection.Of(tag.Outbound),
+		tag.RPCID.Of(fmt.Sprintf("%q", result.id)),
+	)
+	result.endSpan = endSpan
+	event.Metric(ctx, tag.Started.Of(1))
+	// We have to add ourselves to the pending map before we send, otherwise we
+	// are racing the response.
+	// rchan is buffered in case the response arrives without a listener.
+	result.response = make(chan *Response, 1)
+	pending := <-c.outgoingBox
+	pending[result.id] = result.response
+	c.outgoingBox <- pending
+	// now we are ready to send
+	if err := c.write(ctx, call); err != nil {
+		// sending failed, we will never get a response, so deliver a fake one
+		r, _ := NewResponse(result.id, nil, err)
+		c.incomingResponse(r)
+	}
+	return result
+}
+
+// ID used for this call.
+// This can be used to cancel the call if needed.
+func (a *AsyncCall) ID() ID { return a.id }
+
+// IsReady can be used to check if the result is already prepared.
+// This is guaranteed to return true on a result for which Await has already
+// returned, or a call that failed to send in the first place.
+func (a *AsyncCall) IsReady() bool {
+	select {
+	case r := <-a.resultBox:
+		a.resultBox <- r
+		return true
+	default:
+		return false
+	}
+}
+
+// Await the results of a Call.
+// The response will be unmarshaled from JSON into the result.
+func (a *AsyncCall) Await(ctx context.Context, result interface{}) error {
+	defer a.endSpan()
+	var r asyncResult
+	select {
+	case response := <-a.response:
+		// response just arrived, prepare the result
+		switch {
+		case response.Error != nil:
+			r.err = response.Error
+			event.Label(ctx, tag.StatusCode.Of("ERROR"))
+		default:
+			r.result = response.Result
+			event.Label(ctx, tag.StatusCode.Of("OK"))
+		}
+	case r = <-a.resultBox:
+		// result already available
+	case <-ctx.Done():
+		event.Label(ctx, tag.StatusCode.Of("CANCELLED"))
+		return ctx.Err()
+	}
+	// refill the box for the next caller
+	a.resultBox <- r
+	// and unpack the result
+	if r.err != nil {
+		return r.err
+	}
+	if result == nil || len(r.result) == 0 {
+		return nil
+	}
+	return json.Unmarshal(r.result, result)
+}
+
+// Respond deliverers a response to an incoming Call.
+// It is an error to not call this exactly once for any message for which a
+// handler has previously returned ErrAsyncResponse. It is also an error to
+// call this for any other message.
+func (c *Connection) Respond(id ID, result interface{}, rerr error) error {
+	pending := <-c.incomingBox
+	defer func() { c.incomingBox <- pending }()
+	entry, found := pending[id]
+	if !found {
+		return nil
+	}
+	delete(pending, id)
+	return c.respond(entry, result, rerr)
+}
+
+// Cancel is used to cancel an inbound message by ID, it does not cancel
+// outgoing messages.
+// This is only used inside a message handler that is layering a
+// cancellation protocol on top of JSON RPC 2.
+// It will not complain if the ID is not a currently active message, and it will
+// not cause any messages that have not arrived yet with that ID to be
+// cancelled.
+func (c *Connection) Cancel(id ID) {
+	pending := <-c.incomingBox
+	defer func() { c.incomingBox <- pending }()
+	if entry, found := pending[id]; found && entry.cancel != nil {
+		entry.cancel()
+		entry.cancel = nil
+	}
+}
+
+// Wait blocks until the connection is fully closed, but does not close it.
+func (c *Connection) Wait() error {
+	return c.async.wait()
+}
+
+// Close can be used to close the underlying stream, and then wait for the connection to
+// fully shut down.
+// This does not cancel in flight requests, but waits for them to gracefully complete.
+func (c *Connection) Close() error {
+	// close the underlying stream
+	if err := c.closer.Close(); err != nil && !isClosingError(err) {
+		return err
+	}
+	// and then wait for it to cause the connection to close
+	if err := c.Wait(); err != nil && !isClosingError(err) {
+		return err
+	}
+	return nil
+}
+
+// readIncoming collects inbound messages from the reader and delivers them, either responding
+// to outgoing calls or feeding requests to the queue.
+func (c *Connection) readIncoming(ctx context.Context, reader Reader, toQueue chan<- *incoming) {
+	defer close(toQueue)
+	for {
+		// get the next message
+		// no lock is needed, this is the only reader
+		msg, n, err := reader.Read(ctx)
+		if err != nil {
+			// The stream failed, we cannot continue
+			c.async.setError(err)
+			return
+		}
+		switch msg := msg.(type) {
+		case *Request:
+			entry := &incoming{
+				request: msg,
+			}
+			// add a span to the context for this request
+			labels := append(make([]label.Label, 0, 3), // make space for the id if present
+				tag.Method.Of(msg.Method),
+				tag.RPCDirection.Of(tag.Inbound),
+			)
+			if msg.IsCall() {
+				labels = append(labels, tag.RPCID.Of(fmt.Sprintf("%q", msg.ID)))
+			}
+			entry.baseCtx, entry.done = event.Start(ctx, msg.Method, labels...)
+			event.Metric(entry.baseCtx,
+				tag.Started.Of(1),
+				tag.ReceivedBytes.Of(n))
+			// in theory notifications cannot be cancelled, but we build them a cancel context anyway
+			entry.handleCtx, entry.cancel = context.WithCancel(entry.baseCtx)
+			// if the request is a call, add it to the incoming map so it can be
+			// cancelled by id
+			if msg.IsCall() {
+				pending := <-c.incomingBox
+				c.incomingBox <- pending
+				pending[msg.ID] = entry
+			}
+			// send the message to the incoming queue
+			toQueue <- entry
+		case *Response:
+			// If method is not set, this should be a response, in which case we must
+			// have an id to send the response back to the caller.
+			c.incomingResponse(msg)
+		}
+	}
+}
+
+func (c *Connection) incomingResponse(msg *Response) {
+	pending := <-c.outgoingBox
+	response, ok := pending[msg.ID]
+	if ok {
+		delete(pending, msg.ID)
+	}
+	c.outgoingBox <- pending
+	if response != nil {
+		response <- msg
+	}
+}
+
+// manageQueue reads incoming requests, attempts to proccess them with the preempter, or queue them
+// up for normal handling.
+func (c *Connection) manageQueue(ctx context.Context, preempter Preempter, fromRead <-chan *incoming, toDeliver chan<- *incoming) {
+	defer close(toDeliver)
+	q := []*incoming{}
+	ok := true
+	for {
+		var nextReq *incoming
+		if len(q) == 0 {
+			// no messages in the queue
+			// if we were closing, then we are done
+			if !ok {
+				return
+			}
+			// not closing, but nothing in the queue, so just block waiting for a read
+			nextReq, ok = <-fromRead
+		} else {
+			// we have a non empty queue, so pick whichever of reading or delivering
+			// that we can make progress on
+			select {
+			case nextReq, ok = <-fromRead:
+			case toDeliver <- q[0]:
+				//TODO: this causes a lot of shuffling, should we use a growing ring buffer? compaction?
+				q = q[1:]
+			}
+		}
+		if nextReq != nil {
+			// TODO: should we allow to limit the queue size?
+			var result interface{}
+			rerr := nextReq.handleCtx.Err()
+			if rerr == nil {
+				// only preempt if not already cancelled
+				result, rerr = preempter.Preempt(nextReq.handleCtx, nextReq.request)
+			}
+			switch {
+			case rerr == ErrNotHandled:
+				// message not handled, add it to the queue for the main handler
+				q = append(q, nextReq)
+			case rerr == ErrAsyncResponse:
+				// message handled but the response will come later
+			default:
+				// anything else means the message is fully handled
+				c.reply(nextReq, result, rerr)
+			}
+		}
+	}
+}
+
+func (c *Connection) deliverMessages(ctx context.Context, handler Handler, fromQueue <-chan *incoming) {
+	defer c.async.done()
+	for entry := range fromQueue {
+		// cancel any messages in the queue that we have a pending cancel for
+		var result interface{}
+		rerr := entry.handleCtx.Err()
+		if rerr == nil {
+			// only deliver if not already cancelled
+			result, rerr = handler.Handle(entry.handleCtx, entry.request)
+		}
+		switch {
+		case rerr == ErrNotHandled:
+			// message not handled, report it back to the caller as an error
+			c.reply(entry, nil, errors.Errorf("%w: %q", ErrMethodNotFound, entry.request.Method))
+		case rerr == ErrAsyncResponse:
+			// message handled but the response will come later
+		default:
+			c.reply(entry, result, rerr)
+		}
+	}
+}
+
+// reply is used to reply to an incoming request that has just been handled
+func (c *Connection) reply(entry *incoming, result interface{}, rerr error) {
+	if entry.request.IsCall() {
+		// we have a call finishing, remove it from the incoming map
+		pending := <-c.incomingBox
+		defer func() { c.incomingBox <- pending }()
+		delete(pending, entry.request.ID)
+	}
+	if err := c.respond(entry, result, rerr); err != nil {
+		// no way to propagate this error
+		//TODO: should we do more than just log it?
+		event.Error(entry.baseCtx, "jsonrpc2 message delivery failed", err)
+	}
+}
+
+// respond sends a response.
+// This is the code shared between reply and SendResponse.
+func (c *Connection) respond(entry *incoming, result interface{}, rerr error) error {
+	var err error
+	if entry.request.IsCall() {
+		// send the response
+		if result == nil && rerr == nil {
+			// call with no response, send an error anyway
+			rerr = errors.Errorf("%w: %q produced no response", ErrInternal, entry.request.Method)
+		}
+		var response *Response
+		response, err = NewResponse(entry.request.ID, result, rerr)
+		if err == nil {
+			// we write the response with the base context, in case the message was cancelled
+			err = c.write(entry.baseCtx, response)
+		}
+	} else {
+		switch {
+		case rerr != nil:
+			// notification failed
+			err = errors.Errorf("%w: %q notification failed: %v", ErrInternal, entry.request.Method, rerr)
+			rerr = nil
+		case result != nil:
+			//notification produced a response, which is an error
+			err = errors.Errorf("%w: %q produced unwanted response", ErrInternal, entry.request.Method)
+		default:
+			// normal notification finish
+		}
+	}
+	switch {
+	case rerr != nil || err != nil:
+		event.Label(entry.baseCtx, tag.StatusCode.Of("ERROR"))
+	default:
+		event.Label(entry.baseCtx, tag.StatusCode.Of("OK"))
+	}
+	// and just to be clean, invoke and clear the cancel if needed
+	if entry.cancel != nil {
+		entry.cancel()
+		entry.cancel = nil
+	}
+	// mark the entire request processing as done
+	entry.done()
+	return err
+}
+
+// write is used by all things that write outgoing messages, including replies.
+// it makes sure that writes are atomic
+func (c *Connection) write(ctx context.Context, msg Message) error {
+	writer := <-c.writerBox
+	defer func() { c.writerBox <- writer }()
+	n, err := writer.Write(ctx, msg)
+	event.Metric(ctx, tag.SentBytes.Of(n))
+	return err
+}
diff --git a/internal/jsonrpc2_v2/frame.go b/internal/jsonrpc2_v2/frame.go
new file mode 100644
index 0000000..634717c
--- /dev/null
+++ b/internal/jsonrpc2_v2/frame.go
@@ -0,0 +1,179 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package jsonrpc2
+
+import (
+	"bufio"
+	"context"
+	"encoding/json"
+	"fmt"
+	"io"
+	"strconv"
+	"strings"
+
+	errors "golang.org/x/xerrors"
+)
+
+// Reader abstracts the transport mechanics from the JSON RPC protocol.
+// A Conn reads messages from the reader it was provided on construction,
+// and assumes that each call to Read fully transfers a single message,
+// or returns an error.
+// A reader is not safe for concurrent use, it is expected it will be used by
+// a single Conn in a safe manner.
+type Reader interface {
+	// Read gets the next message from the stream.
+	Read(context.Context) (Message, int64, error)
+}
+
+// Writer abstracts the transport mechanics from the JSON RPC protocol.
+// A Conn writes messages using the writer it was provided on construction,
+// and assumes that each call to Write fully transfers a single message,
+// or returns an error.
+// A writer is not safe for concurrent use, it is expected it will be used by
+// a single Conn in a safe manner.
+type Writer interface {
+	// Write sends a message to the stream.
+	Write(context.Context, Message) (int64, error)
+}
+
+// Framer wraps low level byte readers and writers into jsonrpc2 message
+// readers and writers.
+// It is responsible for the framing and encoding of messages into wire form.
+type Framer interface {
+	// Reader wraps a byte reader into a message reader.
+	Reader(rw io.Reader) Reader
+	// Writer wraps a byte writer into a message writer.
+	Writer(rw io.Writer) Writer
+}
+
+// RawFramer returns a new Framer.
+// The messages are sent with no wrapping, and rely on json decode consistency
+// to determine message boundaries.
+func RawFramer() Framer { return rawFramer{} }
+
+type rawFramer struct{}
+type rawReader struct{ in *json.Decoder }
+type rawWriter struct{ out io.Writer }
+
+func (rawFramer) Reader(rw io.Reader) Reader {
+	return &rawReader{in: json.NewDecoder(rw)}
+}
+
+func (rawFramer) Writer(rw io.Writer) Writer {
+	return &rawWriter{out: rw}
+}
+
+func (r *rawReader) Read(ctx context.Context) (Message, int64, error) {
+	select {
+	case <-ctx.Done():
+		return nil, 0, ctx.Err()
+	default:
+	}
+	var raw json.RawMessage
+	if err := r.in.Decode(&raw); err != nil {
+		return nil, 0, err
+	}
+	msg, err := DecodeMessage(raw)
+	return msg, int64(len(raw)), err
+}
+
+func (w *rawWriter) Write(ctx context.Context, msg Message) (int64, error) {
+	select {
+	case <-ctx.Done():
+		return 0, ctx.Err()
+	default:
+	}
+	data, err := EncodeMessage(msg)
+	if err != nil {
+		return 0, errors.Errorf("marshaling message: %v", err)
+	}
+	n, err := w.out.Write(data)
+	return int64(n), err
+}
+
+// HeaderFramer returns a new Framer.
+// The messages are sent with HTTP content length and MIME type headers.
+// This is the format used by LSP and others.
+func HeaderFramer() Framer { return headerFramer{} }
+
+type headerFramer struct{}
+type headerReader struct{ in *bufio.Reader }
+type headerWriter struct{ out io.Writer }
+
+func (headerFramer) Reader(rw io.Reader) Reader {
+	return &headerReader{in: bufio.NewReader(rw)}
+}
+
+func (headerFramer) Writer(rw io.Writer) Writer {
+	return &headerWriter{out: rw}
+}
+
+func (r *headerReader) Read(ctx context.Context) (Message, int64, error) {
+	select {
+	case <-ctx.Done():
+		return nil, 0, ctx.Err()
+	default:
+	}
+	var total, length int64
+	// read the header, stop on the first empty line
+	for {
+		line, err := r.in.ReadString('\n')
+		total += int64(len(line))
+		if err != nil {
+			return nil, total, errors.Errorf("failed reading header line: %w", err)
+		}
+		line = strings.TrimSpace(line)
+		// check we have a header line
+		if line == "" {
+			break
+		}
+		colon := strings.IndexRune(line, ':')
+		if colon < 0 {
+			return nil, total, errors.Errorf("invalid header line %q", line)
+		}
+		name, value := line[:colon], strings.TrimSpace(line[colon+1:])
+		switch name {
+		case "Content-Length":
+			if length, err = strconv.ParseInt(value, 10, 32); err != nil {
+				return nil, total, errors.Errorf("failed parsing Content-Length: %v", value)
+			}
+			if length <= 0 {
+				return nil, total, errors.Errorf("invalid Content-Length: %v", length)
+			}
+		default:
+			// ignoring unknown headers
+		}
+	}
+	if length == 0 {
+		return nil, total, errors.Errorf("missing Content-Length header")
+	}
+	data := make([]byte, length)
+	n, err := io.ReadFull(r.in, data)
+	total += int64(n)
+	if err != nil {
+		return nil, total, err
+	}
+	msg, err := DecodeMessage(data)
+	return msg, total, err
+}
+
+func (w *headerWriter) Write(ctx context.Context, msg Message) (int64, error) {
+	select {
+	case <-ctx.Done():
+		return 0, ctx.Err()
+	default:
+	}
+	data, err := EncodeMessage(msg)
+	if err != nil {
+		return 0, errors.Errorf("marshaling message: %v", err)
+	}
+	n, err := fmt.Fprintf(w.out, "Content-Length: %v\r\n\r\n", len(data))
+	total := int64(n)
+	if err == nil {
+		n, err = w.out.Write(data)
+		total += int64(n)
+	}
+	return total, err
+}
diff --git a/internal/jsonrpc2_v2/jsonrpc2.go b/internal/jsonrpc2_v2/jsonrpc2.go
new file mode 100644
index 0000000..1279ba3
--- /dev/null
+++ b/internal/jsonrpc2_v2/jsonrpc2.go
@@ -0,0 +1,93 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package jsonrpc2 is a minimal implementation of the JSON RPC 2 spec.
+// https://www.jsonrpc.org/specification
+// It is intended to be compatible with other implementations at the wire level.
+package jsonrpc2
+
+import (
+	"context"
+	"errors"
+)
+
+var (
+	// ErrIdleTimeout is returned when serving timed out waiting for new connections.
+	ErrIdleTimeout = errors.New("timed out waiting for new connections")
+	// ErrNotHandled is returned from a handler to indicate it did not handle the
+	// message.
+	ErrNotHandled = errors.New("JSON RPC not handled")
+	// ErrAsyncResponse is returned from a handler to indicate it will generate a
+	// response asynchronously.
+	ErrAsyncResponse = errors.New("JSON RPC asynchronous response")
+)
+
+// Preempter handles messages on a connection before they are queued to the main
+// handler.
+// Primarily this is used for cancel handlers or notifications for which out of
+// order processing is not an issue.
+type Preempter interface {
+	// Preempt is invoked for each incoming request before it is queued.
+	// If the request is a call, it must return a value or an error for the reply.
+	// Preempt should not block or start any new messages on the connection.
+	Preempt(ctx context.Context, req *Request) (interface{}, error)
+}
+
+// Handler handles messages on a connection.
+type Handler interface {
+	// Handle is invoked for each incoming request.
+	// If the request is a call, it must return a value or an error for the reply.
+	Handle(ctx context.Context, req *Request) (interface{}, error)
+}
+
+type defaultHandler struct{}
+
+func (defaultHandler) Preempt(context.Context, *Request) (interface{}, error) {
+	return nil, ErrNotHandled
+}
+
+func (defaultHandler) Handle(context.Context, *Request) (interface{}, error) {
+	return nil, ErrNotHandled
+}
+
+// async is a small helper for things with an asynchronous result that you can
+// wait for.
+type async struct {
+	ready  chan struct{}
+	errBox chan error
+}
+
+func (a *async) init() {
+	a.ready = make(chan struct{})
+	a.errBox = make(chan error, 1)
+	a.errBox <- nil
+}
+
+func (a *async) done() {
+	close(a.ready)
+}
+
+func (a *async) isDone() bool {
+	select {
+	case <-a.ready:
+		return true
+	default:
+		return false
+	}
+}
+
+func (a *async) wait() error {
+	<-a.ready
+	err := <-a.errBox
+	a.errBox <- err
+	return err
+}
+
+func (a *async) setError(err error) {
+	storedErr := <-a.errBox
+	if storedErr == nil {
+		storedErr = err
+	}
+	a.errBox <- storedErr
+}
diff --git a/internal/jsonrpc2_v2/jsonrpc2_test.go b/internal/jsonrpc2_v2/jsonrpc2_test.go
new file mode 100644
index 0000000..6d057b4
--- /dev/null
+++ b/internal/jsonrpc2_v2/jsonrpc2_test.go
@@ -0,0 +1,389 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package jsonrpc2_test
+
+import (
+	"context"
+	"encoding/json"
+	"fmt"
+	"path"
+	"reflect"
+	"testing"
+	"time"
+
+	"golang.org/x/tools/internal/event/export/eventtest"
+	jsonrpc2 "golang.org/x/tools/internal/jsonrpc2_v2"
+	"golang.org/x/tools/internal/stack/stacktest"
+	errors "golang.org/x/xerrors"
+)
+
+var callTests = []invoker{
+	call{"no_args", nil, true},
+	call{"one_string", "fish", "got:fish"},
+	call{"one_number", 10, "got:10"},
+	call{"join", []string{"a", "b", "c"}, "a/b/c"},
+	sequence{"notify", []invoker{
+		notify{"set", 3},
+		notify{"add", 5},
+		call{"get", nil, 8},
+	}},
+	sequence{"preempt", []invoker{
+		async{"a", "wait", "a"},
+		notify{"unblock", "a"},
+		collect{"a", true, false},
+	}},
+	sequence{"basic cancel", []invoker{
+		async{"b", "wait", "b"},
+		cancel{"b"},
+		collect{"b", nil, true},
+	}},
+	sequence{"queue", []invoker{
+		async{"a", "wait", "a"},
+		notify{"set", 1},
+		notify{"add", 2},
+		notify{"add", 3},
+		notify{"add", 4},
+		call{"peek", nil, 0}, // accumulator will not have any adds yet
+		notify{"unblock", "a"},
+		collect{"a", true, false},
+		call{"get", nil, 10}, // accumulator now has all the adds
+	}},
+	sequence{"fork", []invoker{
+		async{"a", "fork", "a"},
+		notify{"set", 1},
+		notify{"add", 2},
+		notify{"add", 3},
+		notify{"add", 4},
+		call{"get", nil, 10}, // fork will not have blocked the adds
+		notify{"unblock", "a"},
+		collect{"a", true, false},
+	}},
+}
+
+type binder struct {
+	framer  jsonrpc2.Framer
+	runTest func(*handler)
+}
+
+type handler struct {
+	conn        *jsonrpc2.Connection
+	accumulator int
+	waitersBox  chan map[string]chan struct{}
+	calls       map[string]*jsonrpc2.AsyncCall
+}
+
+type invoker interface {
+	Name() string
+	Invoke(t *testing.T, ctx context.Context, h *handler)
+}
+
+type notify struct {
+	method string
+	params interface{}
+}
+
+type call struct {
+	method string
+	params interface{}
+	expect interface{}
+}
+
+type async struct {
+	name   string
+	method string
+	params interface{}
+}
+
+type collect struct {
+	name   string
+	expect interface{}
+	fails  bool
+}
+
+type cancel struct {
+	name string
+}
+
+type sequence struct {
+	name  string
+	tests []invoker
+}
+
+type echo call
+
+type cancelParams struct{ ID int64 }
+
+func TestConnectionRaw(t *testing.T) {
+	testConnection(t, jsonrpc2.RawFramer())
+}
+
+func TestConnectionHeader(t *testing.T) {
+	testConnection(t, jsonrpc2.HeaderFramer())
+}
+
+func testConnection(t *testing.T, framer jsonrpc2.Framer) {
+	stacktest.NoLeak(t)
+	ctx := eventtest.NewContext(context.Background(), t)
+	listener, err := jsonrpc2.NetPipe(ctx)
+	if err != nil {
+		t.Fatal(err)
+	}
+	server, err := jsonrpc2.Serve(ctx, listener, binder{framer, nil})
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer func() {
+		listener.Close()
+		server.Wait()
+	}()
+
+	for _, test := range callTests {
+		t.Run(test.Name(), func(t *testing.T) {
+			client, err := jsonrpc2.Dial(ctx,
+				listener.Dialer(), binder{framer, func(h *handler) {
+					defer h.conn.Close()
+					ctx := eventtest.NewContext(ctx, t)
+					test.Invoke(t, ctx, h)
+					if call, ok := test.(*call); ok {
+						// also run all simple call tests in echo mode
+						(*echo)(call).Invoke(t, ctx, h)
+					}
+				}})
+			if err != nil {
+				t.Fatal(err)
+			}
+			client.Wait()
+		})
+	}
+}
+
+func (test notify) Name() string { return test.method }
+func (test notify) Invoke(t *testing.T, ctx context.Context, h *handler) {
+	if err := h.conn.Notify(ctx, test.method, test.params); err != nil {
+		t.Fatalf("%v:Notify failed: %v", test.method, err)
+	}
+}
+
+func (test call) Name() string { return test.method }
+func (test call) Invoke(t *testing.T, ctx context.Context, h *handler) {
+	results := newResults(test.expect)
+	if err := h.conn.Call(ctx, test.method, test.params).Await(ctx, results); err != nil {
+		t.Fatalf("%v:Call failed: %v", test.method, err)
+	}
+	verifyResults(t, test.method, results, test.expect)
+}
+
+func (test echo) Invoke(t *testing.T, ctx context.Context, h *handler) {
+	results := newResults(test.expect)
+	if err := h.conn.Call(ctx, "echo", []interface{}{test.method, test.params}).Await(ctx, results); err != nil {
+		t.Fatalf("%v:Echo failed: %v", test.method, err)
+	}
+	verifyResults(t, test.method, results, test.expect)
+}
+
+func (test async) Name() string { return test.name }
+func (test async) Invoke(t *testing.T, ctx context.Context, h *handler) {
+	h.calls[test.name] = h.conn.Call(ctx, test.method, test.params)
+}
+
+func (test collect) Name() string { return test.name }
+func (test collect) Invoke(t *testing.T, ctx context.Context, h *handler) {
+	o := h.calls[test.name]
+	results := newResults(test.expect)
+	err := o.Await(ctx, results)
+	switch {
+	case test.fails && err == nil:
+		t.Fatalf("%v:Collect was supposed to fail", test.name)
+	case !test.fails && err != nil:
+		t.Fatalf("%v:Collect failed: %v", test.name, err)
+	}
+	verifyResults(t, test.name, results, test.expect)
+}
+
+func (test cancel) Name() string { return test.name }
+func (test cancel) Invoke(t *testing.T, ctx context.Context, h *handler) {
+	o := h.calls[test.name]
+	if err := h.conn.Notify(ctx, "cancel", &cancelParams{o.ID().Raw().(int64)}); err != nil {
+		t.Fatalf("%v:Collect failed: %v", test.name, err)
+	}
+}
+
+func (test sequence) Name() string { return test.name }
+func (test sequence) Invoke(t *testing.T, ctx context.Context, h *handler) {
+	for _, child := range test.tests {
+		child.Invoke(t, ctx, h)
+	}
+}
+
+// newResults makes a new empty copy of the expected type to put the results into
+func newResults(expect interface{}) interface{} {
+	switch e := expect.(type) {
+	case []interface{}:
+		var r []interface{}
+		for _, v := range e {
+			r = append(r, reflect.New(reflect.TypeOf(v)).Interface())
+		}
+		return r
+	case nil:
+		return nil
+	default:
+		return reflect.New(reflect.TypeOf(expect)).Interface()
+	}
+}
+
+// verifyResults compares the results to the expected values
+func verifyResults(t *testing.T, method string, results interface{}, expect interface{}) {
+	if expect == nil {
+		if results != nil {
+			t.Errorf("%v:Got results %+v where none expeted", method, expect)
+		}
+		return
+	}
+	val := reflect.Indirect(reflect.ValueOf(results)).Interface()
+	if !reflect.DeepEqual(val, expect) {
+		t.Errorf("%v:Results are incorrect, got %+v expect %+v", method, val, expect)
+	}
+}
+
+func (b binder) Bind(ctx context.Context, conn *jsonrpc2.Connection) (jsonrpc2.ConnectionOptions, error) {
+	h := &handler{
+		conn:       conn,
+		waitersBox: make(chan map[string]chan struct{}, 1),
+		calls:      make(map[string]*jsonrpc2.AsyncCall),
+	}
+	h.waitersBox <- make(map[string]chan struct{})
+	if b.runTest != nil {
+		go b.runTest(h)
+	}
+	return jsonrpc2.ConnectionOptions{
+		Framer:    b.framer,
+		Preempter: h,
+		Handler:   h,
+	}, nil
+}
+
+func (h *handler) waiter(name string) chan struct{} {
+	waiters := <-h.waitersBox
+	defer func() { h.waitersBox <- waiters }()
+	waiter, found := waiters[name]
+	if !found {
+		waiter = make(chan struct{})
+		waiters[name] = waiter
+	}
+	return waiter
+}
+
+func (h *handler) Preempt(ctx context.Context, req *jsonrpc2.Request) (interface{}, error) {
+	switch req.Method {
+	case "unblock":
+		var name string
+		if err := json.Unmarshal(req.Params, &name); err != nil {
+			return nil, errors.Errorf("%w: %s", jsonrpc2.ErrParse, err)
+		}
+		close(h.waiter(name))
+		return nil, nil
+	case "peek":
+		if len(req.Params) > 0 {
+			return nil, errors.Errorf("%w: expected no params", jsonrpc2.ErrInvalidParams)
+		}
+		return h.accumulator, nil
+	case "cancel":
+		var params cancelParams
+		if err := json.Unmarshal(req.Params, &params); err != nil {
+			return nil, errors.Errorf("%w: %s", jsonrpc2.ErrParse, err)
+		}
+		h.conn.Cancel(jsonrpc2.Int64ID(params.ID))
+		return nil, nil
+	default:
+		return nil, jsonrpc2.ErrNotHandled
+	}
+}
+
+func (h *handler) Handle(ctx context.Context, req *jsonrpc2.Request) (interface{}, error) {
+	switch req.Method {
+	case "no_args":
+		if len(req.Params) > 0 {
+			return nil, errors.Errorf("%w: expected no params", jsonrpc2.ErrInvalidParams)
+		}
+		return true, nil
+	case "one_string":
+		var v string
+		if err := json.Unmarshal(req.Params, &v); err != nil {
+			return nil, errors.Errorf("%w: %s", jsonrpc2.ErrParse, err)
+		}
+		return "got:" + v, nil
+	case "one_number":
+		var v int
+		if err := json.Unmarshal(req.Params, &v); err != nil {
+			return nil, errors.Errorf("%w: %s", jsonrpc2.ErrParse, err)
+		}
+		return fmt.Sprintf("got:%d", v), nil
+	case "set":
+		var v int
+		if err := json.Unmarshal(req.Params, &v); err != nil {
+			return nil, errors.Errorf("%w: %s", jsonrpc2.ErrParse, err)
+		}
+		h.accumulator = v
+		return nil, nil
+	case "add":
+		var v int
+		if err := json.Unmarshal(req.Params, &v); err != nil {
+			return nil, errors.Errorf("%w: %s", jsonrpc2.ErrParse, err)
+		}
+		h.accumulator += v
+		return nil, nil
+	case "get":
+		if len(req.Params) > 0 {
+			return nil, errors.Errorf("%w: expected no params", jsonrpc2.ErrInvalidParams)
+		}
+		return h.accumulator, nil
+	case "join":
+		var v []string
+		if err := json.Unmarshal(req.Params, &v); err != nil {
+			return nil, errors.Errorf("%w: %s", jsonrpc2.ErrParse, err)
+		}
+		return path.Join(v...), nil
+	case "echo":
+		var v []interface{}
+		if err := json.Unmarshal(req.Params, &v); err != nil {
+			return nil, errors.Errorf("%w: %s", jsonrpc2.ErrParse, err)
+		}
+		var result interface{}
+		err := h.conn.Call(ctx, v[0].(string), v[1]).Await(ctx, &result)
+		return result, err
+	case "wait":
+		var name string
+		if err := json.Unmarshal(req.Params, &name); err != nil {
+			return nil, errors.Errorf("%w: %s", jsonrpc2.ErrParse, err)
+		}
+		select {
+		case <-h.waiter(name):
+			return true, nil
+		case <-ctx.Done():
+			return nil, ctx.Err()
+		case <-time.After(time.Second):
+			return nil, errors.Errorf("wait for %q timed out", name)
+		}
+	case "fork":
+		var name string
+		if err := json.Unmarshal(req.Params, &name); err != nil {
+			return nil, errors.Errorf("%w: %s", jsonrpc2.ErrParse, err)
+		}
+		waitFor := h.waiter(name)
+		go func() {
+			select {
+			case <-waitFor:
+				h.conn.Respond(req.ID, true, nil)
+			case <-ctx.Done():
+				h.conn.Respond(req.ID, nil, ctx.Err())
+			case <-time.After(time.Second):
+				h.conn.Respond(req.ID, nil, errors.Errorf("wait for %q timed out", name))
+			}
+		}()
+		return nil, jsonrpc2.ErrAsyncResponse
+	default:
+		return nil, jsonrpc2.ErrNotHandled
+	}
+}
diff --git a/internal/jsonrpc2_v2/messages.go b/internal/jsonrpc2_v2/messages.go
new file mode 100644
index 0000000..652ac81
--- /dev/null
+++ b/internal/jsonrpc2_v2/messages.go
@@ -0,0 +1,181 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package jsonrpc2
+
+import (
+	"encoding/json"
+
+	errors "golang.org/x/xerrors"
+)
+
+// ID is a Request identifier.
+type ID struct {
+	value interface{}
+}
+
+// Message is the interface to all jsonrpc2 message types.
+// They share no common functionality, but are a closed set of concrete types
+// that are allowed to implement this interface. The message types are *Request
+// and *Response.
+type Message interface {
+	// marshal builds the wire form from the API form.
+	// It is private, which makes the set of Message implementations closed.
+	marshal(to *wireCombined)
+}
+
+// Request is a Message sent to a peer to request behavior.
+// If it has an ID it is a call, otherwise it is a notification.
+type Request struct {
+	// ID of this request, used to tie the Response back to the request.
+	// This will be nil for notifications.
+	ID ID
+	// Method is a string containing the method name to invoke.
+	Method string
+	// Params is either a struct or an array with the parameters of the method.
+	Params json.RawMessage
+}
+
+// Response is a Message used as a reply to a call Request.
+// It will have the same ID as the call it is a response to.
+type Response struct {
+	// result is the content of the response.
+	Result json.RawMessage
+	// err is set only if the call failed.
+	Error error
+	// id of the request this is a response to.
+	ID ID
+}
+
+// StringID creates a new string request identifier.
+func StringID(s string) ID { return ID{value: s} }
+
+// Int64ID creates a new integer request identifier.
+func Int64ID(i int64) ID { return ID{value: i} }
+
+// IsValid returns true if the ID is a valid identifier.
+// The default value for ID will return false.
+func (id ID) IsValid() bool { return id.value != nil }
+
+// Raw returns the underlying value of the ID.
+func (id ID) Raw() interface{} { return id.value }
+
+// NewNotification constructs a new Notification message for the supplied
+// method and parameters.
+func NewNotification(method string, params interface{}) (*Request, error) {
+	p, merr := marshalToRaw(params)
+	return &Request{Method: method, Params: p}, merr
+}
+
+// NewCall constructs a new Call message for the supplied ID, method and
+// parameters.
+func NewCall(id ID, method string, params interface{}) (*Request, error) {
+	p, merr := marshalToRaw(params)
+	return &Request{ID: id, Method: method, Params: p}, merr
+}
+
+func (msg *Request) IsCall() bool { return msg.ID.IsValid() }
+
+func (msg *Request) marshal(to *wireCombined) {
+	to.ID = msg.ID.value
+	to.Method = msg.Method
+	to.Params = msg.Params
+}
+
+// NewResponse constructs a new Response message that is a reply to the
+// supplied. If err is set result may be ignored.
+func NewResponse(id ID, result interface{}, rerr error) (*Response, error) {
+	r, merr := marshalToRaw(result)
+	return &Response{ID: id, Result: r, Error: rerr}, merr
+}
+
+func (msg *Response) marshal(to *wireCombined) {
+	to.ID = msg.ID.value
+	to.Error = toWireError(msg.Error)
+	to.Result = msg.Result
+}
+
+func toWireError(err error) *wireError {
+	if err == nil {
+		// no error, the response is complete
+		return nil
+	}
+	if err, ok := err.(*wireError); ok {
+		// already a wire error, just use it
+		return err
+	}
+	result := &wireError{Message: err.Error()}
+	var wrapped *wireError
+	if errors.As(err, &wrapped) {
+		// if we wrapped a wire error, keep the code from the wrapped error
+		// but the message from the outer error
+		result.Code = wrapped.Code
+	}
+	return result
+}
+
+func EncodeMessage(msg Message) ([]byte, error) {
+	wire := wireCombined{VersionTag: wireVersion}
+	msg.marshal(&wire)
+	data, err := json.Marshal(&wire)
+	if err != nil {
+		return data, errors.Errorf("marshaling jsonrpc message: %w", err)
+	}
+	return data, nil
+}
+
+func DecodeMessage(data []byte) (Message, error) {
+	msg := wireCombined{}
+	if err := json.Unmarshal(data, &msg); err != nil {
+		return nil, errors.Errorf("unmarshaling jsonrpc message: %w", err)
+	}
+	if msg.VersionTag != wireVersion {
+		return nil, errors.Errorf("invalid message version tag %s expected %s", msg.VersionTag, wireVersion)
+	}
+	id := ID{}
+	switch v := msg.ID.(type) {
+	case nil:
+	case float64:
+		// coerce the id type to int64 if it is float64, the spec does not allow fractional parts
+		id = Int64ID(int64(v))
+	case int64:
+		id = Int64ID(v)
+	case string:
+		id = StringID(v)
+	default:
+		return nil, errors.Errorf("invalid message id type <%T>%v", v, v)
+	}
+	if msg.Method != "" {
+		// has a method, must be a call
+		return &Request{
+			Method: msg.Method,
+			ID:     id,
+			Params: msg.Params,
+		}, nil
+	}
+	// no method, should be a response
+	if !id.IsValid() {
+		return nil, ErrInvalidRequest
+	}
+	resp := &Response{
+		ID:     id,
+		Result: msg.Result,
+	}
+	// we have to check if msg.Error is nil to avoid a typed error
+	if msg.Error != nil {
+		resp.Error = msg.Error
+	}
+	return resp, nil
+}
+
+func marshalToRaw(obj interface{}) (json.RawMessage, error) {
+	if obj == nil {
+		return nil, nil
+	}
+	data, err := json.Marshal(obj)
+	if err != nil {
+		return nil, err
+	}
+	return json.RawMessage(data), nil
+}
diff --git a/internal/jsonrpc2_v2/net.go b/internal/jsonrpc2_v2/net.go
new file mode 100644
index 0000000..c8cfaab
--- /dev/null
+++ b/internal/jsonrpc2_v2/net.go
@@ -0,0 +1,129 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package jsonrpc2
+
+import (
+	"context"
+	"io"
+	"net"
+	"os"
+	"time"
+)
+
+// This file contains implementations of the transport primitives that use the standard network
+// package.
+
+// NetListenOptions is the optional arguments to the NetListen function.
+type NetListenOptions struct {
+	NetListenConfig net.ListenConfig
+	NetDialer       net.Dialer
+}
+
+// NetListener returns a new Listener that listents on a socket using the net package.
+func NetListener(ctx context.Context, network, address string, options NetListenOptions) (Listener, error) {
+	ln, err := options.NetListenConfig.Listen(ctx, network, address)
+	if err != nil {
+		return nil, err
+	}
+	return &netListener{net: ln}, nil
+}
+
+// netListener is the implementation of Listener for connections made using the net package.
+type netListener struct {
+	net net.Listener
+}
+
+// Accept blocks waiting for an incoming connection to the listener.
+func (l *netListener) Accept(ctx context.Context) (io.ReadWriteCloser, error) {
+	return l.net.Accept()
+}
+
+// Close will cause the listener to stop listening. It will not close any connections that have
+// already been accepted.
+func (l *netListener) Close() error {
+	addr := l.net.Addr()
+	err := l.net.Close()
+	if addr.Network() == "unix" {
+		rerr := os.Remove(addr.String())
+		if rerr != nil && err == nil {
+			err = rerr
+		}
+	}
+	return err
+}
+
+// Dialer returns a dialer that can be used to connect to the listener.
+func (l *netListener) Dialer() Dialer {
+	return NetDialer(l.net.Addr().Network(), l.net.Addr().String(), net.Dialer{
+		Timeout: 5 * time.Second,
+	})
+}
+
+// NetDialer returns a Dialer using the supplied standard network dialer.
+func NetDialer(network, address string, nd net.Dialer) Dialer {
+	return &netDialer{
+		network: network,
+		address: address,
+		dialer:  nd,
+	}
+}
+
+type netDialer struct {
+	network string
+	address string
+	dialer  net.Dialer
+}
+
+func (n *netDialer) Dial(ctx context.Context) (io.ReadWriteCloser, error) {
+	return n.dialer.DialContext(ctx, n.network, n.address)
+}
+
+// NetPipe returns a new Listener that listens using net.Pipe.
+// It is only possibly to connect to it using the Dialier returned by the
+// Dialer method, each call to that method will generate a new pipe the other
+// side of which will be returnd from the Accept call.
+func NetPipe(ctx context.Context) (Listener, error) {
+	return &netPiper{
+		done:   make(chan struct{}),
+		dialed: make(chan io.ReadWriteCloser),
+	}, nil
+}
+
+// netPiper is the implementation of Listener build on top of net.Pipes.
+type netPiper struct {
+	done   chan struct{}
+	dialed chan io.ReadWriteCloser
+}
+
+// Accept blocks waiting for an incoming connection to the listener.
+func (l *netPiper) Accept(ctx context.Context) (io.ReadWriteCloser, error) {
+	// block until we have a listener, or are closed or cancelled
+	select {
+	case rwc := <-l.dialed:
+		return rwc, nil
+	case <-l.done:
+		return nil, io.EOF
+	case <-ctx.Done():
+		return nil, ctx.Err()
+	}
+}
+
+// Close will cause the listener to stop listening. It will not close any connections that have
+// already been accepted.
+func (l *netPiper) Close() error {
+	// unblock any accept calls that are pending
+	close(l.done)
+	return nil
+}
+
+func (l *netPiper) Dialer() Dialer {
+	return l
+}
+
+func (l *netPiper) Dial(ctx context.Context) (io.ReadWriteCloser, error) {
+	client, server := net.Pipe()
+	l.dialed <- server
+	return client, nil
+}
diff --git a/internal/jsonrpc2_v2/serve.go b/internal/jsonrpc2_v2/serve.go
new file mode 100644
index 0000000..78259b1
--- /dev/null
+++ b/internal/jsonrpc2_v2/serve.go
@@ -0,0 +1,265 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package jsonrpc2
+
+import (
+	"context"
+	"io"
+	"sync"
+	"time"
+
+	errors "golang.org/x/xerrors"
+)
+
+// Listener is implemented by protocols to accept new inbound connections.
+type Listener interface {
+	// Accept an inbound connection to a server.
+	// It must block until an inbound connection is made, or the listener is
+	// shut down.
+	Accept(context.Context) (io.ReadWriteCloser, error)
+
+	// Close is used to ask a listener to stop accepting new connections.
+	Close() error
+
+	// Dialer returns a dialer that can be used to connect to this listener
+	// locally.
+	// If a listener does not implement this it will return a nil.
+	Dialer() Dialer
+}
+
+// Dialer is used by clients to dial a server.
+type Dialer interface {
+	// Dial returns a new communication byte stream to a listening server.
+	Dial(ctx context.Context) (io.ReadWriteCloser, error)
+}
+
+// Server is a running server that is accepting incoming connections.
+type Server struct {
+	listener Listener
+	binder   Binder
+	async    async
+}
+
+// Dial uses the dialer to make a new connection, wraps the returned
+// reader and writer using the framer to make a stream, and then builds
+// a connection on top of that stream using the binder.
+func Dial(ctx context.Context, dialer Dialer, binder Binder) (*Connection, error) {
+	// dial a server
+	rwc, err := dialer.Dial(ctx)
+	if err != nil {
+		return nil, err
+	}
+	return newConnection(ctx, rwc, binder)
+}
+
+// Serve starts a new server listening for incoming connections and returns
+// it.
+// This returns a fully running and connected server, it does not block on
+// the listener.
+// You can call Wait to block on the server, or Shutdown to get the sever to
+// terminate gracefully.
+// To notice incoming connections, use an intercepting Binder.
+func Serve(ctx context.Context, listener Listener, binder Binder) (*Server, error) {
+	server := &Server{
+		listener: listener,
+		binder:   binder,
+	}
+	server.async.init()
+	go server.run(ctx)
+	return server, nil
+}
+
+// Wait returns only when the server has shut down.
+func (s *Server) Wait() error {
+	return s.async.wait()
+}
+
+// run accepts incoming connections from the listener,
+// If IdleTimeout is non-zero, run exits after there are no clients for this
+// duration, otherwise it exits only on error.
+func (s *Server) run(ctx context.Context) {
+	defer s.async.done()
+	var activeConns []*Connection
+	for {
+		// we never close the accepted connection, we rely on the other end
+		// closing or the socket closing itself naturally
+		rwc, err := s.listener.Accept(ctx)
+		if err != nil {
+			if !isClosingError(err) {
+				s.async.setError(err)
+			}
+			// we are done generating new connections for good
+			break
+		}
+
+		// see if any connections were closed while we were waiting
+		activeConns = onlyActive(activeConns)
+
+		// a new inbound connection,
+		conn, err := newConnection(ctx, rwc, s.binder)
+		if err != nil {
+			if !isClosingError(err) {
+				s.async.setError(err)
+			}
+			continue
+		}
+		activeConns = append(activeConns, conn)
+	}
+
+	// wait for all active conns to finish
+	for _, c := range activeConns {
+		c.Wait()
+	}
+}
+
+func onlyActive(conns []*Connection) []*Connection {
+	i := 0
+	for _, c := range conns {
+		if !c.async.isDone() {
+			conns[i] = c
+			i++
+		}
+	}
+	// trim the slice down
+	return conns[:i]
+}
+
+// isClosingError reports if the error occurs normally during the process of
+// closing a network connection. It uses imperfect heuristics that err on the
+// side of false negatives, and should not be used for anything critical.
+func isClosingError(err error) bool {
+	if err == nil {
+		return false
+	}
+	// fully unwrap the error, so the following tests work
+	for wrapped := err; wrapped != nil; wrapped = errors.Unwrap(err) {
+		err = wrapped
+	}
+
+	// was it based on an EOF error?
+	if err == io.EOF {
+		return true
+	}
+
+	// Per https://github.com/golang/go/issues/4373, this error string should not
+	// change. This is not ideal, but since the worst that could happen here is
+	// some superfluous logging, it is acceptable.
+	if err.Error() == "use of closed network connection" {
+		return true
+	}
+
+	return false
+}
+
+// NewIdleListener wraps a listener with an idle timeout.
+// When there are no active connections for at least the timeout duration a
+// call to accept will fail with ErrIdleTimeout.
+func NewIdleListener(timeout time.Duration, wrap Listener) Listener {
+	l := &idleListener{
+		timeout:    timeout,
+		wrapped:    wrap,
+		newConns:   make(chan *idleCloser),
+		closed:     make(chan struct{}),
+		wasTimeout: make(chan struct{}),
+	}
+	go l.run()
+	return l
+}
+
+type idleListener struct {
+	wrapped    Listener
+	timeout    time.Duration
+	newConns   chan *idleCloser
+	closed     chan struct{}
+	wasTimeout chan struct{}
+	closeOnce  sync.Once
+}
+
+type idleCloser struct {
+	wrapped   io.ReadWriteCloser
+	closed    chan struct{}
+	closeOnce sync.Once
+}
+
+func (c *idleCloser) Read(p []byte) (int, error) {
+	n, err := c.wrapped.Read(p)
+	if err != nil && isClosingError(err) {
+		c.closeOnce.Do(func() { close(c.closed) })
+	}
+	return n, err
+}
+
+func (c *idleCloser) Write(p []byte) (int, error) {
+	// we do not close on write failure, we rely on the wrapped writer to do that
+	// if it is appropriate, which we will detect in the next read.
+	return c.wrapped.Write(p)
+}
+
+func (c *idleCloser) Close() error {
+	// we rely on closing the wrapped stream to signal to the next read that we
+	// are closed, rather than triggering the closed signal directly
+	return c.wrapped.Close()
+}
+
+func (l *idleListener) Accept(ctx context.Context) (io.ReadWriteCloser, error) {
+	rwc, err := l.wrapped.Accept(ctx)
+	if err != nil {
+		if isClosingError(err) {
+			// underlying listener was closed
+			l.closeOnce.Do(func() { close(l.closed) })
+			// was it closed because of the idle timeout?
+			select {
+			case <-l.wasTimeout:
+				err = ErrIdleTimeout
+			default:
+			}
+		}
+		return nil, err
+	}
+	conn := &idleCloser{
+		wrapped: rwc,
+		closed:  make(chan struct{}),
+	}
+	l.newConns <- conn
+	return conn, err
+}
+
+func (l *idleListener) Close() error {
+	defer l.closeOnce.Do(func() { close(l.closed) })
+	return l.wrapped.Close()
+}
+
+func (l *idleListener) Dialer() Dialer {
+	return l.wrapped.Dialer()
+}
+
+func (l *idleListener) run() {
+	var conns []*idleCloser
+	for {
+		var firstClosed chan struct{} // left at nil if there are no active conns
+		var timeout <-chan time.Time  // left at nil if there are  active conns
+		if len(conns) > 0 {
+			firstClosed = conns[0].closed
+		} else {
+			timeout = time.After(l.timeout)
+		}
+		select {
+		case <-l.closed:
+			// the main listener closed, no need to keep going
+			return
+		case conn := <-l.newConns:
+			// a new conn arrived, add it to the list
+			conns = append(conns, conn)
+		case <-timeout:
+			// we timed out, only happens when there are no active conns
+			// close the underlying listener, and allow the normal closing process to happen
+			close(l.wasTimeout)
+			l.wrapped.Close()
+		case <-firstClosed:
+			// a conn closed, remove it from the active list
+			conns = conns[:copy(conns, conns[1:])]
+		}
+	}
+}
diff --git a/internal/jsonrpc2_v2/serve_test.go b/internal/jsonrpc2_v2/serve_test.go
new file mode 100644
index 0000000..22f18cd
--- /dev/null
+++ b/internal/jsonrpc2_v2/serve_test.go
@@ -0,0 +1,140 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package jsonrpc2_test
+
+import (
+	"context"
+	"errors"
+	"testing"
+	"time"
+
+	jsonrpc2 "golang.org/x/tools/internal/jsonrpc2_v2"
+	"golang.org/x/tools/internal/stack/stacktest"
+)
+
+func TestIdleTimeout(t *testing.T) {
+	stacktest.NoLeak(t)
+	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+	defer cancel()
+
+	listener, err := jsonrpc2.NetListener(ctx, "tcp", "localhost:0", jsonrpc2.NetListenOptions{})
+	if err != nil {
+		t.Fatal(err)
+	}
+	listener = jsonrpc2.NewIdleListener(100*time.Millisecond, listener)
+	defer listener.Close()
+	server, err := jsonrpc2.Serve(ctx, listener, jsonrpc2.ConnectionOptions{})
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	connect := func() *jsonrpc2.Connection {
+		client, err := jsonrpc2.Dial(ctx,
+			listener.Dialer(),
+			jsonrpc2.ConnectionOptions{})
+		if err != nil {
+			t.Fatal(err)
+		}
+		return client
+	}
+	// Exercise some connection/disconnection patterns, and then assert that when
+	// our timer fires, the server exits.
+	conn1 := connect()
+	conn2 := connect()
+	if err := conn1.Close(); err != nil {
+		t.Fatalf("conn1.Close failed with error: %v", err)
+	}
+	if err := conn2.Close(); err != nil {
+		t.Fatalf("conn2.Close failed with error: %v", err)
+	}
+	conn3 := connect()
+	if err := conn3.Close(); err != nil {
+		t.Fatalf("conn3.Close failed with error: %v", err)
+	}
+
+	serverError := server.Wait()
+
+	if !errors.Is(serverError, jsonrpc2.ErrIdleTimeout) {
+		t.Errorf("run() returned error %v, want %v", serverError, jsonrpc2.ErrIdleTimeout)
+	}
+}
+
+type msg struct {
+	Msg string
+}
+
+type fakeHandler struct{}
+
+func (fakeHandler) Handle(ctx context.Context, req *jsonrpc2.Request) (interface{}, error) {
+	switch req.Method {
+	case "ping":
+		return &msg{"pong"}, nil
+	default:
+		return nil, jsonrpc2.ErrNotHandled
+	}
+}
+
+func TestServe(t *testing.T) {
+	stacktest.NoLeak(t)
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+	defer cancel()
+
+	tests := []struct {
+		name    string
+		factory func(context.Context) (jsonrpc2.Listener, error)
+	}{
+		{"tcp", func(ctx context.Context) (jsonrpc2.Listener, error) {
+			return jsonrpc2.NetListener(ctx, "tcp", "localhost:0", jsonrpc2.NetListenOptions{})
+		}},
+		{"pipe", func(ctx context.Context) (jsonrpc2.Listener, error) {
+			return jsonrpc2.NetPipe(ctx)
+		}},
+	}
+
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			fake, err := test.factory(ctx)
+			if err != nil {
+				t.Fatal(err)
+			}
+			conn, shutdown, err := newFake(ctx, fake)
+			if err != nil {
+				t.Fatal(err)
+			}
+			defer shutdown(ctx)
+			var got msg
+			if err := conn.Call(ctx, "ping", &msg{"ting"}).Await(ctx, &got); err != nil {
+				t.Fatal(err)
+			}
+			if want := "pong"; got.Msg != want {
+				t.Errorf("conn.Call(...): returned %q, want %q", got, want)
+			}
+		})
+	}
+}
+
+func newFake(ctx context.Context, l jsonrpc2.Listener) (*jsonrpc2.Connection, func(context.Context), error) {
+	l = jsonrpc2.NewIdleListener(100*time.Millisecond, l)
+	server, err := jsonrpc2.Serve(ctx, l, jsonrpc2.ConnectionOptions{
+		Handler: fakeHandler{},
+	})
+	if err != nil {
+		return nil, nil, err
+	}
+
+	client, err := jsonrpc2.Dial(ctx,
+		l.Dialer(),
+		jsonrpc2.ConnectionOptions{
+			Handler: fakeHandler{},
+		})
+	if err != nil {
+		return nil, nil, err
+	}
+	return client, func(ctx context.Context) {
+		l.Close()
+		client.Close()
+		server.Wait()
+	}, nil
+}
diff --git a/internal/jsonrpc2_v2/wire.go b/internal/jsonrpc2_v2/wire.go
new file mode 100644
index 0000000..97b1ae8
--- /dev/null
+++ b/internal/jsonrpc2_v2/wire.go
@@ -0,0 +1,74 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package jsonrpc2
+
+import (
+	"encoding/json"
+)
+
+// This file contains the go forms of the wire specification.
+// see http://www.jsonrpc.org/specification for details
+
+var (
+	// ErrUnknown should be used for all non coded errors.
+	ErrUnknown = NewError(-32001, "JSON RPC unknown error")
+	// ErrParse is used when invalid JSON was received by the server.
+	ErrParse = NewError(-32700, "JSON RPC parse error")
+	// ErrInvalidRequest is used when the JSON sent is not a valid Request object.
+	ErrInvalidRequest = NewError(-32600, "JSON RPC invalid request")
+	// ErrMethodNotFound should be returned by the handler when the method does
+	// not exist / is not available.
+	ErrMethodNotFound = NewError(-32601, "JSON RPC method not found")
+	// ErrInvalidParams should be returned by the handler when method
+	// parameter(s) were invalid.
+	ErrInvalidParams = NewError(-32602, "JSON RPC invalid params")
+	// ErrInternal indicates a failure to process a call correctly
+	ErrInternal = NewError(-32603, "JSON RPC internal error")
+
+	// The following errors are not part of the json specification, but
+	// compliant extensions specific to this implimentation.
+
+	// ErrServerOverloaded is returned when a message was refused due to a
+	// server being temporarily unable to accept any new messages.
+	ErrServerOverloaded = NewError(-32000, "JSON RPC overloaded")
+)
+
+const wireVersion = "2.0"
+
+// wireCombined has all the fields of both Request and Response.
+// We can decode this and then work out which it is.
+type wireCombined struct {
+	VersionTag string          `json:"jsonrpc"`
+	ID         interface{}     `json:"id,omitempty"`
+	Method     string          `json:"method,omitempty"`
+	Params     json.RawMessage `json:"params,omitempty"`
+	Result     json.RawMessage `json:"result,omitempty"`
+	Error      *wireError      `json:"error,omitempty"`
+}
+
+// wireError represents a structured error in a Response.
+type wireError struct {
+	// Code is an error code indicating the type of failure.
+	Code int64 `json:"code"`
+	// Message is a short description of the error.
+	Message string `json:"message"`
+	// Data is optional structured data containing additional information about the error.
+	Data json.RawMessage `json:"data,omitempty"`
+}
+
+// NewError returns an error that will encode on the wire correctly.
+// The standard codes are made available from this package, this function should
+// only be used to build errors for application specific codes as allowed by the
+// specification.
+func NewError(code int64, message string) error {
+	return &wireError{
+		Code:    code,
+		Message: message,
+	}
+}
+
+func (err *wireError) Error() string {
+	return err.Message
+}
diff --git a/internal/jsonrpc2_v2/wire_test.go b/internal/jsonrpc2_v2/wire_test.go
new file mode 100644
index 0000000..e933737
--- /dev/null
+++ b/internal/jsonrpc2_v2/wire_test.go
@@ -0,0 +1,118 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package jsonrpc2_test
+
+import (
+	"bytes"
+	"encoding/json"
+	"reflect"
+	"testing"
+
+	jsonrpc2 "golang.org/x/tools/internal/jsonrpc2_v2"
+)
+
+func TestWireMessage(t *testing.T) {
+	for _, test := range []struct {
+		name    string
+		msg     jsonrpc2.Message
+		encoded []byte
+	}{{
+		name:    "notification",
+		msg:     newNotification("alive", nil),
+		encoded: []byte(`{"jsonrpc":"2.0","method":"alive"}`),
+	}, {
+		name:    "call",
+		msg:     newCall("msg1", "ping", nil),
+		encoded: []byte(`{"jsonrpc":"2.0","id":"msg1","method":"ping"}`),
+	}, {
+		name:    "response",
+		msg:     newResponse("msg2", "pong", nil),
+		encoded: []byte(`{"jsonrpc":"2.0","id":"msg2","result":"pong"}`),
+	}, {
+		name:    "numerical id",
+		msg:     newCall(1, "poke", nil),
+		encoded: []byte(`{"jsonrpc":"2.0","id":1,"method":"poke"}`),
+	}, {
+		// originally reported in #39719, this checks that result is not present if
+		// it is an error response
+		name: "computing fix edits",
+		msg:  newResponse(3, nil, jsonrpc2.NewError(0, "computing fix edits")),
+		encoded: []byte(`{
+		"jsonrpc":"2.0",
+		"id":3,
+		"error":{
+			"code":0,
+			"message":"computing fix edits"
+		}
+	}`),
+	}} {
+		b, err := jsonrpc2.EncodeMessage(test.msg)
+		if err != nil {
+			t.Fatal(err)
+		}
+		checkJSON(t, b, test.encoded)
+		msg, err := jsonrpc2.DecodeMessage(test.encoded)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if !reflect.DeepEqual(msg, test.msg) {
+			t.Errorf("decoded message does not match\nGot:\n%+#v\nWant:\n%+#v", msg, test.msg)
+		}
+	}
+}
+
+func newNotification(method string, params interface{}) jsonrpc2.Message {
+	msg, err := jsonrpc2.NewNotification(method, params)
+	if err != nil {
+		panic(err)
+	}
+	return msg
+}
+
+func newID(id interface{}) jsonrpc2.ID {
+	switch v := id.(type) {
+	case nil:
+		return jsonrpc2.ID{}
+	case string:
+		return jsonrpc2.StringID(v)
+	case int:
+		return jsonrpc2.Int64ID(int64(v))
+	case int64:
+		return jsonrpc2.Int64ID(v)
+	default:
+		panic("invalid ID type")
+	}
+}
+
+func newCall(id interface{}, method string, params interface{}) jsonrpc2.Message {
+	msg, err := jsonrpc2.NewCall(newID(id), method, params)
+	if err != nil {
+		panic(err)
+	}
+	return msg
+}
+
+func newResponse(id interface{}, result interface{}, rerr error) jsonrpc2.Message {
+	msg, err := jsonrpc2.NewResponse(newID(id), result, rerr)
+	if err != nil {
+		panic(err)
+	}
+	return msg
+}
+
+func checkJSON(t *testing.T, got, want []byte) {
+	// compare the compact form, to allow for formatting differences
+	g := &bytes.Buffer{}
+	if err := json.Compact(g, []byte(got)); err != nil {
+		t.Fatal(err)
+	}
+	w := &bytes.Buffer{}
+	if err := json.Compact(w, []byte(want)); err != nil {
+		t.Fatal(err)
+	}
+	if g.String() != w.String() {
+		t.Errorf("encoded message does not match\nGot:\n%s\nWant:\n%s", g, w)
+	}
+}
diff --git a/internal/lsp/cache/analysis.go b/internal/lsp/cache/analysis.go
index 19675af..e3d7443 100644
--- a/internal/lsp/cache/analysis.go
+++ b/internal/lsp/cache/analysis.go
@@ -351,7 +351,7 @@
 	}
 
 	for _, diag := range diagnostics {
-		srcDiags, err := analysisDiagnosticDiagnostics(ctx, snapshot, pkg, analyzer, diag)
+		srcDiags, err := analysisDiagnosticDiagnostics(snapshot, pkg, analyzer, diag)
 		if err != nil {
 			event.Error(ctx, "unable to compute analysis error position", err, tag.Category.Of(diag.Category), tag.Package.Of(pkg.ID()))
 			continue
@@ -423,6 +423,7 @@
 				clone := *diag
 				clone.SuggestedFixes = eaDiag.SuggestedFixes
 				clone.Tags = eaDiag.Tags
+				clone.Analyzer = eaDiag.Analyzer
 				diag = &clone
 			}
 		}
diff --git a/internal/lsp/cache/cache.go b/internal/lsp/cache/cache.go
index fa1b530..7221874 100644
--- a/internal/lsp/cache/cache.go
+++ b/internal/lsp/cache/cache.go
@@ -29,7 +29,7 @@
 	"golang.org/x/tools/internal/span"
 )
 
-func New(ctx context.Context, options func(*source.Options)) *Cache {
+func New(options func(*source.Options)) *Cache {
 	index := atomic.AddInt64(&cacheIndex, 1)
 	c := &Cache{
 		id:          strconv.FormatInt(index, 10),
@@ -270,7 +270,7 @@
 		return 0
 	}
 	var count int64
-	ast.Inspect(f, func(n ast.Node) bool {
+	ast.Inspect(f, func(_ ast.Node) bool {
 		count += 32 // nodes are pretty small.
 		return true
 	})
diff --git a/internal/lsp/cache/check.go b/internal/lsp/cache/check.go
index 9df626b..65c3371 100644
--- a/internal/lsp/cache/check.go
+++ b/internal/lsp/cache/check.go
@@ -55,6 +55,26 @@
 	}
 }
 
+func (ph *packageHandle) imports(ctx context.Context, s source.Snapshot) (result []string) {
+	for _, pgh := range ph.goFiles {
+		f, err := s.ParseGo(ctx, pgh.file, source.ParseHeader)
+		if err != nil {
+			continue
+		}
+		seen := map[string]struct{}{}
+		for _, impSpec := range f.File.Imports {
+			imp := strings.Trim(impSpec.Path.Value, `"`)
+			if _, ok := seen[imp]; !ok {
+				seen[imp] = struct{}{}
+				result = append(result, imp)
+			}
+		}
+	}
+
+	sort.Strings(result)
+	return result
+}
+
 // packageData contains the data produced by type-checking a package.
 type packageData struct {
 	pkg *pkg
@@ -162,7 +182,7 @@
 		depKeys = append(depKeys, depHandle.key)
 	}
 	experimentalKey := s.View().Options().ExperimentalPackageCacheKey
-	ph.key = checkPackageKey(ctx, ph.m.id, compiledGoFiles, m.config, depKeys, mode, experimentalKey)
+	ph.key = checkPackageKey(ph.m.id, compiledGoFiles, m.config, depKeys, mode, experimentalKey)
 	return ph, deps, nil
 }
 
@@ -174,7 +194,7 @@
 	}
 }
 
-func checkPackageKey(ctx context.Context, id packageID, pghs []*parseGoHandle, cfg *packages.Config, deps []packageHandleKey, mode source.ParseMode, experimentalKey bool) packageHandleKey {
+func checkPackageKey(id packageID, pghs []*parseGoHandle, cfg *packages.Config, deps []packageHandleKey, mode source.ParseMode, experimentalKey bool) packageHandleKey {
 	b := bytes.NewBuffer(nil)
 	b.WriteString(string(id))
 	if !experimentalKey {
@@ -381,7 +401,7 @@
 		// Try to attach error messages to the file as much as possible.
 		var found bool
 		for _, e := range m.errors {
-			srcDiags, err := goPackagesErrorDiagnostics(ctx, snapshot, pkg, e)
+			srcDiags, err := goPackagesErrorDiagnostics(snapshot, pkg, e)
 			if err != nil {
 				continue
 			}
@@ -443,7 +463,7 @@
 	if len(m.errors) != 0 {
 		pkg.hasListOrParseErrors = true
 		for _, e := range m.errors {
-			diags, err := goPackagesErrorDiagnostics(ctx, snapshot, pkg, e)
+			diags, err := goPackagesErrorDiagnostics(snapshot, pkg, e)
 			if err != nil {
 				event.Error(ctx, "unable to compute positions for list errors", err, tag.Package.Of(pkg.ID()))
 				continue
@@ -468,7 +488,7 @@
 	if len(parseErrors) != 0 {
 		pkg.hasListOrParseErrors = true
 		for _, e := range parseErrors {
-			diags, err := parseErrorDiagnostics(ctx, snapshot, pkg, e)
+			diags, err := parseErrorDiagnostics(snapshot, pkg, e)
 			if err != nil {
 				event.Error(ctx, "unable to compute positions for parse errors", err, tag.Package.Of(pkg.ID()))
 				continue
@@ -486,7 +506,7 @@
 
 	for _, e := range expandErrors(typeErrors, snapshot.View().Options().RelatedInformationSupported) {
 		pkg.hasTypeErrors = true
-		diags, err := typeErrorDiagnostics(ctx, snapshot, pkg, e)
+		diags, err := typeErrorDiagnostics(snapshot, pkg, e)
 		if err != nil {
 			event.Error(ctx, "unable to compute positions for type errors", err, tag.Package.Of(pkg.ID()))
 			continue
@@ -764,7 +784,7 @@
 	if i == -1 {
 		return true
 	}
-	if pkgPath == "command-line-arguments" {
+	if isCommandLineArguments(string(pkgPath)) {
 		return true
 	}
 	return strings.HasPrefix(string(pkgPath), string(importPkgPath[:i]))
diff --git a/internal/lsp/cache/errors.go b/internal/lsp/cache/errors.go
index f18d5ed..9d109de 100644
--- a/internal/lsp/cache/errors.go
+++ b/internal/lsp/cache/errors.go
@@ -5,7 +5,6 @@
 package cache
 
 import (
-	"context"
 	"fmt"
 	"go/scanner"
 	"go/token"
@@ -25,9 +24,9 @@
 	errors "golang.org/x/xerrors"
 )
 
-func goPackagesErrorDiagnostics(ctx context.Context, snapshot *snapshot, pkg *pkg, e packages.Error) ([]*source.Diagnostic, error) {
-	if msg, spn, ok := parseGoListImportCycleError(ctx, snapshot, e, pkg); ok {
-		rng, err := spanToRange(snapshot, pkg, spn)
+func goPackagesErrorDiagnostics(snapshot *snapshot, pkg *pkg, e packages.Error) ([]*source.Diagnostic, error) {
+	if msg, spn, ok := parseGoListImportCycleError(snapshot, e, pkg); ok {
+		rng, err := spanToRange(pkg, spn)
 		if err != nil {
 			return nil, err
 		}
@@ -44,7 +43,7 @@
 	if e.Pos == "" {
 		spn = parseGoListError(e.Msg, pkg.m.config.Dir)
 		// We may not have been able to parse a valid span. Apply the errors to all files.
-		if _, err := spanToRange(snapshot, pkg, spn); err != nil {
+		if _, err := spanToRange(pkg, spn); err != nil {
 			var diags []*source.Diagnostic
 			for _, cgf := range pkg.compiledGoFiles {
 				diags = append(diags, &source.Diagnostic{
@@ -60,7 +59,7 @@
 		spn = span.ParseInDir(e.Pos, pkg.m.config.Dir)
 	}
 
-	rng, err := spanToRange(snapshot, pkg, spn)
+	rng, err := spanToRange(pkg, spn)
 	if err != nil {
 		return nil, err
 	}
@@ -73,7 +72,7 @@
 	}}, nil
 }
 
-func parseErrorDiagnostics(ctx context.Context, snapshot *snapshot, pkg *pkg, errList scanner.ErrorList) ([]*source.Diagnostic, error) {
+func parseErrorDiagnostics(snapshot *snapshot, pkg *pkg, errList scanner.ErrorList) ([]*source.Diagnostic, error) {
 	// The first parser error is likely the root cause of the problem.
 	if errList.Len() <= 0 {
 		return nil, errors.Errorf("no errors in %v", errList)
@@ -88,7 +87,7 @@
 	if err != nil {
 		return nil, err
 	}
-	rng, err := spanToRange(snapshot, pkg, spn)
+	rng, err := spanToRange(pkg, spn)
 	if err != nil {
 		return nil, err
 	}
@@ -103,12 +102,12 @@
 
 var importErrorRe = regexp.MustCompile(`could not import ([^\s]+)`)
 
-func typeErrorDiagnostics(ctx context.Context, snapshot *snapshot, pkg *pkg, e extendedError) ([]*source.Diagnostic, error) {
+func typeErrorDiagnostics(snapshot *snapshot, pkg *pkg, e extendedError) ([]*source.Diagnostic, error) {
 	code, spn, err := typeErrorData(snapshot.FileSet(), pkg, e.primary)
 	if err != nil {
 		return nil, err
 	}
-	rng, err := spanToRange(snapshot, pkg, spn)
+	rng, err := spanToRange(pkg, spn)
 	if err != nil {
 		return nil, err
 	}
@@ -129,7 +128,7 @@
 		if err != nil {
 			return nil, err
 		}
-		rng, err := spanToRange(snapshot, pkg, secondarySpan)
+		rng, err := spanToRange(pkg, secondarySpan)
 		if err != nil {
 			return nil, err
 		}
@@ -163,10 +162,10 @@
 	if err != nil {
 		return nil, err
 	}
-	return []source.SuggestedFix{source.SuggestedFixFromCommand(cmd)}, nil
+	return []source.SuggestedFix{source.SuggestedFixFromCommand(cmd, protocol.QuickFix)}, nil
 }
 
-func analysisDiagnosticDiagnostics(ctx context.Context, snapshot *snapshot, pkg *pkg, a *analysis.Analyzer, e *analysis.Diagnostic) ([]*source.Diagnostic, error) {
+func analysisDiagnosticDiagnostics(snapshot *snapshot, pkg *pkg, a *analysis.Analyzer, e *analysis.Diagnostic) ([]*source.Diagnostic, error) {
 	var srcAnalyzer *source.Analyzer
 	// Find the analyzer that generated this diagnostic.
 	for _, sa := range source.EnabledAnalyzers(snapshot) {
@@ -180,11 +179,15 @@
 	if err != nil {
 		return nil, err
 	}
-	rng, err := spanToRange(snapshot, pkg, spn)
+	rng, err := spanToRange(pkg, spn)
 	if err != nil {
 		return nil, err
 	}
-	fixes, err := suggestedAnalysisFixes(snapshot, pkg, e)
+	kinds := srcAnalyzer.ActionKind
+	if len(srcAnalyzer.ActionKind) == 0 {
+		kinds = append(kinds, protocol.QuickFix)
+	}
+	fixes, err := suggestedAnalysisFixes(snapshot, pkg, e, kinds)
 	if err != nil {
 		return nil, err
 	}
@@ -197,9 +200,11 @@
 		if err != nil {
 			return nil, err
 		}
-		fixes = append(fixes, source.SuggestedFixFromCommand(cmd))
+		for _, kind := range kinds {
+			fixes = append(fixes, source.SuggestedFixFromCommand(cmd, kind))
+		}
 	}
-	related, err := relatedInformation(snapshot, pkg, e)
+	related, err := relatedInformation(pkg, snapshot.FileSet(), e)
 	if err != nil {
 		return nil, err
 	}
@@ -242,7 +247,7 @@
 	return fmt.Sprintf("https://%s/golang.org/x/tools/internal/typesinternal#%s", target, code.String())
 }
 
-func suggestedAnalysisFixes(snapshot *snapshot, pkg *pkg, diag *analysis.Diagnostic) ([]source.SuggestedFix, error) {
+func suggestedAnalysisFixes(snapshot *snapshot, pkg *pkg, diag *analysis.Diagnostic, kinds []protocol.CodeActionKind) ([]source.SuggestedFix, error) {
 	var fixes []source.SuggestedFix
 	for _, fix := range diag.SuggestedFixes {
 		edits := make(map[span.URI][]protocol.TextEdit)
@@ -251,7 +256,7 @@
 			if err != nil {
 				return nil, err
 			}
-			rng, err := spanToRange(snapshot, pkg, spn)
+			rng, err := spanToRange(pkg, spn)
 			if err != nil {
 				return nil, err
 			}
@@ -260,22 +265,26 @@
 				NewText: string(e.NewText),
 			})
 		}
-		fixes = append(fixes, source.SuggestedFix{
-			Title: fix.Message,
-			Edits: edits,
-		})
+		for _, kind := range kinds {
+			fixes = append(fixes, source.SuggestedFix{
+				Title:      fix.Message,
+				Edits:      edits,
+				ActionKind: kind,
+			})
+		}
+
 	}
 	return fixes, nil
 }
 
-func relatedInformation(snapshot *snapshot, pkg *pkg, diag *analysis.Diagnostic) ([]source.RelatedInformation, error) {
+func relatedInformation(pkg *pkg, fset *token.FileSet, diag *analysis.Diagnostic) ([]source.RelatedInformation, error) {
 	var out []source.RelatedInformation
 	for _, related := range diag.Related {
-		spn, err := span.NewRange(snapshot.view.session.cache.fset, related.Pos, related.End).Span()
+		spn, err := span.NewRange(fset, related.Pos, related.End).Span()
 		if err != nil {
 			return nil, err
 		}
-		rng, err := spanToRange(snapshot, pkg, spn)
+		rng, err := spanToRange(pkg, spn)
 		if err != nil {
 			return nil, err
 		}
@@ -315,7 +324,7 @@
 
 // spanToRange converts a span.Span to a protocol.Range,
 // assuming that the span belongs to the package whose diagnostics are being computed.
-func spanToRange(snapshot *snapshot, pkg *pkg, spn span.Span) (protocol.Range, error) {
+func spanToRange(pkg *pkg, spn span.Span) (protocol.Range, error) {
 	pgf, err := pkg.File(spn.URI())
 	if err != nil {
 		return protocol.Range{}, err
@@ -340,7 +349,7 @@
 	return span.ParseInDir(input[:msgIndex], wd)
 }
 
-func parseGoListImportCycleError(ctx context.Context, snapshot *snapshot, e packages.Error, pkg *pkg) (string, span.Span, bool) {
+func parseGoListImportCycleError(snapshot *snapshot, e packages.Error, pkg *pkg) (string, span.Span, bool) {
 	re := regexp.MustCompile(`(.*): import stack: \[(.+)\]`)
 	matches := re.FindStringSubmatch(strings.TrimSpace(e.Msg))
 	if len(matches) < 3 {
diff --git a/internal/lsp/cache/mod.go b/internal/lsp/cache/mod.go
index 2e1917a..a915d05 100644
--- a/internal/lsp/cache/mod.go
+++ b/internal/lsp/cache/mod.go
@@ -358,7 +358,7 @@
 			Source:   source.ListError,
 			Message: `Inconsistent vendoring detected. Please re-run "go mod vendor".
 See https://github.com/golang/go/issues/39164 for more detail on this issue.`,
-			SuggestedFixes: []source.SuggestedFix{source.SuggestedFixFromCommand(cmd)},
+			SuggestedFixes: []source.SuggestedFix{source.SuggestedFixFromCommand(cmd, protocol.QuickFix)},
 		}, nil
 
 	case strings.Contains(goCmdError, "updates to go.sum needed"), strings.Contains(goCmdError, "missing go.sum entry"):
@@ -385,8 +385,8 @@
 			Source:   source.ListError,
 			Message:  msg,
 			SuggestedFixes: []source.SuggestedFix{
-				source.SuggestedFixFromCommand(tidyCmd),
-				source.SuggestedFixFromCommand(updateCmd),
+				source.SuggestedFixFromCommand(tidyCmd, protocol.QuickFix),
+				source.SuggestedFixFromCommand(updateCmd, protocol.QuickFix),
 			},
 		}, nil
 	case strings.Contains(goCmdError, "disabled by GOPROXY=off") && innermost != nil:
@@ -405,7 +405,7 @@
 			Severity:       protocol.SeverityError,
 			Message:        fmt.Sprintf("%v@%v has not been downloaded", innermost.Path, innermost.Version),
 			Source:         source.ListError,
-			SuggestedFixes: []source.SuggestedFix{source.SuggestedFixFromCommand(cmd)},
+			SuggestedFixes: []source.SuggestedFix{source.SuggestedFixFromCommand(cmd, protocol.QuickFix)},
 		}, nil
 	default:
 		return &source.Diagnostic{
diff --git a/internal/lsp/cache/mod_tidy.go b/internal/lsp/cache/mod_tidy.go
index 6891a39..7c92746 100644
--- a/internal/lsp/cache/mod_tidy.go
+++ b/internal/lsp/cache/mod_tidy.go
@@ -77,11 +77,11 @@
 			Diagnostics: criticalErr.DiagList,
 		}, nil
 	}
-	workspacePkgs, err := s.WorkspacePackages(ctx)
+	workspacePkgs, err := s.workspacePackageHandles(ctx)
 	if err != nil {
 		return nil, err
 	}
-	importHash, err := hashImports(ctx, workspacePkgs)
+	importHash, err := s.hashImports(ctx, workspacePkgs)
 	if err != nil {
 		return nil, err
 	}
@@ -167,18 +167,16 @@
 	return rangeFromPositions(pmf.Mapper, pmf.File.Module.Syntax.Start, pmf.File.Module.Syntax.End)
 }
 
-func hashImports(ctx context.Context, wsPackages []source.Package) (string, error) {
-	results := make(map[string]bool)
+func (s *snapshot) hashImports(ctx context.Context, wsPackages []*packageHandle) (string, error) {
+	seen := map[string]struct{}{}
 	var imports []string
-	for _, pkg := range wsPackages {
-		for _, path := range pkg.Imports() {
-			imp := path.PkgPath()
-			if _, ok := results[imp]; !ok {
-				results[imp] = true
+	for _, ph := range wsPackages {
+		for _, imp := range ph.imports(ctx, s) {
+			if _, ok := seen[imp]; !ok {
 				imports = append(imports, imp)
+				seen[imp] = struct{}{}
 			}
 		}
-		imports = append(imports, pkg.MissingDependencies()...)
 	}
 	sort.Strings(imports)
 	hashed := strings.Join(imports, ",")
@@ -188,7 +186,7 @@
 // modTidyDiagnostics computes the differences between the original and tidied
 // go.mod files to produce diagnostic and suggested fixes. Some diagnostics
 // may appear on the Go files that import packages from missing modules.
-func modTidyDiagnostics(ctx context.Context, snapshot source.Snapshot, pm *source.ParsedModule, ideal *modfile.File, workspacePkgs []source.Package) (diagnostics []*source.Diagnostic, err error) {
+func modTidyDiagnostics(ctx context.Context, snapshot source.Snapshot, pm *source.ParsedModule, ideal *modfile.File, workspacePkgs []*packageHandle) (diagnostics []*source.Diagnostic, err error) {
 	// First, determine which modules are unused and which are missing from the
 	// original go.mod file.
 	var (
@@ -224,7 +222,7 @@
 	// statements in the Go files in which the dependencies are used.
 	missingModuleFixes := map[*modfile.Require][]source.SuggestedFix{}
 	for _, req := range missing {
-		srcDiag, err := missingModuleDiagnostic(snapshot, pm, req)
+		srcDiag, err := missingModuleDiagnostic(pm, req)
 		if err != nil {
 			return nil, err
 		}
@@ -233,17 +231,13 @@
 	}
 	// Add diagnostics for missing modules anywhere they are imported in the
 	// workspace.
-	for _, pkg := range workspacePkgs {
+	for _, ph := range workspacePkgs {
 		missingImports := map[string]*modfile.Require{}
-		var importedPkgs []string
 
 		// If -mod=readonly is not set we may have successfully imported
 		// packages from missing modules. Otherwise they'll be in
 		// MissingDependencies. Combine both.
-		for _, imp := range pkg.Imports() {
-			importedPkgs = append(importedPkgs, imp.PkgPath())
-		}
-		importedPkgs = append(importedPkgs, pkg.MissingDependencies()...)
+		importedPkgs := ph.imports(ctx, snapshot)
 
 		for _, imp := range importedPkgs {
 			if req, ok := missing[imp]; ok {
@@ -274,7 +268,11 @@
 		if len(missingImports) == 0 {
 			continue
 		}
-		for _, pgf := range pkg.CompiledGoFiles() {
+		for _, pgh := range ph.compiledGoFiles {
+			pgf, err := snapshot.ParseGo(ctx, pgh.file, source.ParseHeader)
+			if err != nil {
+				continue
+			}
 			file, m := pgf.File, pgf.Mapper
 			if file == nil || m == nil {
 				continue
@@ -311,7 +309,7 @@
 	// Finally, add errors for any unused dependencies.
 	onlyDiagnostic := len(diagnostics) == 0 && len(unused) == 1
 	for _, req := range unused {
-		srcErr, err := unusedDiagnostic(pm.Mapper, req, onlyDiagnostic, snapshot.View().Options().ComputeEdits)
+		srcErr, err := unusedDiagnostic(pm.Mapper, req, onlyDiagnostic)
 		if err != nil {
 			return nil, err
 		}
@@ -321,7 +319,7 @@
 }
 
 // unusedDiagnostic returns a source.Diagnostic for an unused require.
-func unusedDiagnostic(m *protocol.ColumnMapper, req *modfile.Require, onlyDiagnostic bool, computeEdits diff.ComputeEdits) (*source.Diagnostic, error) {
+func unusedDiagnostic(m *protocol.ColumnMapper, req *modfile.Require, onlyDiagnostic bool) (*source.Diagnostic, error) {
 	rng, err := rangeFromPositions(m, req.Syntax.Start, req.Syntax.End)
 	if err != nil {
 		return nil, err
@@ -341,7 +339,7 @@
 		Severity:       protocol.SeverityWarning,
 		Source:         source.ModTidyError,
 		Message:        fmt.Sprintf("%s is not used in this module", req.Mod.Path),
-		SuggestedFixes: []source.SuggestedFix{source.SuggestedFixFromCommand(cmd)},
+		SuggestedFixes: []source.SuggestedFix{source.SuggestedFixFromCommand(cmd, protocol.QuickFix)},
 	}, nil
 }
 
@@ -383,11 +381,12 @@
 			Edits: map[span.URI][]protocol.TextEdit{
 				m.URI: edits,
 			},
+			ActionKind: protocol.QuickFix,
 		}},
 	}, nil
 }
 
-func missingModuleDiagnostic(snapshot source.Snapshot, pm *source.ParsedModule, req *modfile.Require) (*source.Diagnostic, error) {
+func missingModuleDiagnostic(pm *source.ParsedModule, req *modfile.Require) (*source.Diagnostic, error) {
 	var rng protocol.Range
 	// Default to the start of the file if there is no module declaration.
 	if pm.File != nil && pm.File.Module != nil && pm.File.Module.Syntax != nil {
@@ -413,7 +412,7 @@
 		Severity:       protocol.SeverityError,
 		Source:         source.ModTidyError,
 		Message:        fmt.Sprintf("%s is not in your go.mod file", req.Mod.Path),
-		SuggestedFixes: []source.SuggestedFix{source.SuggestedFixFromCommand(cmd)},
+		SuggestedFixes: []source.SuggestedFix{source.SuggestedFixFromCommand(cmd, protocol.QuickFix)},
 	}, nil
 }
 
diff --git a/internal/lsp/cache/session.go b/internal/lsp/cache/session.go
index 928249e..ba155c7 100644
--- a/internal/lsp/cache/session.go
+++ b/internal/lsp/cache/session.go
@@ -7,7 +7,6 @@
 import (
 	"context"
 	"fmt"
-	"os"
 	"strconv"
 	"sync"
 	"sync/atomic"
@@ -30,7 +29,7 @@
 
 	viewMu  sync.Mutex
 	views   []*View
-	viewMap map[span.URI]*View
+	viewMap map[span.URI]*View // map of URI->best view
 
 	overlayMu sync.Mutex
 	overlays  map[span.URI]*overlay
@@ -244,15 +243,13 @@
 		snapshot.initialize(initCtx, true)
 		if v.tempWorkspace != "" {
 			var err error
-			if err = os.Mkdir(v.tempWorkspace.Filename(), 0700); err == nil {
-				var wsdir span.URI
-				wsdir, err = snapshot.getWorkspaceDir(initCtx)
-				if err == nil {
-					err = copyWorkspace(v.tempWorkspace, wsdir)
-				}
+			var wsdir span.URI
+			wsdir, err = snapshot.getWorkspaceDir(initCtx)
+			if err == nil {
+				err = copyWorkspace(v.tempWorkspace, wsdir)
 			}
 			if err != nil {
-				event.Error(initCtx, "creating workspace dir", err)
+				event.Error(ctx, "copying workspace dir", err)
 			}
 		}
 		release()
diff --git a/internal/lsp/cache/snapshot.go b/internal/lsp/cache/snapshot.go
index b80d518..28d0449 100644
--- a/internal/lsp/cache/snapshot.go
+++ b/internal/lsp/cache/snapshot.go
@@ -200,14 +200,10 @@
 	verboseOutput := s.view.options.VerboseOutput
 	s.view.optionsMu.Unlock()
 
-	// Forcibly disable GOPACKAGESDRIVER. It's incompatible with the
-	// packagesinternal APIs we use, and we really only support the go command
-	// anyway.
-	env := append(append([]string{}, inv.Env...), "GOPACKAGESDRIVER=off")
 	cfg := &packages.Config{
 		Context:    ctx,
 		Dir:        inv.WorkingDir,
-		Env:        env,
+		Env:        inv.Env,
 		BuildFlags: inv.BuildFlags,
 		Mode: packages.NeedName |
 			packages.NeedFiles |
@@ -761,12 +757,13 @@
 }
 
 func (s *snapshot) WorkspacePackages(ctx context.Context) ([]source.Package, error) {
-	if err := s.awaitLoaded(ctx); err != nil {
+	phs, err := s.workspacePackageHandles(ctx)
+	if err != nil {
 		return nil, err
 	}
 	var pkgs []source.Package
-	for _, pkgID := range s.workspacePackageIDs() {
-		pkg, err := s.checkedPackage(ctx, pkgID, s.workspaceParseMode(pkgID))
+	for _, ph := range phs {
+		pkg, err := ph.check(ctx, s)
 		if err != nil {
 			return nil, err
 		}
@@ -775,6 +772,21 @@
 	return pkgs, nil
 }
 
+func (s *snapshot) workspacePackageHandles(ctx context.Context) ([]*packageHandle, error) {
+	if err := s.awaitLoaded(ctx); err != nil {
+		return nil, err
+	}
+	var phs []*packageHandle
+	for _, pkgID := range s.workspacePackageIDs() {
+		ph, err := s.buildPackageHandle(ctx, pkgID, s.workspaceParseMode(pkgID))
+		if err != nil {
+			return nil, err
+		}
+		phs = append(phs, ph)
+	}
+	return phs, nil
+}
+
 func (s *snapshot) KnownPackages(ctx context.Context) ([]source.Package, error) {
 	if err := s.awaitLoaded(ctx); err != nil {
 		return nil, err
@@ -1085,7 +1097,7 @@
 
 func containsCommandLineArguments(pkgs []source.Package) bool {
 	for _, pkg := range pkgs {
-		if strings.Contains(pkg.ID(), "command-line-arguments") {
+		if isCommandLineArguments(pkg.ID()) {
 			return true
 		}
 	}
@@ -1096,6 +1108,16 @@
 	// Do not return results until the snapshot's view has been initialized.
 	s.AwaitInitialized(ctx)
 
+	// TODO(rstambler): Should we be more careful about returning the
+	// initialization error? Is it possible for the initialization error to be
+	// corrected without a successful reinitialization?
+	s.mu.Lock()
+	initializedErr := s.initializedErr
+	s.mu.Unlock()
+	if initializedErr != nil {
+		return initializedErr
+	}
+
 	if ctx.Err() != nil {
 		return &source.CriticalError{MainError: ctx.Err()}
 	}
@@ -1114,10 +1136,7 @@
 			DiagList:  diags,
 		}
 	}
-	// TODO(rstambler): Should we be more careful about returning the
-	// initialization error? Is it possible for the initialization error to be
-	// corrected without a successful reinitialization?
-	return s.initializedErr
+	return nil
 }
 
 func (s *snapshot) AwaitInitialized(ctx context.Context) {
@@ -1173,11 +1192,27 @@
 	// that exist only in overlays. As a workaround, we search all of the files
 	// available in the snapshot and reload their metadata individually using a
 	// file= query if the metadata is unavailable.
-	scopes := s.orphanedFileScopes()
+	files := s.orphanedFiles()
+
+	// Files without a valid package declaration can't be loaded. Don't try.
+	var scopes []interface{}
+	for _, file := range files {
+		pgf, err := s.ParseGo(ctx, file, source.ParseHeader)
+		if err != nil {
+			continue
+		}
+		if !pgf.File.Package.IsValid() {
+			continue
+		}
+		scopes = append(scopes, fileURI(file.URI()))
+	}
+
 	if len(scopes) == 0 {
 		return nil
 	}
 
+	// The regtests match this exact log message, keep them in sync.
+	event.Log(ctx, "reloadOrphanedFiles reloading", tag.Query.Of(scopes))
 	err := s.load(ctx, false, scopes...)
 
 	// If we failed to load some files, i.e. they have no metadata,
@@ -1203,11 +1238,11 @@
 	return nil
 }
 
-func (s *snapshot) orphanedFileScopes() []interface{} {
+func (s *snapshot) orphanedFiles() []source.VersionedFileHandle {
 	s.mu.Lock()
 	defer s.mu.Unlock()
 
-	scopeSet := make(map[span.URI]struct{})
+	var files []source.VersionedFileHandle
 	for uri, fh := range s.files {
 		// Don't try to reload metadata for go.mod files.
 		if fh.Kind() != source.Go {
@@ -1228,14 +1263,10 @@
 			continue
 		}
 		if s.getMetadataForURILocked(uri) == nil {
-			scopeSet[uri] = struct{}{}
+			files = append(files, fh)
 		}
 	}
-	var scopes []interface{}
-	for uri := range scopeSet {
-		scopes = append(scopes, fileURI(uri))
-	}
-	return scopes
+	return files
 }
 
 func contains(views []*View, view *View) bool {
@@ -1485,14 +1516,17 @@
 	}
 	// Copy the URI to package ID mappings, skipping only those URIs whose
 	// metadata will be reloaded in future calls to load.
-copyIDs:
 	for k, ids := range s.ids {
+		var newIDs []packageID
 		for _, id := range ids {
 			if invalidateMetadata, ok := transitiveIDs[id]; invalidateMetadata && ok {
-				continue copyIDs
+				continue
 			}
+			newIDs = append(newIDs, id)
 		}
-		result.ids[k] = ids
+		if len(newIDs) != 0 {
+			result.ids[k] = newIDs
+		}
 	}
 	// Copy the set of initially loaded packages.
 	for id, pkgPath := range s.workspacePackages {
@@ -1767,7 +1801,7 @@
 // BuildGoplsMod generates a go.mod file for all modules in the workspace. It
 // bypasses any existing gopls.mod.
 func BuildGoplsMod(ctx context.Context, root span.URI, s source.Snapshot) (*modfile.File, error) {
-	allModules, err := findModules(ctx, root, pathExcludedByFilterFunc(s.View().Options()), 0)
+	allModules, err := findModules(root, pathExcludedByFilterFunc(s.View().Options()), 0)
 	if err != nil {
 		return nil, err
 	}
diff --git a/internal/lsp/cache/view.go b/internal/lsp/cache/view.go
index 64a9e7e..af00c39 100644
--- a/internal/lsp/cache/view.go
+++ b/internal/lsp/cache/view.go
@@ -236,6 +236,10 @@
 	return v.folder
 }
 
+func (v *View) TempWorkspace() span.URI {
+	return v.tempWorkspace
+}
+
 func (v *View) Options() *source.Options {
 	v.optionsMu.Lock()
 	defer v.optionsMu.Unlock()
@@ -456,11 +460,6 @@
 	go v.snapshot.generation.Destroy()
 	v.snapshotMu.Unlock()
 	v.importsState.destroy()
-	if v.tempWorkspace != "" {
-		if err := os.RemoveAll(v.tempWorkspace.Filename()); err != nil {
-			event.Error(ctx, "removing temp workspace", err)
-		}
-	}
 }
 
 func (v *View) Session() *Session {
@@ -528,24 +527,30 @@
 		return
 	}
 	s.initializeOnce.Do(func() {
-		defer func() {
-			s.initializeOnce = nil
-			if firstAttempt {
-				close(s.view.initialWorkspaceLoad)
-			}
-		}()
+		s.loadWorkspace(ctx, firstAttempt)
+	})
+}
 
-		// If we have multiple modules, we need to load them by paths.
-		var scopes []interface{}
-		var modDiagnostics []*source.Diagnostic
-		addError := func(uri span.URI, err error) {
-			modDiagnostics = append(modDiagnostics, &source.Diagnostic{
-				URI:      uri,
-				Severity: protocol.SeverityError,
-				Source:   source.ListError,
-				Message:  err.Error(),
-			})
+func (s *snapshot) loadWorkspace(ctx context.Context, firstAttempt bool) {
+	defer func() {
+		s.initializeOnce = nil
+		if firstAttempt {
+			close(s.view.initialWorkspaceLoad)
 		}
+	}()
+
+	// If we have multiple modules, we need to load them by paths.
+	var scopes []interface{}
+	var modDiagnostics []*source.Diagnostic
+	addError := func(uri span.URI, err error) {
+		modDiagnostics = append(modDiagnostics, &source.Diagnostic{
+			URI:      uri,
+			Severity: protocol.SeverityError,
+			Source:   source.ListError,
+			Message:  err.Error(),
+		})
+	}
+	if len(s.workspace.getActiveModFiles()) > 0 {
 		for modURI := range s.workspace.getActiveModFiles() {
 			fh, err := s.GetFile(ctx, modURI)
 			if err != nil {
@@ -564,31 +569,41 @@
 			path := parsed.File.Module.Mod.Path
 			scopes = append(scopes, moduleLoadScope(path))
 		}
-		if len(scopes) == 0 {
-			scopes = append(scopes, viewLoadScope("LOAD_VIEW"))
+	} else {
+		scopes = append(scopes, viewLoadScope("LOAD_VIEW"))
+	}
+	var err error
+	if len(scopes) > 0 {
+		err = s.load(ctx, firstAttempt, append(scopes, packagePath("builtin"))...)
+	}
+	if ctx.Err() != nil {
+		return
+	}
+
+	var criticalErr *source.CriticalError
+	if err != nil {
+		event.Error(ctx, "initial workspace load failed", err)
+		extractedDiags, _ := s.extractGoCommandErrors(ctx, err.Error())
+		criticalErr = &source.CriticalError{
+			MainError: err,
+			DiagList:  append(modDiagnostics, extractedDiags...),
 		}
-		err := s.load(ctx, firstAttempt, append(scopes, packagePath("builtin"))...)
-		if ctx.Err() != nil {
-			return
+	} else if len(modDiagnostics) == 1 {
+		criticalErr = &source.CriticalError{
+			MainError: fmt.Errorf(modDiagnostics[0].Message),
+			DiagList:  modDiagnostics,
 		}
-		if err != nil {
-			event.Error(ctx, "initial workspace load failed", err)
-			extractedDiags, _ := s.extractGoCommandErrors(ctx, err.Error())
-			s.initializedErr = &source.CriticalError{
-				MainError: err,
-				DiagList:  append(modDiagnostics, extractedDiags...),
-			}
-		} else if len(modDiagnostics) != 0 {
-			s.initializedErr = &source.CriticalError{
-				MainError: fmt.Errorf("error loading module names"),
-				DiagList:  modDiagnostics,
-			}
-		} else {
-			// Clear out the initialization error, in case it had been set
-			// previously.
-			s.initializedErr = nil
+	} else if len(modDiagnostics) > 1 {
+		criticalErr = &source.CriticalError{
+			MainError: fmt.Errorf("error loading module names"),
+			DiagList:  modDiagnostics,
 		}
-	})
+	}
+
+	// Lock the snapshot when setting the initialized error.
+	s.mu.Lock()
+	defer s.mu.Unlock()
+	s.initializedErr = criticalErr
 }
 
 // invalidateContent invalidates the content of a Go file,
@@ -614,7 +629,9 @@
 	v.snapshot, workspaceChanged = oldSnapshot.clone(ctx, v.baseCtx, changes, forceReloadMetadata)
 	if workspaceChanged && v.tempWorkspace != "" {
 		snap := v.snapshot
+		release := snap.generation.Acquire(ctx)
 		go func() {
+			defer release()
 			wsdir, err := snap.getWorkspaceDir(ctx)
 			if err != nil {
 				event.Error(ctx, "getting workspace dir", err)
@@ -745,7 +762,7 @@
 	}
 
 	// ...else we should check if there's exactly one nested module.
-	all, err := findModules(ctx, folder, excludePath, 2)
+	all, err := findModules(folder, excludePath, 2)
 	if err == errExhausted {
 		// Fall-back behavior: if we don't find any modules after searching 10000
 		// files, assume there are none.
diff --git a/internal/lsp/cache/workspace.go b/internal/lsp/cache/workspace.go
index 84db093..6b62d29 100644
--- a/internal/lsp/cache/workspace.go
+++ b/internal/lsp/cache/workspace.go
@@ -108,7 +108,7 @@
 	}
 	// Otherwise, in all other modes, search for all of the go.mod files in the
 	// workspace.
-	knownModFiles, err := findModules(ctx, root, excludePath, 0)
+	knownModFiles, err := findModules(root, excludePath, 0)
 	if err != nil {
 		return nil, err
 	}
@@ -305,7 +305,7 @@
 				result.moduleSource = fileSystemWorkspace
 				// The parsed gopls.mod is no longer valid.
 				result.mod = nil
-				knownModFiles, err := findModules(ctx, w.root, w.excludePath, 0)
+				knownModFiles, err := findModules(w.root, w.excludePath, 0)
 				if err != nil {
 					result.knownModFiles = nil
 					result.activeModFiles = nil
@@ -463,7 +463,7 @@
 // searching stops once modLimit modules have been found.
 //
 // TODO(rfindley): consider overlays.
-func findModules(ctx context.Context, root span.URI, excludePath func(string) bool, modLimit int) (map[span.URI]struct{}, error) {
+func findModules(root span.URI, excludePath func(string) bool, modLimit int) (map[span.URI]struct{}, error) {
 	// Walk the view's folder to find all modules in the view.
 	modFiles := make(map[span.URI]struct{})
 	searched := 0
diff --git a/internal/lsp/cmd/capabilities_test.go b/internal/lsp/cmd/capabilities_test.go
index acd5450..70db8d7 100644
--- a/internal/lsp/cmd/capabilities_test.go
+++ b/internal/lsp/cmd/capabilities_test.go
@@ -43,7 +43,7 @@
 	params.Capabilities.Workspace.Configuration = true
 
 	// Send an initialize request to the server.
-	c.Server = lsp.NewServer(cache.New(ctx, app.options).NewSession(ctx), c.Client)
+	c.Server = lsp.NewServer(cache.New(app.options).NewSession(ctx), c.Client)
 	result, err := c.Server.Initialize(ctx, params)
 	if err != nil {
 		t.Fatal(err)
diff --git a/internal/lsp/cmd/cmd.go b/internal/lsp/cmd/cmd.go
index 228a713..41c2bce 100644
--- a/internal/lsp/cmd/cmd.go
+++ b/internal/lsp/cmd/cmd.go
@@ -208,7 +208,7 @@
 	switch {
 	case app.Remote == "":
 		connection := newConnection(app)
-		connection.Server = lsp.NewServer(cache.New(ctx, app.options).NewSession(ctx), connection.Client)
+		connection.Server = lsp.NewServer(cache.New(app.options).NewSession(ctx), connection.Client)
 		ctx = protocol.WithClient(ctx, connection.Client)
 		return connection, connection.initialize(ctx, app.options)
 	case strings.HasPrefix(app.Remote, "internal@"):
diff --git a/internal/lsp/cmd/serve.go b/internal/lsp/cmd/serve.go
index a3bfd91..c45790d 100644
--- a/internal/lsp/cmd/serve.go
+++ b/internal/lsp/cmd/serve.go
@@ -86,7 +86,7 @@
 			lsprpc.RemoteLogfile(s.RemoteLogfile),
 		)
 	} else {
-		ss = lsprpc.NewStreamServer(cache.New(ctx, s.app.options), isDaemon)
+		ss = lsprpc.NewStreamServer(cache.New(s.app.options), isDaemon)
 	}
 
 	var network, addr string
diff --git a/internal/lsp/cmd/test/cmdtest.go b/internal/lsp/cmd/test/cmdtest.go
index b8abe6d..869d4f5 100644
--- a/internal/lsp/cmd/test/cmdtest.go
+++ b/internal/lsp/cmd/test/cmdtest.go
@@ -49,7 +49,7 @@
 
 func NewTestServer(ctx context.Context, options func(*source.Options)) *servertest.TCPServer {
 	ctx = debug.WithInstance(ctx, "", "")
-	cache := cache.New(ctx, options)
+	cache := cache.New(options)
 	ss := lsprpc.NewStreamServer(cache, false)
 	return servertest.NewTCPServer(ctx, ss, nil)
 }
diff --git a/internal/lsp/code_action.go b/internal/lsp/code_action.go
index da6cf97..7a389b5 100644
--- a/internal/lsp/code_action.go
+++ b/internal/lsp/code_action.go
@@ -147,11 +147,14 @@
 			if len(d.SuggestedFixes) == 0 {
 				continue
 			}
-			kind := protocol.QuickFix
-			if d.Analyzer != nil && d.Analyzer.ActionKind != "" {
-				kind = d.Analyzer.ActionKind
+			var isFix bool
+			for _, fix := range d.SuggestedFixes {
+				if fix.ActionKind == protocol.QuickFix || fix.ActionKind == protocol.SourceFixAll {
+					isFix = true
+					break
+				}
 			}
-			if kind == protocol.QuickFix || kind == protocol.SourceFixAll {
+			if isFix {
 				fixDiags = append(fixDiags, d)
 			} else {
 				nonFixDiags = append(nonFixDiags, d)
@@ -356,25 +359,13 @@
 func codeActionsForDiagnostic(ctx context.Context, snapshot source.Snapshot, sd *source.Diagnostic, pd *protocol.Diagnostic) ([]protocol.CodeAction, error) {
 	var actions []protocol.CodeAction
 	for _, fix := range sd.SuggestedFixes {
-		action := protocol.CodeAction{
-			Title:   fix.Title,
-			Kind:    protocol.QuickFix,
-			Edit:    protocol.WorkspaceEdit{},
-			Command: fix.Command,
-		}
-		if pd != nil {
-			action.Diagnostics = []protocol.Diagnostic{*pd}
-		}
-		if sd.Analyzer != nil && sd.Analyzer.ActionKind != "" {
-			action.Kind = sd.Analyzer.ActionKind
-		}
-
+		var changes []protocol.TextDocumentEdit
 		for uri, edits := range fix.Edits {
 			fh, err := snapshot.GetVersionedFile(ctx, uri)
 			if err != nil {
 				return nil, err
 			}
-			action.Edit.DocumentChanges = append(action.Edit.DocumentChanges, protocol.TextDocumentEdit{
+			changes = append(changes, protocol.TextDocumentEdit{
 				TextDocument: protocol.OptionalVersionedTextDocumentIdentifier{
 					Version: fh.Version(),
 					TextDocumentIdentifier: protocol.TextDocumentIdentifier{
@@ -384,6 +375,17 @@
 				Edits: edits,
 			})
 		}
+		action := protocol.CodeAction{
+			Title: fix.Title,
+			Kind:  fix.ActionKind,
+			Edit: protocol.WorkspaceEdit{
+				DocumentChanges: changes,
+			},
+			Command: fix.Command,
+		}
+		if pd != nil {
+			action.Diagnostics = []protocol.Diagnostic{*pd}
+		}
 		actions = append(actions, action)
 	}
 	return actions, nil
diff --git a/internal/lsp/command.go b/internal/lsp/command.go
index 1960270..24fd719 100644
--- a/internal/lsp/command.go
+++ b/internal/lsp/command.go
@@ -683,3 +683,14 @@
 	})
 	return result, err
 }
+
+func (c *commandHandler) WorkspaceMetadata(ctx context.Context) (command.WorkspaceMetadataResult, error) {
+	var result command.WorkspaceMetadataResult
+	for _, view := range c.s.session.Views() {
+		result.Workspaces = append(result.Workspaces, command.Workspace{
+			Name:      view.Name(),
+			ModuleDir: view.TempWorkspace().Filename(),
+		})
+	}
+	return result, nil
+}
diff --git a/internal/lsp/command/command_gen.go b/internal/lsp/command/command_gen.go
index 1871c9d..9cdcb41 100644
--- a/internal/lsp/command/command_gen.go
+++ b/internal/lsp/command/command_gen.go
@@ -37,6 +37,7 @@
 	UpdateGoSum       Command = "update_go_sum"
 	UpgradeDependency Command = "upgrade_dependency"
 	Vendor            Command = "vendor"
+	WorkspaceMetadata Command = "workspace_metadata"
 )
 
 var Commands = []Command{
@@ -58,6 +59,7 @@
 	UpdateGoSum,
 	UpgradeDependency,
 	Vendor,
+	WorkspaceMetadata,
 }
 
 func Dispatch(ctx context.Context, params *protocol.ExecuteCommandParams, s Interface) (interface{}, error) {
@@ -172,6 +174,8 @@
 			return nil, err
 		}
 		return nil, s.Vendor(ctx, a0)
+	case "gopls.workspace_metadata":
+		return s.WorkspaceMetadata(ctx)
 	}
 	return nil, fmt.Errorf("unsupported command %q", params.Command)
 }
@@ -391,3 +395,15 @@
 		Arguments: args,
 	}, nil
 }
+
+func NewWorkspaceMetadataCommand(title string) (protocol.Command, error) {
+	args, err := MarshalArgs()
+	if err != nil {
+		return protocol.Command{}, err
+	}
+	return protocol.Command{
+		Title:     title,
+		Command:   "gopls.workspace_metadata",
+		Arguments: args,
+	}, nil
+}
diff --git a/internal/lsp/command/interface.go b/internal/lsp/command/interface.go
index bd5e4c2..1712327 100644
--- a/internal/lsp/command/interface.go
+++ b/internal/lsp/command/interface.go
@@ -118,6 +118,8 @@
 	ListKnownPackages(context.Context, URIArg) (ListKnownPackagesResult, error)
 
 	AddImport(context.Context, AddImportArgs) (AddImportResult, error)
+
+	WorkspaceMetadata(context.Context) (WorkspaceMetadataResult, error)
 }
 
 type RunTestsArgs struct {
@@ -206,3 +208,15 @@
 type ListKnownPackagesResult struct {
 	Packages []string
 }
+
+type WorkspaceMetadataArgs struct {
+}
+
+type WorkspaceMetadataResult struct {
+	Workspaces []Workspace
+}
+
+type Workspace struct {
+	Name      string
+	ModuleDir string
+}
diff --git a/internal/lsp/completion_test.go b/internal/lsp/completion_test.go
index 22a377e..d496a40 100644
--- a/internal/lsp/completion_test.go
+++ b/internal/lsp/completion_test.go
@@ -20,9 +20,8 @@
 		opts.Matcher = source.CaseInsensitive
 		opts.CompleteUnimported = false
 		opts.InsertTextFormat = protocol.SnippetTextFormat
-		if !strings.Contains(string(src.URI()), "literal") {
-			opts.LiteralCompletions = false
-		}
+		opts.LiteralCompletions = strings.Contains(string(src.URI()), "literal")
+		opts.ExperimentalPostfixCompletions = strings.Contains(string(src.URI()), "postfix")
 	})
 	got = tests.FilterBuiltins(src, got)
 	want := expected(t, test, items)
@@ -101,6 +100,7 @@
 		opts.Matcher = source.Fuzzy
 		opts.CompleteUnimported = false
 		opts.LiteralCompletions = true
+		opts.ExperimentalPostfixCompletions = true
 	})
 	want := expected(t, test, items)
 	if msg := tests.CheckCompletionOrder(want, got, true); msg != "" {
diff --git a/internal/lsp/debug/info.go b/internal/lsp/debug/info.go
index 92114cc..7013396 100644
--- a/internal/lsp/debug/info.go
+++ b/internal/lsp/debug/info.go
@@ -26,7 +26,7 @@
 )
 
 // Version is a manually-updated mechanism for tracking versions.
-const Version = "v0.6.9"
+const Version = "v0.6.10"
 
 // ServerVersion is the format used by gopls to report its version to the
 // client. This format is structured so that the client can parse it easily.
diff --git a/internal/lsp/diagnostics.go b/internal/lsp/diagnostics.go
index 6b75feb..f93e525 100644
--- a/internal/lsp/diagnostics.go
+++ b/internal/lsp/diagnostics.go
@@ -285,15 +285,25 @@
 		if err != nil {
 			event.Error(ctx, "warning: gc details", err, tag.Snapshot.Of(snapshot.ID()), tag.Package.Of(pkg.ID()))
 		}
-		for id, diags := range gcReports {
-			fh := snapshot.FindFile(id.URI)
-			// Don't publish gc details for unsaved buffers, since the underlying
-			// logic operates on the file on disk.
-			if fh == nil || !fh.Saved() {
-				continue
+		s.gcOptimizationDetailsMu.Lock()
+		_, enableGCDetails := s.gcOptimizationDetails[pkg.ID()]
+
+		// NOTE(golang/go#44826): hold the gcOptimizationDetails lock, and re-check
+		// whether gc optimization details are enabled, while storing gc_details
+		// results. This ensures that the toggling of GC details and clearing of
+		// diagnostics does not race with storing the results here.
+		if enableGCDetails {
+			for id, diags := range gcReports {
+				fh := snapshot.FindFile(id.URI)
+				// Don't publish gc details for unsaved buffers, since the underlying
+				// logic operates on the file on disk.
+				if fh == nil || !fh.Saved() {
+					continue
+				}
+				s.storeDiagnostics(snapshot, id.URI, gcDetailsSource, diags)
 			}
-			s.storeDiagnostics(snapshot, id.URI, gcDetailsSource, diags)
 		}
+		s.gcOptimizationDetailsMu.Unlock()
 	}
 }
 
diff --git a/internal/lsp/fake/editor.go b/internal/lsp/fake/editor.go
index 725c596..f10ea44 100644
--- a/internal/lsp/fake/editor.go
+++ b/internal/lsp/fake/editor.go
@@ -275,6 +275,8 @@
 		params.ProcessID = int32(os.Getpid())
 	}
 
+	params.Capabilities.TextDocument.Completion.CompletionItem.SnippetSupport = true
+
 	// This is a bit of a hack, since the fake editor doesn't actually support
 	// watching changed files that match a specific glob pattern. However, the
 	// editor does send didChangeWatchedFiles notifications, so set this to
@@ -1039,7 +1041,7 @@
 }
 
 // CodeAction executes a codeAction request on the server.
-func (e *Editor) CodeAction(ctx context.Context, path string, rng *protocol.Range) ([]protocol.CodeAction, error) {
+func (e *Editor) CodeAction(ctx context.Context, path string, rng *protocol.Range, diagnostics []protocol.Diagnostic) ([]protocol.CodeAction, error) {
 	if e.Server == nil {
 		return nil, nil
 	}
@@ -1051,6 +1053,9 @@
 	}
 	params := &protocol.CodeActionParams{
 		TextDocument: e.textDocumentIdentifier(path),
+		Context: protocol.CodeActionContext{
+			Diagnostics: diagnostics,
+		},
 	}
 	if rng != nil {
 		params.Range = *rng
@@ -1089,3 +1094,17 @@
 	params.TextDocument.URI = e.sandbox.Workdir.URI(path)
 	return e.Server.DocumentLink(ctx, params)
 }
+
+func (e *Editor) DocumentHighlight(ctx context.Context, path string, pos Pos) ([]protocol.DocumentHighlight, error) {
+	if e.Server == nil {
+		return nil, nil
+	}
+	if err := e.checkBufferPosition(path, pos); err != nil {
+		return nil, err
+	}
+	params := &protocol.DocumentHighlightParams{}
+	params.TextDocument.URI = e.sandbox.Workdir.URI(path)
+	params.Position = pos.ToProtocolPosition()
+
+	return e.Server.DocumentHighlight(ctx, params)
+}
diff --git a/internal/lsp/general.go b/internal/lsp/general.go
index c87107f..6603e47 100644
--- a/internal/lsp/general.go
+++ b/internal/lsp/general.go
@@ -33,7 +33,20 @@
 	s.state = serverInitializing
 	s.stateMu.Unlock()
 
-	s.clientPID = int(params.ProcessID)
+	// For uniqueness, use the gopls PID rather than params.ProcessID (the client
+	// pid). Some clients might start multiple gopls servers, though they
+	// probably shouldn't.
+	pid := os.Getpid()
+	s.tempDir = filepath.Join(os.TempDir(), fmt.Sprintf("gopls-%d.%s", pid, s.session.ID()))
+	err := os.Mkdir(s.tempDir, 0700)
+	if err != nil {
+		// MkdirTemp could fail due to permissions issues. This is a problem with
+		// the user's environment, but should not block gopls otherwise behaving.
+		// All usage of s.tempDir should be predicated on having a non-empty
+		// s.tempDir.
+		event.Error(ctx, "creating temp dir", err)
+		s.tempDir = ""
+	}
 	s.progress.supportsWorkDoneProgress = params.Capabilities.Window.WorkDoneProgress
 
 	options := s.session.Options()
@@ -197,7 +210,6 @@
 		}()
 	}
 	// Only one view gets to have a workspace.
-	assignedWorkspace := false
 	var allFoldersWg sync.WaitGroup
 	for _, folder := range folders {
 		uri := span.URIFromURI(folder.URI)
@@ -206,22 +218,7 @@
 			continue
 		}
 		work := s.progress.start(ctx, "Setting up workspace", "Loading packages...", nil, nil)
-		var workspaceURI span.URI = ""
-		if !assignedWorkspace && s.clientPID != 0 {
-			// For quick-and-dirty testing, set the temp workspace file to
-			// $TMPDIR/gopls-<client PID>.workspace.
-			//
-			// This has a couple limitations:
-			//  + If there are multiple workspace roots, only the first one gets
-			//    written to this dir (and the client has no way to know precisely
-			//    which one).
-			//  + If a single client PID spawns multiple gopls sessions, they will
-			//    clobber eachother's temp workspace.
-			wsdir := filepath.Join(os.TempDir(), fmt.Sprintf("gopls-%d.workspace", s.clientPID))
-			workspaceURI = span.URIFromPath(wsdir)
-			assignedWorkspace = true
-		}
-		snapshot, release, err := s.addView(ctx, folder.Name, uri, workspaceURI)
+		snapshot, release, err := s.addView(ctx, folder.Name, uri)
 		if err != nil {
 			viewErrors[uri] = err
 			work.end(fmt.Sprintf("Error loading packages: %s", err))
@@ -471,6 +468,11 @@
 		// drop all the active views
 		s.session.Shutdown(ctx)
 		s.state = serverShutDown
+		if s.tempDir != "" {
+			if err := os.RemoveAll(s.tempDir); err != nil {
+				event.Error(ctx, "removing temp dir", err)
+			}
+		}
 	}
 	return nil
 }
diff --git a/internal/lsp/lsp_test.go b/internal/lsp/lsp_test.go
index 2b71029..621e42a 100644
--- a/internal/lsp/lsp_test.go
+++ b/internal/lsp/lsp_test.go
@@ -46,7 +46,7 @@
 func testLSP(t *testing.T, datum *tests.Data) {
 	ctx := tests.Context(t)
 
-	cache := cache.New(ctx, nil)
+	cache := cache.New(nil)
 	session := cache.NewSession(ctx)
 	options := source.DefaultOptions().Clone()
 	tests.DefaultOptions(options)
diff --git a/internal/lsp/lsprpc/lsprpc_test.go b/internal/lsp/lsprpc/lsprpc_test.go
index 1b546e7..538569b 100644
--- a/internal/lsp/lsprpc/lsprpc_test.go
+++ b/internal/lsp/lsprpc/lsprpc_test.go
@@ -57,7 +57,7 @@
 	client := fakeClient{logs: make(chan string, 10)}
 
 	ctx = debug.WithInstance(ctx, "", "")
-	ss := NewStreamServer(cache.New(ctx, nil), false)
+	ss := NewStreamServer(cache.New(nil), false)
 	ss.serverForTest = server
 	ts := servertest.NewPipeServer(ctx, ss, nil)
 	defer checkClose(t, ts.Close)
@@ -114,7 +114,7 @@
 func setupForwarding(ctx context.Context, t *testing.T, s protocol.Server) (direct, forwarded servertest.Connector, cleanup func()) {
 	t.Helper()
 	serveCtx := debug.WithInstance(ctx, "", "")
-	ss := NewStreamServer(cache.New(serveCtx, nil), false)
+	ss := NewStreamServer(cache.New(nil), false)
 	ss.serverForTest = s
 	tsDirect := servertest.NewTCPServer(serveCtx, ss, nil)
 
@@ -217,7 +217,7 @@
 	clientCtx := debug.WithInstance(baseCtx, "", "")
 	serverCtx := debug.WithInstance(baseCtx, "", "")
 
-	cache := cache.New(serverCtx, nil)
+	cache := cache.New(nil)
 	ss := NewStreamServer(cache, false)
 	tsBackend := servertest.NewTCPServer(serverCtx, ss, nil)
 
diff --git a/internal/lsp/mod/code_lens.go b/internal/lsp/mod/code_lens.go
index 1598ed5..d7310c7 100644
--- a/internal/lsp/mod/code_lens.go
+++ b/internal/lsp/mod/code_lens.go
@@ -50,7 +50,7 @@
 	upgradeTransitive, err := command.NewUpgradeDependencyCommand("Upgrade transitive dependencies", command.DependencyArgs{
 		URI:        uri,
 		AddRequire: false,
-		GoCmdArgs:  []string{"-u", "all"},
+		GoCmdArgs:  []string{"-d", "-u", "-t", "./..."},
 	})
 	if err != nil {
 		return nil, err
@@ -58,7 +58,7 @@
 	upgradeDirect, err := command.NewUpgradeDependencyCommand("Upgrade direct dependencies", command.DependencyArgs{
 		URI:        uri,
 		AddRequire: false,
-		GoCmdArgs:  requires,
+		GoCmdArgs:  append([]string{"-d"}, requires...),
 	})
 	if err != nil {
 		return nil, err
diff --git a/internal/lsp/mod/diagnostics.go b/internal/lsp/mod/diagnostics.go
index 0aa8caf..6495aeb 100644
--- a/internal/lsp/mod/diagnostics.go
+++ b/internal/lsp/mod/diagnostics.go
@@ -81,7 +81,7 @@
 			Severity:       protocol.SeverityInformation,
 			Source:         source.UpgradeNotification,
 			Message:        fmt.Sprintf("%v can be upgraded", req.Mod.Path),
-			SuggestedFixes: []source.SuggestedFix{source.SuggestedFixFromCommand(cmd)},
+			SuggestedFixes: []source.SuggestedFix{source.SuggestedFixFromCommand(cmd, protocol.QuickFix)},
 		})
 	}
 
diff --git a/internal/lsp/mod/mod_test.go b/internal/lsp/mod/mod_test.go
index 6ce8926..3298910 100644
--- a/internal/lsp/mod/mod_test.go
+++ b/internal/lsp/mod/mod_test.go
@@ -26,7 +26,7 @@
 	testenv.NeedsGo1Point(t, 14)
 
 	ctx := tests.Context(t)
-	cache := cache.New(ctx, nil)
+	cache := cache.New(nil)
 	session := cache.NewSession(ctx)
 	options := source.DefaultOptions().Clone()
 	tests.DefaultOptions(options)
diff --git a/internal/lsp/protocol/typescript/README.md b/internal/lsp/protocol/typescript/README.md
index 456cc85..bf6dc8d 100644
--- a/internal/lsp/protocol/typescript/README.md
+++ b/internal/lsp/protocol/typescript/README.md
@@ -16,7 +16,7 @@
 
 Code is generated and normalized by
 
-`tsc code.ts && node code.js && gofmt -w ts*.go`
+`tsc && node code.js && gofmt -w ts*.go`
 
 (`code.ts` imports `util.ts`.) This generates 3 files in the current directory, `tsprotocol.go`
 containing type definitions, and `tsserver.go`, `tsclient.go` containing API stubs.
diff --git a/internal/lsp/protocol/typescript/code.ts b/internal/lsp/protocol/typescript/code.ts
index bc6c643..dc5d266 100644
--- a/internal/lsp/protocol/typescript/code.ts
+++ b/internal/lsp/protocol/typescript/code.ts
@@ -23,15 +23,13 @@
 import { constName, getComments, goName, loc, strKind } from './util';
 
 var program: ts.Program;
-// eslint-disable-next-line no-unused-vars
-var checker: ts.TypeChecker;
 
 function parse() {
   // this won't complain if some fnames don't exist
   program = ts.createProgram(
     u.fnames,
     { target: ts.ScriptTarget.ES2018, module: ts.ModuleKind.CommonJS });
-  checker = program.getTypeChecker();  // finish type checking and assignment
+  program.getTypeChecker();  // finish type checking and assignment
 }
 
 // ----- collecting information for RPCs
@@ -56,7 +54,7 @@
 
   if (!ts.isModuleBlock(node.body)) {
     throw new Error(
-      `expected ModuleBody got ${strKind(node.body)} at ${loc(node)}`);
+      `expected ModuleBlock got ${strKind(node.body)} at ${loc(node)}`);
   }
   let x: ts.ModuleBlock = node.body;
   // The story is to expect const method = 'textDocument/implementation'
@@ -103,7 +101,7 @@
           ptypes.set(rpc, [nn.typeArguments[0], nn.typeArguments[1]]);
           break;
         default:
-          throw new Error(`${nn.typeArguments.length} at ${loc(nn)}`);
+          throw new Error(`${nn.typeArguments?.length} at ${loc(nn)}`);
       }
     }
   }
@@ -426,7 +424,7 @@
 
 // helper function to find underlying types
 // eslint-disable-next-line no-unused-vars
-function underlying(n: ts.Node, f: (n: ts.Node) => void) {
+function underlying(n: ts.Node | undefined, f: (n: ts.Node) => void) {
   if (!n) return;
   const ff = function (n: ts.Node) {
     underlying(n, f);
@@ -543,7 +541,9 @@
   }
   throw new Error(`546 sameType? ${strKind(a)} ${strKind(b)}`);
 }
-
+type CreateMutable<Type> = {
+  -readonly [Property in keyof Type]: Type[Property];
+};
 type propMap = Map<string, ts.PropertySignature>;
 function propMapSet(pm: propMap, name: string, v: ts.PropertySignature) {
   if (!pm.get(name)) {
@@ -557,16 +557,16 @@
     return;
   }
   if (ts.isTypeReferenceNode(a) && ts.isTypeLiteralNode(b)) {
-    const x = mergeTypeRefLit(name, a, b);
-    const fake: Object = v;
+    const x = mergeTypeRefLit(a, b);
+    const fake: CreateMutable<ts.PropertySignature> = v;
     fake['type'] = x;
     check(fake as ts.PropertySignature, '565');
     pm.set(name, fake as ts.PropertySignature);
     return;
   }
   if (ts.isTypeLiteralNode(a) && ts.isTypeLiteralNode(b)) {
-    const x = mergeTypeLitLit(name, a, b);
-    const fake: Object = v;
+    const x = mergeTypeLitLit(a, b);
+    const fake: CreateMutable<ts.PropertySignature> = v;
     fake['type'] = x;
     check(fake as ts.PropertySignature, '578');
     pm.set(name, fake as ts.PropertySignature);
@@ -575,7 +575,8 @@
   console.log(`577 ${pm.get(name).getText()}\n${v.getText()}`);
   throw new Error(`578 should merge ${strKind(a)} and ${strKind(b)} for ${name}`);
 }
-function addToProperties(pm: propMap, tn: ts.TypeNode, prefix = '') {
+function addToProperties(pm: propMap, tn: ts.TypeNode | undefined, prefix = '') {
+  if (!tn) return;
   if (ts.isTypeReferenceNode(tn)) {
     const d = seenTypes.get(goName(tn.typeName.getText()));
     if (tn.typeName.getText() === 'T') return;
@@ -602,9 +603,9 @@
     });
   }
 }
-function deepProperties(d: Data): propMap {
+function deepProperties(d: Data): propMap | undefined {
   let properties: propMap = new Map<string, ts.PropertySignature>();
-  if (!d.alias || !ts.isIntersectionTypeNode(d.alias)) return;
+  if (!d.alias || !ts.isIntersectionTypeNode(d.alias)) return undefined;
   d.alias.types.forEach((ts) => addToProperties(properties, ts));
   return properties;
 }
@@ -625,19 +626,19 @@
   d.properties = ts.factory.createNodeArray(v);
 }
 
-function mergeTypeLitLit(name: string, a: ts.TypeLiteralNode, b: ts.TypeLiteralNode): ts.TypeLiteralNode {
+function mergeTypeLitLit(a: ts.TypeLiteralNode, b: ts.TypeLiteralNode): ts.TypeLiteralNode {
   const v = new Map<string, ts.TypeElement>(); // avoid duplicates
   a.members.forEach((te) => v.set(te.name.getText(), te));
   b.members.forEach((te) => v.set(te.name.getText(), te));
   const x: ts.TypeElement[] = [];
   v.forEach((te) => x.push(te));
-  const fake: Object = a;
-  fake['members'] = x;
+  const fake: CreateMutable<ts.TypeLiteralNode> = a;
+  fake['members'] = ts.factory.createNodeArray(x);
   check(fake as ts.TypeLiteralNode, '643');
   return fake as ts.TypeLiteralNode;
 }
 
-function mergeTypeRefLit(name: string, a: ts.TypeReferenceNode, b: ts.TypeLiteralNode): ts.TypeLiteralNode {
+function mergeTypeRefLit(a: ts.TypeReferenceNode, b: ts.TypeLiteralNode): ts.TypeLiteralNode {
   const d = seenTypes.get(goName(a.typeName.getText()));
   if (!d) throw new Error(`644 name ${a.typeName.getText()} not found`);
   const typ = d.me;
@@ -649,10 +650,10 @@
   v.forEach((te) => x.push(te));
 
   const w = ts.factory.createNodeArray(x);
-  const fk: Object = b;
+  const fk: CreateMutable<ts.TypeLiteralNode> = b;
   fk['members'] = w;
-  fk['members']['pos'] = b.members.pos;
-  fk['members']['end'] = b.members.end;
+  (fk['members'] as { pos: number })['pos'] = b.members.pos;
+  (fk['members'] as { end: number })['end'] = b.members.end;
   check(fk as ts.TypeLiteralNode, '662');
   return fk as ts.TypeLiteralNode;
 }
@@ -801,7 +802,8 @@
 }
 
 // return a go type and maybe an assocated javascript tag
-function goType(n: ts.TypeNode, nm: string): string {
+function goType(n: ts.TypeNode | undefined, nm: string): string {
+  if (!n) throw new Error(`goType undefined for ${nm}`);
   if (n.getText() == 'T') return 'interface{}';  // should check it's generic
   if (ts.isTypeReferenceNode(n)) {
     switch (n.getText()) {
@@ -1305,8 +1307,8 @@
     side.fd = fs.openSync(side.outputFile, 'w');
   }
   const f = function (s: string) {
-    fs.writeSync(side.fd, s);
-    fs.writeSync(side.fd, '\n');
+    fs.writeSync(side.fd!, s);
+    fs.writeSync(side.fd!, '\n');
   };
   f(u.computeHeader(false));
   f(`
diff --git a/internal/lsp/protocol/typescript/tsconfig.json b/internal/lsp/protocol/typescript/tsconfig.json
new file mode 100644
index 0000000..14cfe0c
--- /dev/null
+++ b/internal/lsp/protocol/typescript/tsconfig.json
@@ -0,0 +1,29 @@
+{
+    "compilerOptions": {
+        "isolatedModules": true,
+        "moduleResolution": "node",
+        "lib":["ES2020"],
+        "sourceMap": true, // sourceMap or inlineSourceMap? and see inlineSources
+        "target": "ES5",
+
+        "noFallthroughCasesInSwitch": false, // there is one legitimate on
+        "noImplicitReturns": true,
+        "noPropertyAccessFromIndexSignature": true,
+        "noUncheckedIndexedAccess": true,
+        "noUnusedLocals": true,
+        "noUnusedParameters": false,
+        "noEmitOnError": true,
+
+        // "extendedDiagnostics": true, // for occasional amusement
+
+        // "strict": true, // too many undefineds in types, etc
+        "alwaysStrict": true,
+        "noImplicitAny": true,
+        "noImplicitThis": true,
+        "strictBindCallApply": true,
+        "strictFunctionTypes": true,
+        "strictNullChecks": false, // doesn't like arrray access, among other things.
+        //"strictPropertyInitialization": true, // needs strictNullChecks
+    },
+    "files": ["./code.ts", "./util.ts"]
+}
diff --git a/internal/lsp/protocol/typescript/util.ts b/internal/lsp/protocol/typescript/util.ts
index 09c8aae..a4f5d7e 100644
--- a/internal/lsp/protocol/typescript/util.ts
+++ b/internal/lsp/protocol/typescript/util.ts
@@ -58,7 +58,7 @@
 // Produce a header for Go output files
 export function computeHeader(pkgDoc: boolean): string {
   let lastMod = 0;
-  let lastDate: Date;
+  let lastDate = new Date();
   for (const f of fnames) {
     const st = fs.statSync(f);
     if (st.mtimeMs > lastMod) {
@@ -90,6 +90,7 @@
 export function goName(s: string): string {
   let ans = s;
   if (s.charAt(0) == '_') {
+    // in the end, none of these are emitted.
     ans = 'Inner' + s.substring(1);
   }
   else { ans = s.substring(0, 1).toUpperCase() + s.substring(1); }
@@ -100,8 +101,7 @@
 
 // Generate JSON tag for a struct field
 export function JSON(n: ts.PropertySignature): string {
-  const json = `\`json:"${n.name.getText()}${
-    n.questionToken != undefined ? ',omitempty' : ''}"\``;
+  const json = `\`json:"${n.name.getText()}${n.questionToken !== undefined ? ',omitempty' : ''}"\``;
   return json;
 }
 
@@ -149,18 +149,19 @@
   }
   pra('\n');
   for (const key of Object.keys(seenThings).sort()) {
-    pra(`${key}: ${seenThings[key]} \n`);
+    pra(`${key}: ${seenThings.get(key)} \n`);
   }
 }
 
 // Used in printing the AST
 let seenThings = new Map<string, number>();
 function seenAdd(x: string) {
-  seenThings[x] = (seenThings[x] === undefined ? 1 : seenThings[x] + 1);
+  const u = seenThings.get(x);
+  seenThings.set(x, u === undefined ? 1 : u + 1);
 }
 
 // eslint-disable-next-line no-unused-vars
-function describe(node: ts.Node, pr: (s: string) => any) {
+function describe(node: ts.Node, pr: (_: string) => any) {
   if (node === undefined) {
     return;
   }
@@ -191,7 +192,8 @@
 
 
 // For debugging, say where an AST node is in a file
-export function loc(node: ts.Node): string {
+export function loc(node: ts.Node | undefined): string {
+  if (!node) throw new Error('loc called with undefined (cannot happen!)');
   const sf = node.getSourceFile();
   const start = node.getStart();
   const x = sf.getLineAndCharacterOfPosition(start);
@@ -200,9 +202,9 @@
   let fn = sf.fileName;
   const n = fn.search(/-node./);
   fn = fn.substring(n + 6);
-  return `${fn} ${x.line + 1}: ${x.character + 1} (${y.line + 1}: ${
-    y.character + 1})`;
+  return `${fn} ${x.line + 1}: ${x.character + 1} (${y.line + 1}: ${y.character + 1})`;
 }
+
 // --- various string stuff
 
 // return a string of the kinds of the immediate descendants
@@ -217,15 +219,14 @@
 // What kind of AST node is it? This would just be typescript's
 // SyntaxKind[n.kind] except that the default names for some nodes
 // are misleading
-export function strKind(n: ts.Node): string {
+export function strKind(n: ts.Node | undefined): string {
   if (n == null || n == undefined) {
     return 'null';
   }
-   return kindToStr(n.kind);
+  return kindToStr(n.kind);
 }
 
-export function kindToStr(k: ts.SyntaxKind): string {
-  if (k === undefined) return 'unDefined';
+function kindToStr(k: ts.SyntaxKind): string {
   const x = ts.SyntaxKind[k];
   // some of these have two names
   switch (x) {
diff --git a/internal/lsp/semantic.go b/internal/lsp/semantic.go
index 7f168bc..fbca581 100644
--- a/internal/lsp/semantic.go
+++ b/internal/lsp/semantic.go
@@ -394,11 +394,15 @@
 		// nothing to map it to
 	case *types.Nil:
 		// nil is a predeclared identifier
-		e.token(x.Pos(), len("nil"), tokVariable, []string{"readonly"})
+		e.token(x.Pos(), len("nil"), tokVariable, []string{"readonly", "defaultLibrary"})
 	case *types.PkgName:
 		e.token(x.Pos(), len(x.Name), tokNamespace, nil)
 	case *types.TypeName:
-		e.token(x.Pos(), len(x.String()), tokType, nil)
+		var mods []string
+		if _, ok := y.Type().(*types.Basic); ok {
+			mods = []string{"defaultLibrary"}
+		}
+		e.token(x.Pos(), len(x.String()), tokType, mods)
 	case *types.Var:
 		e.token(x.Pos(), len(x.Name), tokVariable, nil)
 	default:
@@ -447,6 +451,15 @@
 		case *ast.InterfaceType:
 			return tokMember, mods
 		case *ast.TypeSpec:
+			// GenDecl/Typespec/FuncType/FieldList/Field/Ident
+			// (type A func(b uint64)) (err error)
+			// b and err should not be tokType, but tokVaraible
+			// and in GenDecl/TpeSpec/StructType/FieldList/Field/Ident
+			// (type A struct{b uint64})
+			fldm := e.stack[len(e.stack)-2]
+			if _, ok := fldm.(*ast.Field); ok {
+				return tokVariable, mods
+			}
 			return tokType, mods
 		}
 	}
diff --git a/internal/lsp/server.go b/internal/lsp/server.go
index 793ee5d..dd6d6e2 100644
--- a/internal/lsp/server.go
+++ b/internal/lsp/server.go
@@ -64,13 +64,13 @@
 
 	stateMu sync.Mutex
 	state   serverState
-
-	session   source.Session
-	clientPID int
-
 	// notifications generated before serverInitialized
 	notifications []*protocol.ShowMessageParams
 
+	session source.Session
+
+	tempDir string
+
 	// changedFiles tracks files for which there has been a textDocument/didChange.
 	changedFilesMu sync.Mutex
 	changedFiles   map[span.URI]struct{}
diff --git a/internal/lsp/snippet/snippet_builder.go b/internal/lsp/snippet/snippet_builder.go
index d518980..f7fc5b4 100644
--- a/internal/lsp/snippet/snippet_builder.go
+++ b/internal/lsp/snippet/snippet_builder.go
@@ -46,6 +46,10 @@
 	b.sb.WriteString(rawSnip)
 }
 
+func (b *Builder) Write(data []byte) (int, error) {
+	return b.sb.Write(data)
+}
+
 // WritePlaceholder writes a tab stop and placeholder value to the Builder.
 // The callback style allows for creating nested placeholders. To write an
 // empty tab stop, provide a nil callback.
diff --git a/internal/lsp/source/api_json.go b/internal/lsp/source/api_json.go
index 8f72405..a106c61 100755
--- a/internal/lsp/source/api_json.go
+++ b/internal/lsp/source/api_json.go
@@ -222,6 +222,19 @@
 				Hierarchy: "ui.completion",
 			},
 			{
+				Name: "experimentalPostfixCompletions",
+				Type: "bool",
+				Doc:  "experimentalPostfixCompletions enables artifical method snippets\nsuch as \"someSlice.sort!\".\n",
+				EnumKeys: EnumKeys{
+					ValueType: "",
+					Keys:      nil,
+				},
+				EnumValues: nil,
+				Default:    "false",
+				Status:     "experimental",
+				Hierarchy:  "ui.completion",
+			},
+			{
 				Name: "importShortcut",
 				Type: "enum",
 				Doc:  "importShortcut specifies whether import statements should link to\ndocumentation or go to definitions.\n",
@@ -790,6 +803,12 @@
 			Doc:     "Runs `go mod vendor` for a module.",
 			ArgDoc:  "{\n\t// The file URI.\n\t\"URI\": string,\n}",
 		},
+		{
+			Command: "gopls.workspace_metadata",
+			Title:   "",
+			Doc:     "",
+			ArgDoc:  "",
+		},
 	},
 	Lenses: []*LensJSON{
 		{
diff --git a/internal/lsp/source/completion/completion.go b/internal/lsp/source/completion/completion.go
index de6e53f..8864081 100644
--- a/internal/lsp/source/completion/completion.go
+++ b/internal/lsp/source/completion/completion.go
@@ -96,6 +96,7 @@
 	placeholders      bool
 	literal           bool
 	snippets          bool
+	postfix           bool
 	matcher           source.Matcher
 	budget            time.Duration
 }
@@ -521,6 +522,7 @@
 			literal:           opts.LiteralCompletions && opts.InsertTextFormat == protocol.SnippetTextFormat,
 			budget:            opts.CompletionBudget,
 			snippets:          opts.InsertTextFormat == protocol.SnippetTextFormat,
+			postfix:           opts.ExperimentalPostfixCompletions,
 		},
 		// default to a matcher that always matches
 		matcher:        prefixMatcher(""),
@@ -1104,6 +1106,9 @@
 		for _, cand := range candidates {
 			c.deepState.enqueue(cand)
 		}
+
+		c.addPostfixSnippetCandidates(ctx, sel)
+
 		return nil
 	}
 
diff --git a/internal/lsp/source/completion/format.go b/internal/lsp/source/completion/format.go
index ec67060..6d8299c 100644
--- a/internal/lsp/source/completion/format.go
+++ b/internal/lsp/source/completion/format.go
@@ -158,7 +158,7 @@
 	if prefix != "" {
 		// If we are in a selector, add an edit to place prefix before selector.
 		if sel := enclosingSelector(c.path, c.pos); sel != nil {
-			edits, err := prependEdit(c.snapshot.FileSet(), c.mapper, sel, prefix)
+			edits, err := c.editText(sel.Pos(), sel.Pos(), prefix)
 			if err != nil {
 				return CompletionItem{}, err
 			}
@@ -229,7 +229,7 @@
 		return item, nil
 	}
 
-	hover, err := source.HoverInfo(ctx, pkg, obj, decl)
+	hover, err := source.HoverInfo(ctx, c.snapshot, pkg, obj, decl)
 	if err != nil {
 		event.Error(ctx, "failed to find Hover", err, tag.URI.Of(uri))
 		return item, nil
diff --git a/internal/lsp/source/completion/literal.go b/internal/lsp/source/completion/literal.go
index 2c75310..0938e02 100644
--- a/internal/lsp/source/completion/literal.go
+++ b/internal/lsp/source/completion/literal.go
@@ -7,14 +7,11 @@
 import (
 	"context"
 	"fmt"
-	"go/ast"
-	"go/token"
 	"go/types"
 	"strings"
 	"unicode"
 
 	"golang.org/x/tools/internal/event"
-	"golang.org/x/tools/internal/lsp/diff"
 	"golang.org/x/tools/internal/lsp/protocol"
 	"golang.org/x/tools/internal/lsp/snippet"
 	"golang.org/x/tools/internal/lsp/source"
@@ -111,7 +108,7 @@
 				// If we are in a selector we must place the "&" before the selector.
 				// For example, "foo.B<>" must complete to "&foo.Bar{}", not
 				// "foo.&Bar{}".
-				edits, err := prependEdit(c.snapshot.FileSet(), c.mapper, sel, "&")
+				edits, err := c.editText(sel.Pos(), sel.Pos(), "&")
 				if err != nil {
 					event.Error(ctx, "error making edit for literal pointer completion", err)
 					return
@@ -168,20 +165,6 @@
 	}
 }
 
-// prependEdit produces text edits that preprend the specified prefix
-// to the specified node.
-func prependEdit(fset *token.FileSet, m *protocol.ColumnMapper, node ast.Node, prefix string) ([]protocol.TextEdit, error) {
-	rng := source.NewMappedRange(fset, m, node.Pos(), node.Pos())
-	spn, err := rng.Span()
-	if err != nil {
-		return nil, err
-	}
-	return source.ToProtocolEdits(m, []diff.TextEdit{{
-		Span:    spn,
-		NewText: prefix,
-	}})
-}
-
 // literalCandidateScore is the base score for literal candidates.
 // Literal candidates match the expected type so they should be high
 // scoring, but we want them ranked below lexical objects of the
diff --git a/internal/lsp/source/completion/postfix_snippets.go b/internal/lsp/source/completion/postfix_snippets.go
new file mode 100644
index 0000000..2c3c6e9
--- /dev/null
+++ b/internal/lsp/source/completion/postfix_snippets.go
@@ -0,0 +1,436 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package completion
+
+import (
+	"context"
+	"fmt"
+	"go/ast"
+	"go/token"
+	"go/types"
+	"log"
+	"reflect"
+	"strings"
+	"sync"
+	"text/template"
+
+	"golang.org/x/tools/internal/event"
+	"golang.org/x/tools/internal/imports"
+	"golang.org/x/tools/internal/lsp/protocol"
+	"golang.org/x/tools/internal/lsp/snippet"
+	"golang.org/x/tools/internal/lsp/source"
+	errors "golang.org/x/xerrors"
+)
+
+// Postfix snippets are artificial methods that allow the user to
+// compose common operations in an "argument oriented" fashion. For
+// example, instead of "sort.Slice(someSlice, ...)" a user can expand
+// "someSlice.sort!".
+
+// postfixTmpl represents a postfix snippet completion candidate.
+type postfixTmpl struct {
+	// label is the completion candidate's label presented to the user.
+	label string
+
+	// details is passed along to the client as the candidate's details.
+	details string
+
+	// body is the template text. See postfixTmplArgs for details on the
+	// facilities available to the template.
+	body string
+
+	tmpl *template.Template
+}
+
+// postfixTmplArgs are the template execution arguments available to
+// the postfix snippet templates.
+type postfixTmplArgs struct {
+	// StmtOK is true if it is valid to replace the selector with a
+	// statement. For example:
+	//
+	//    func foo() {
+	//      bar.sort! // statement okay
+	//
+	//      someMethod(bar.sort!) // statement not okay
+	//    }
+	StmtOK bool
+
+	// X is the textual SelectorExpr.X. For example, when completing
+	// "foo.bar.print!", "X" is "foo.bar".
+	X string
+
+	// Obj is the types.Object of SelectorExpr.X, if any.
+	Obj types.Object
+
+	// Type is the type of "foo.bar" in "foo.bar.print!".
+	Type types.Type
+
+	scope          *types.Scope
+	snip           snippet.Builder
+	importIfNeeded func(pkgPath string, scope *types.Scope) (name string, edits []protocol.TextEdit, err error)
+	edits          []protocol.TextEdit
+	qf             types.Qualifier
+	varNames       map[string]bool
+}
+
+var postfixTmpls = []postfixTmpl{{
+	label:   "sort",
+	details: "sort.Slice()",
+	body: `{{if and (eq .Kind "slice") .StmtOK -}}
+{{.Import "sort"}}.Slice({{.X}}, func({{.VarName nil "i"}}, {{.VarName nil "j"}} int) bool {
+	{{.Cursor}}
+})
+{{- end}}`,
+}, {
+	label:   "last",
+	details: "s[len(s)-1]",
+	body: `{{if and (eq .Kind "slice") .Obj -}}
+{{.X}}[len({{.X}})-1]
+{{- end}}`,
+}, {
+	label:   "reverse",
+	details: "reverse slice",
+	body: `{{if and (eq .Kind "slice") .StmtOK -}}
+{{$i := .VarName nil "i"}}{{$j := .VarName nil "j" -}}
+for {{$i}}, {{$j}} := 0, len({{.X}})-1; {{$i}} < {{$j}}; {{$i}}, {{$j}} = {{$i}}+1, {{$j}}-1 {
+	{{.X}}[{{$i}}], {{.X}}[{{$j}}] = {{.X}}[{{$j}}], {{.X}}[{{$i}}]
+}
+{{end}}`,
+}, {
+	label:   "range",
+	details: "range over slice",
+	body: `{{if and (eq .Kind "slice") .StmtOK -}}
+for {{.VarName nil "i"}}, {{.VarName .ElemType "v"}} := range {{.X}} {
+	{{.Cursor}}
+}
+{{- end}}`,
+}, {
+	label:   "append",
+	details: "append and re-assign slice",
+	body: `{{if and (eq .Kind "slice") .StmtOK .Obj -}}
+{{.X}} = append({{.X}}, {{.Cursor}})
+{{- end}}`,
+}, {
+	label:   "append",
+	details: "append to slice",
+	body: `{{if and (eq .Kind "slice") (not .StmtOK) -}}
+append({{.X}}, {{.Cursor}})
+{{- end}}`,
+}, {
+	label:   "copy",
+	details: "duplicate slice",
+	body: `{{if and (eq .Kind "slice") .StmtOK .Obj -}}
+{{$v := (.VarName nil (printf "%sCopy" .X))}}{{$v}} := make([]{{.TypeName .ElemType}}, len({{.X}}))
+copy({{$v}}, {{.X}})
+{{end}}`,
+}, {
+	label:   "range",
+	details: "range over map",
+	body: `{{if and (eq .Kind "map") .StmtOK -}}
+for {{.VarName .KeyType "k"}}, {{.VarName .ElemType "v"}} := range {{.X}} {
+	{{.Cursor}}
+}
+{{- end}}`,
+}, {
+	label:   "clear",
+	details: "clear map contents",
+	body: `{{if and (eq .Kind "map") .StmtOK -}}
+{{$k := (.VarName .KeyType "k")}}for {{$k}} := range {{.X}} {
+	delete({{.X}}, {{$k}})
+}
+{{end}}`,
+}, {
+	label:   "keys",
+	details: "create slice of keys",
+	body: `{{if and (eq .Kind "map") .StmtOK -}}
+{{$keysVar := (.VarName nil "keys")}}{{$keysVar}} := make([]{{.TypeName .KeyType}}, 0, len({{.X}}))
+{{$k := (.VarName .KeyType "k")}}for {{$k}} := range {{.X}} {
+	{{$keysVar}} = append({{$keysVar}}, {{$k}})
+}
+{{end}}`,
+}, {
+	label:   "var",
+	details: "assign to variables",
+	body: `{{if and (eq .Kind "tuple") .StmtOK -}}
+{{$a := .}}{{range $i, $v := .Tuple}}{{if $i}}, {{end}}{{$a.VarName $v.Type $v.Name}}{{end}} := {{.X}}
+{{- end}}`,
+}, {
+	label:   "var",
+	details: "assign to variable",
+	body: `{{if and (ne .Kind "tuple") .StmtOK -}}
+{{.VarName .Type ""}} := {{.X}}
+{{- end}}`,
+}, {
+	label:   "print",
+	details: "print to stdout",
+	body: `{{if and (ne .Kind "tuple") .StmtOK -}}
+{{.Import "fmt"}}.Printf("{{.EscapeQuotes .X}}: %v\n", {{.X}})
+{{- end}}`,
+}, {
+	label:   "print",
+	details: "print to stdout",
+	body: `{{if and (eq .Kind "tuple") .StmtOK -}}
+{{.Import "fmt"}}.Println({{.X}})
+{{- end}}`,
+}}
+
+// Cursor indicates where the client's cursor should end up after the
+// snippet is done.
+func (a *postfixTmplArgs) Cursor() string {
+	a.snip.WriteFinalTabstop()
+	return ""
+}
+
+// Import makes sure the package corresponding to path is imported,
+// returning the identifier to use to refer to the package.
+func (a *postfixTmplArgs) Import(path string) (string, error) {
+	name, edits, err := a.importIfNeeded(path, a.scope)
+	if err != nil {
+		return "", errors.Errorf("couldn't import %q: %w", path, err)
+	}
+	a.edits = append(a.edits, edits...)
+	return name, nil
+}
+
+func (a *postfixTmplArgs) EscapeQuotes(v string) string {
+	return strings.ReplaceAll(v, `"`, `\\"`)
+}
+
+// ElemType returns the Elem() type of xType, if applicable.
+func (a *postfixTmplArgs) ElemType() types.Type {
+	if e, _ := a.Type.(interface{ Elem() types.Type }); e != nil {
+		return e.Elem()
+	}
+	return nil
+}
+
+// Kind returns the underlying kind of type, e.g. "slice", "struct",
+// etc.
+func (a *postfixTmplArgs) Kind() string {
+	t := reflect.TypeOf(a.Type.Underlying())
+	return strings.ToLower(strings.TrimPrefix(t.String(), "*types."))
+}
+
+// KeyType returns the type of X's key. KeyType panics if X is not a
+// map.
+func (a *postfixTmplArgs) KeyType() types.Type {
+	return a.Type.Underlying().(*types.Map).Key()
+}
+
+// Tuple returns the tuple result vars if X is a call expression.
+func (a *postfixTmplArgs) Tuple() []*types.Var {
+	tuple, _ := a.Type.(*types.Tuple)
+	if tuple == nil {
+		return nil
+	}
+
+	typs := make([]*types.Var, 0, tuple.Len())
+	for i := 0; i < tuple.Len(); i++ {
+		typs = append(typs, tuple.At(i))
+	}
+	return typs
+}
+
+// TypeName returns the textual representation of type t.
+func (a *postfixTmplArgs) TypeName(t types.Type) (string, error) {
+	if t == nil || t == types.Typ[types.Invalid] {
+		return "", fmt.Errorf("invalid type: %v", t)
+	}
+	return types.TypeString(t, a.qf), nil
+}
+
+// VarName returns a suitable variable name for the type t. If t
+// implements the error interface, "err" is used. If t is not a named
+// type then nonNamedDefault is used. Otherwise a name is made by
+// abbreviating the type name. If the resultant name is already in
+// scope, an integer is appended to make a unique name.
+func (a *postfixTmplArgs) VarName(t types.Type, nonNamedDefault string) string {
+	if t == nil {
+		t = types.Typ[types.Invalid]
+	}
+
+	var name string
+	if types.Implements(t, errorIntf) {
+		name = "err"
+	} else if _, isNamed := source.Deref(t).(*types.Named); !isNamed {
+		name = nonNamedDefault
+	}
+
+	if name == "" {
+		name = types.TypeString(t, func(p *types.Package) string {
+			return ""
+		})
+		name = abbreviateTypeName(name)
+	}
+
+	if dot := strings.LastIndex(name, "."); dot > -1 {
+		name = name[dot+1:]
+	}
+
+	uniqueName := name
+	for i := 2; ; i++ {
+		if s, _ := a.scope.LookupParent(uniqueName, token.NoPos); s == nil && !a.varNames[uniqueName] {
+			break
+		}
+		uniqueName = fmt.Sprintf("%s%d", name, i)
+	}
+
+	a.varNames[uniqueName] = true
+
+	return uniqueName
+}
+
+func (c *completer) addPostfixSnippetCandidates(ctx context.Context, sel *ast.SelectorExpr) {
+	if !c.opts.postfix {
+		return
+	}
+
+	initPostfixRules()
+
+	if sel == nil || sel.Sel == nil {
+		return
+	}
+
+	selType := c.pkg.GetTypesInfo().TypeOf(sel.X)
+	if selType == nil {
+		return
+	}
+
+	// Skip empty tuples since there is no value to operate on.
+	if tuple, ok := selType.Underlying().(*types.Tuple); ok && tuple == nil {
+		return
+	}
+
+	// Only replace sel with a statement if sel is already a statement.
+	var stmtOK bool
+	for i, n := range c.path {
+		if n == sel && i < len(c.path)-1 {
+			_, stmtOK = c.path[i+1].(*ast.ExprStmt)
+			break
+		}
+	}
+
+	scope := c.pkg.GetTypes().Scope().Innermost(c.pos)
+	if scope == nil {
+		return
+	}
+
+	// afterDot is the position after selector dot, e.g. "|" in
+	// "foo.|print".
+	afterDot := sel.Sel.Pos()
+
+	// We must detect dangling selectors such as:
+	//
+	//    foo.<>
+	//    bar
+	//
+	// and adjust afterDot so that we don't mistakenly delete the
+	// newline thinking "bar" is part of our selector.
+	tokFile := c.snapshot.FileSet().File(c.pos)
+	if startLine := tokFile.Line(sel.Pos()); startLine != tokFile.Line(afterDot) {
+		if tokFile.Line(c.pos) != startLine {
+			return
+		}
+		afterDot = c.pos
+	}
+
+	for _, rule := range postfixTmpls {
+		// When completing foo.print<>, "print" is naturally overwritten,
+		// but we need to also remove "foo." so the snippet has a clean
+		// slate.
+		edits, err := c.editText(sel.Pos(), afterDot, "")
+		if err != nil {
+			event.Error(ctx, "error calculating postfix edits", err)
+			return
+		}
+
+		tmplArgs := postfixTmplArgs{
+			X:              source.FormatNode(c.snapshot.FileSet(), sel.X),
+			StmtOK:         stmtOK,
+			Obj:            exprObj(c.pkg.GetTypesInfo(), sel.X),
+			Type:           selType,
+			qf:             c.qf,
+			importIfNeeded: c.importIfNeeded,
+			scope:          scope,
+			varNames:       make(map[string]bool),
+		}
+
+		// Feed the template straight into the snippet builder. This
+		// allows templates to build snippets as they are executed.
+		err = rule.tmpl.Execute(&tmplArgs.snip, &tmplArgs)
+		if err != nil {
+			event.Error(ctx, "error executing postfix template", err)
+			continue
+		}
+
+		if strings.TrimSpace(tmplArgs.snip.String()) == "" {
+			continue
+		}
+
+		score := c.matcher.Score(rule.label)
+		if score <= 0 {
+			continue
+		}
+
+		c.items = append(c.items, CompletionItem{
+			Label:               rule.label + "!",
+			Detail:              rule.details,
+			Score:               float64(score) * 0.01,
+			Kind:                protocol.SnippetCompletion,
+			snippet:             &tmplArgs.snip,
+			AdditionalTextEdits: append(edits, tmplArgs.edits...),
+		})
+	}
+}
+
+var postfixRulesOnce sync.Once
+
+func initPostfixRules() {
+	postfixRulesOnce.Do(func() {
+		var idx int
+		for _, rule := range postfixTmpls {
+			var err error
+			rule.tmpl, err = template.New("postfix_snippet").Parse(rule.body)
+			if err != nil {
+				log.Panicf("error parsing postfix snippet template: %v", err)
+			}
+			postfixTmpls[idx] = rule
+			idx++
+		}
+		postfixTmpls = postfixTmpls[:idx]
+	})
+}
+
+// importIfNeeded returns the package identifier and any necessary
+// edits to import package pkgPath.
+func (c *completer) importIfNeeded(pkgPath string, scope *types.Scope) (string, []protocol.TextEdit, error) {
+	defaultName := imports.ImportPathToAssumedName(pkgPath)
+
+	// Check if file already imports pkgPath.
+	for _, s := range c.file.Imports {
+		if source.ImportPath(s) == pkgPath {
+			if s.Name == nil {
+				return defaultName, nil, nil
+			}
+			if s.Name.Name != "_" {
+				return s.Name.Name, nil, nil
+			}
+		}
+	}
+
+	// Give up if the package's name is already in use by another object.
+	if _, obj := scope.LookupParent(defaultName, token.NoPos); obj != nil {
+		return "", nil, fmt.Errorf("import name %q of %q already in use", defaultName, pkgPath)
+	}
+
+	edits, err := c.importEdits(&importInfo{
+		importPath: pkgPath,
+	})
+	if err != nil {
+		return "", nil, err
+	}
+
+	return defaultName, edits, nil
+}
diff --git a/internal/lsp/source/completion/statements.go b/internal/lsp/source/completion/statements.go
index 62d3cf0..3280bb5 100644
--- a/internal/lsp/source/completion/statements.go
+++ b/internal/lsp/source/completion/statements.go
@@ -18,7 +18,7 @@
 // addStatementCandidates adds full statement completion candidates
 // appropriate for the current context.
 func (c *completer) addStatementCandidates() {
-	c.addErrCheckAndReturn()
+	c.addErrCheck()
 	c.addAssignAppend()
 }
 
@@ -162,27 +162,36 @@
 	return bestItem
 }
 
-// addErrCheckAndReturn offers a completion candidate of the form:
+// addErrCheck offers a completion candidate of the form:
 //
 //     if err != nil {
 //       return nil, err
 //     }
 //
+// In the case of test functions, it offers a completion candidate of the form:
+//
+//     if err != nil {
+//       t.Fatal(err)
+//     }
+//
 // The position must be in a function that returns an error, and the
 // statement preceding the position must be an assignment where the
-// final LHS object is an error. addErrCheckAndReturn will synthesize
+// final LHS object is an error. addErrCheck will synthesize
 // zero values as necessary to make the return statement valid.
-func (c *completer) addErrCheckAndReturn() {
+func (c *completer) addErrCheck() {
 	if len(c.path) < 2 || c.enclosingFunc == nil || !c.opts.placeholders {
 		return
 	}
 
 	var (
-		errorType = types.Universe.Lookup("error").Type()
-		result    = c.enclosingFunc.sig.Results()
+		errorType        = types.Universe.Lookup("error").Type()
+		result           = c.enclosingFunc.sig.Results()
+		testVar          = getTestVar(c.enclosingFunc, c.pkg)
+		isTest           = testVar != ""
+		doesNotReturnErr = result.Len() == 0 || !types.Identical(result.At(result.Len()-1).Type(), errorType)
 	)
-	// Make sure our enclosing function returns an error.
-	if result.Len() == 0 || !types.Identical(result.At(result.Len()-1).Type(), errorType) {
+	// Make sure our enclosing function is a Test func or returns an error.
+	if !isTest && doesNotReturnErr {
 		return
 	}
 
@@ -205,15 +214,17 @@
 	}
 
 	var (
-		// errText is e.g. "err" in "foo, err := bar()".
-		errText = source.FormatNode(c.snapshot.FileSet(), lastAssignee)
+		// errVar is e.g. "err" in "foo, err := bar()".
+		errVar = source.FormatNode(c.snapshot.FileSet(), lastAssignee)
 
 		// Whether we need to include the "if" keyword in our candidate.
 		needsIf = true
 	)
 
-	// "_" isn't a real object.
-	if errText == "_" {
+	// If the returned error from the previous statement is "_", it is not a real object.
+	// If we don't have an error, and the function signature takes a testing.TB that is either ignored
+	// or an "_", then we also can't call t.Fatal(err).
+	if errVar == "_" {
 		return
 	}
 
@@ -240,7 +251,7 @@
 			//     if er<>
 
 			// Make sure they are typing the error's name.
-			if c.matcher.Score(errText) <= 0 {
+			if c.matcher.Score(errVar) <= 0 {
 				return
 			}
 
@@ -277,20 +288,26 @@
 	if needsIf {
 		snip.WriteText("if ")
 	}
-	snip.WriteText(fmt.Sprintf("%s != nil {\n\treturn ", errText))
+	snip.WriteText(fmt.Sprintf("%s != nil {\n\t", errVar))
 
-	for i := 0; i < result.Len()-1; i++ {
-		snip.WriteText(formatZeroValue(result.At(i).Type(), c.qf))
-		snip.WriteText(", ")
+	var label string
+	if isTest {
+		snip.WriteText(fmt.Sprintf("%s.Fatal(%s)", testVar, errVar))
+		label = fmt.Sprintf("%[1]s != nil { %[2]s.Fatal(%[1]s) }", errVar, testVar)
+	} else {
+		snip.WriteText("return ")
+		for i := 0; i < result.Len()-1; i++ {
+			snip.WriteText(formatZeroValue(result.At(i).Type(), c.qf))
+			snip.WriteText(", ")
+		}
+		snip.WritePlaceholder(func(b *snippet.Builder) {
+			b.WriteText(errVar)
+		})
+		label = fmt.Sprintf("%[1]s != nil { return %[1]s }", errVar)
 	}
 
-	snip.WritePlaceholder(func(b *snippet.Builder) {
-		b.WriteText(errText)
-	})
-
 	snip.WriteText("\n}")
 
-	label := fmt.Sprintf("%[1]s != nil { return %[1]s }", errText)
 	if needsIf {
 		label = "if " + label
 	}
@@ -303,3 +320,41 @@
 		snippet: &snip,
 	})
 }
+
+// getTestVar checks the function signature's input parameters and returns
+// the name of the first parameter that implements "testing.TB". For example,
+// func someFunc(t *testing.T) returns the string "t", func someFunc(b *testing.B)
+// returns "b" etc. An empty string indicates that the function signature
+// does not take a testing.TB parameter or does so but is ignored such
+// as func someFunc(*testing.T).
+func getTestVar(enclosingFunc *funcInfo, pkg source.Package) string {
+	if enclosingFunc == nil || enclosingFunc.sig == nil {
+		return ""
+	}
+
+	sig := enclosingFunc.sig
+	for i := 0; i < sig.Params().Len(); i++ {
+		param := sig.Params().At(i)
+		if param.Name() == "_" {
+			continue
+		}
+		testingPkg, err := pkg.GetImport("testing")
+		if err != nil {
+			continue
+		}
+		tbObj := testingPkg.GetTypes().Scope().Lookup("TB")
+		if tbObj == nil {
+			continue
+		}
+		iface, ok := tbObj.Type().Underlying().(*types.Interface)
+		if !ok {
+			continue
+		}
+		if !types.Implements(param.Type(), iface) {
+			continue
+		}
+		return param.Name()
+	}
+
+	return ""
+}
diff --git a/internal/lsp/source/completion/util.go b/internal/lsp/source/completion/util.go
index 6733906..505c7e2 100644
--- a/internal/lsp/source/completion/util.go
+++ b/internal/lsp/source/completion/util.go
@@ -9,6 +9,8 @@
 	"go/token"
 	"go/types"
 
+	"golang.org/x/tools/internal/lsp/diff"
+	"golang.org/x/tools/internal/lsp/protocol"
 	"golang.org/x/tools/internal/lsp/source"
 )
 
@@ -310,3 +312,15 @@
 	b, _ := t.Underlying().(*types.Basic)
 	return b != nil && b.Info()&k > 0
 }
+
+func (c *completer) editText(from, to token.Pos, newText string) ([]protocol.TextEdit, error) {
+	rng := source.NewMappedRange(c.snapshot.FileSet(), c.mapper, from, to)
+	spn, err := rng.Span()
+	if err != nil {
+		return nil, err
+	}
+	return source.ToProtocolEdits(c.mapper, []diff.TextEdit{{
+		Span:    spn,
+		NewText: newText,
+	}})
+}
diff --git a/internal/lsp/source/diagnostics.go b/internal/lsp/source/diagnostics.go
index 1948381..58154ca 100644
--- a/internal/lsp/source/diagnostics.go
+++ b/internal/lsp/source/diagnostics.go
@@ -12,9 +12,10 @@
 )
 
 type SuggestedFix struct {
-	Title   string
-	Edits   map[span.URI][]protocol.TextEdit
-	Command *protocol.Command
+	Title      string
+	Edits      map[span.URI][]protocol.TextEdit
+	Command    *protocol.Command
+	ActionKind protocol.CodeActionKind
 }
 
 type RelatedInformation struct {
diff --git a/internal/lsp/source/extract.go b/internal/lsp/source/extract.go
index e7faaff..854dc90 100644
--- a/internal/lsp/source/extract.go
+++ b/internal/lsp/source/extract.go
@@ -276,6 +276,10 @@
 		if _, ok := seenVars[v.obj]; ok {
 			continue
 		}
+		if v.obj.Name() == "_" {
+			// The blank identifier is always a local variable
+			continue
+		}
 		typ := analysisinternal.TypeExpr(fset, file, pkg, v.obj.Type())
 		if typ == nil {
 			return nil, fmt.Errorf("nil AST expression for type: %v", v.obj.Name())
diff --git a/internal/lsp/source/fix.go b/internal/lsp/source/fix.go
index 3918355..6a01239 100644
--- a/internal/lsp/source/fix.go
+++ b/internal/lsp/source/fix.go
@@ -42,10 +42,11 @@
 	ExtractFunction: extractFunction,
 }
 
-func SuggestedFixFromCommand(cmd protocol.Command) SuggestedFix {
+func SuggestedFixFromCommand(cmd protocol.Command, kind protocol.CodeActionKind) SuggestedFix {
 	return SuggestedFix{
-		Title:   cmd.Title,
-		Command: &cmd,
+		Title:      cmd.Title,
+		Command:    &cmd,
+		ActionKind: kind,
 	}
 }
 
diff --git a/internal/lsp/source/highlight.go b/internal/lsp/source/highlight.go
index 3af3f49..7cdb484 100644
--- a/internal/lsp/source/highlight.go
+++ b/internal/lsp/source/highlight.go
@@ -22,10 +22,18 @@
 	ctx, done := event.Start(ctx, "source.Highlight")
 	defer done()
 
-	pkg, pgf, err := GetParsedFile(ctx, snapshot, fh, WidestPackage)
+	// Don't use GetParsedFile because it uses TypecheckWorkspace, and we
+	// always want fully parsed files for highlight, regardless of whether
+	// the file belongs to a workspace package.
+	pkg, err := snapshot.PackageForFile(ctx, fh.URI(), TypecheckFull, WidestPackage)
+	if err != nil {
+		return nil, errors.Errorf("getting package for Highlight: %w", err)
+	}
+	pgf, err := pkg.File(fh.URI())
 	if err != nil {
 		return nil, errors.Errorf("getting file for Highlight: %w", err)
 	}
+
 	spn, err := pgf.Mapper.PointSpan(pos)
 	if err != nil {
 		return nil, err
diff --git a/internal/lsp/source/hover.go b/internal/lsp/source/hover.go
index 8f23d1d..e27216e 100644
--- a/internal/lsp/source/hover.go
+++ b/internal/lsp/source/hover.go
@@ -12,12 +12,14 @@
 	"go/constant"
 	"go/doc"
 	"go/format"
+	"go/token"
 	"go/types"
 	"strings"
 	"time"
 
 	"golang.org/x/tools/internal/event"
 	"golang.org/x/tools/internal/lsp/protocol"
+	"golang.org/x/tools/internal/span"
 	errors "golang.org/x/xerrors"
 )
 
@@ -93,7 +95,7 @@
 	defer done()
 
 	fset := i.Snapshot.FileSet()
-	h, err := HoverInfo(ctx, i.pkg, i.Declaration.obj, i.Declaration.node)
+	h, err := HoverInfo(ctx, i.Snapshot, i.pkg, i.Declaration.obj, i.Declaration.node)
 	if err != nil {
 		return nil, err
 	}
@@ -252,7 +254,7 @@
 
 // HoverInfo returns a HoverInformation struct for an ast node and its type
 // object.
-func HoverInfo(ctx context.Context, pkg Package, obj types.Object, node ast.Node) (*HoverInformation, error) {
+func HoverInfo(ctx context.Context, s Snapshot, pkg Package, obj types.Object, node ast.Node) (*HoverInformation, error) {
 	var info *HoverInformation
 
 	switch node := node.(type) {
@@ -304,6 +306,35 @@
 			info = &HoverInformation{source: obj, comment: node.Doc}
 		case *types.Builtin:
 			info = &HoverInformation{source: node.Type, comment: node.Doc}
+		case *types.Var:
+			// Object is a function param or the field of an anonymous struct
+			// declared with ':='. Skip the first one because only fields
+			// can have docs.
+			if isFunctionParam(obj, node) {
+				break
+			}
+
+			f := s.FileSet().File(obj.Pos())
+			if f == nil {
+				break
+			}
+
+			pgf, err := pkg.File(span.URIFromPath(f.Name()))
+			if err != nil {
+				return nil, err
+			}
+			posToField, err := s.PosToField(ctx, pgf)
+			if err != nil {
+				return nil, err
+			}
+
+			if field := posToField[obj.Pos()]; field != nil {
+				comment := field.Doc
+				if comment.Text() == "" {
+					comment = field.Comment
+				}
+				info = &HoverInformation{source: obj, comment: comment}
+			}
 		}
 	}
 
@@ -319,6 +350,24 @@
 	return info, nil
 }
 
+// isFunctionParam returns true if the passed object is either an incoming
+// or an outgoing function param
+func isFunctionParam(obj types.Object, node *ast.FuncDecl) bool {
+	for _, f := range node.Type.Params.List {
+		if f.Pos() == obj.Pos() {
+			return true
+		}
+	}
+	if node.Type.Results != nil {
+		for _, f := range node.Type.Results.List {
+			if f.Pos() == obj.Pos() {
+				return true
+			}
+		}
+	}
+	return false
+}
+
 func formatGenDecl(node *ast.GenDecl, obj types.Object, typ types.Type) (*HoverInformation, error) {
 	if _, ok := typ.(*types.Named); ok {
 		switch typ.Underlying().(type) {
@@ -370,6 +419,11 @@
 			fieldList = t.Methods
 		}
 	case *ast.ValueSpec:
+		// Try to extract the field list of an anonymous struct
+		if fieldList = extractFieldList(spec.Type); fieldList != nil {
+			break
+		}
+
 		comment := spec.Doc
 		if comment == nil {
 			comment = decl.Doc
@@ -379,20 +433,55 @@
 		}
 		return &HoverInformation{source: obj, comment: comment}
 	}
-	// If we have a struct or interface declaration,
-	// we need to match the object to the corresponding field or method.
+
 	if fieldList != nil {
-		for i := 0; i < len(fieldList.List); i++ {
-			field := fieldList.List[i]
-			if field.Pos() <= obj.Pos() && obj.Pos() <= field.End() {
-				if field.Doc.Text() != "" {
-					return &HoverInformation{source: obj, comment: field.Doc}
-				}
-				return &HoverInformation{source: obj, comment: field.Comment}
+		comment := findFieldComment(obj.Pos(), fieldList)
+		return &HoverInformation{source: obj, comment: comment}
+	}
+	return &HoverInformation{source: obj, comment: decl.Doc}
+}
+
+// extractFieldList recursively tries to extract a field list.
+// If it is not found, nil is returned.
+func extractFieldList(specType ast.Expr) *ast.FieldList {
+	switch t := specType.(type) {
+	case *ast.StructType:
+		return t.Fields
+	case *ast.InterfaceType:
+		return t.Methods
+	case *ast.ArrayType:
+		return extractFieldList(t.Elt)
+	case *ast.MapType:
+		// Map value has a greater chance to be a struct
+		if fields := extractFieldList(t.Value); fields != nil {
+			return fields
+		}
+		return extractFieldList(t.Key)
+	case *ast.ChanType:
+		return extractFieldList(t.Value)
+	}
+	return nil
+}
+
+// findFieldComment visits all fields in depth-first order and returns
+// the comment of a field with passed position. If no comment is found,
+// nil is returned.
+func findFieldComment(pos token.Pos, fieldList *ast.FieldList) *ast.CommentGroup {
+	for _, field := range fieldList.List {
+		if field.Pos() == pos {
+			if field.Doc.Text() != "" {
+				return field.Doc
+			}
+			return field.Comment
+		}
+
+		if nestedFieldList := extractFieldList(field.Type); nestedFieldList != nil {
+			if c := findFieldComment(pos, nestedFieldList); c != nil {
+				return c
 			}
 		}
 	}
-	return &HoverInformation{source: obj, comment: decl.Doc}
+	return nil
 }
 
 func FormatHover(h *HoverInformation, options *Options) (string, error) {
diff --git a/internal/lsp/source/identifier.go b/internal/lsp/source/identifier.go
index e648893..7c5e62c 100644
--- a/internal/lsp/source/identifier.go
+++ b/internal/lsp/source/identifier.go
@@ -323,6 +323,12 @@
 		return typ.Obj()
 	case *types.Pointer:
 		return typeToObject(typ.Elem())
+	case *types.Array:
+		return typeToObject(typ.Elem())
+	case *types.Slice:
+		return typeToObject(typ.Elem())
+	case *types.Chan:
+		return typeToObject(typ.Elem())
 	default:
 		return nil
 	}
diff --git a/internal/lsp/source/options.go b/internal/lsp/source/options.go
index 0f8dda1..826faa6 100644
--- a/internal/lsp/source/options.go
+++ b/internal/lsp/source/options.go
@@ -129,8 +129,9 @@
 						SymbolStyle:    DynamicSymbols,
 					},
 					CompletionOptions: CompletionOptions{
-						Matcher:          Fuzzy,
-						CompletionBudget: 100 * time.Millisecond,
+						Matcher:                        Fuzzy,
+						CompletionBudget:               100 * time.Millisecond,
+						ExperimentalPostfixCompletions: false,
 					},
 					Codelenses: map[string]bool{
 						string(command.Generate):          true,
@@ -293,6 +294,10 @@
 	// Matcher sets the algorithm that is used when calculating completion
 	// candidates.
 	Matcher Matcher `status:"advanced"`
+
+	// ExperimentalPostfixCompletions enables artifical method snippets
+	// such as "someSlice.sort!".
+	ExperimentalPostfixCompletions bool `status:"experimental"`
 }
 
 type DocumentationOptions struct {
@@ -681,6 +686,7 @@
 // should be enabled in enableAllExperimentMaps.
 func (o *Options) enableAllExperiments() {
 	o.SemanticTokens = true
+	o.ExperimentalPostfixCompletions = true
 }
 
 func (o *Options) enableAllExperimentMaps() {
@@ -852,6 +858,9 @@
 	case "expandWorkspaceToModule":
 		result.setBool(&o.ExpandWorkspaceToModule)
 
+	case "experimentalPostfixCompletions":
+		result.setBool(&o.ExperimentalPostfixCompletions)
+
 	case "experimentalWorkspaceModule":
 		result.setBool(&o.ExperimentalWorkspaceModule)
 
@@ -1080,7 +1089,7 @@
 	return map[string]*Analyzer{
 		fillreturns.Analyzer.Name: {
 			Analyzer:   fillreturns.Analyzer,
-			ActionKind: protocol.SourceFixAll,
+			ActionKind: []protocol.CodeActionKind{protocol.SourceFixAll, protocol.QuickFix},
 			Enabled:    true,
 		},
 		nonewvars.Analyzer.Name: {
@@ -1105,7 +1114,7 @@
 			Analyzer:   fillstruct.Analyzer,
 			Fix:        FillStruct,
 			Enabled:    true,
-			ActionKind: protocol.RefactorRewrite,
+			ActionKind: []protocol.CodeActionKind{protocol.RefactorRewrite},
 		},
 	}
 }
@@ -1150,9 +1159,21 @@
 		unusedwrite.Analyzer.Name:      {Analyzer: unusedwrite.Analyzer, Enabled: false},
 
 		// gofmt -s suite:
-		simplifycompositelit.Analyzer.Name: {Analyzer: simplifycompositelit.Analyzer, Enabled: true, ActionKind: protocol.SourceFixAll},
-		simplifyrange.Analyzer.Name:        {Analyzer: simplifyrange.Analyzer, Enabled: true, ActionKind: protocol.SourceFixAll},
-		simplifyslice.Analyzer.Name:        {Analyzer: simplifyslice.Analyzer, Enabled: true, ActionKind: protocol.SourceFixAll},
+		simplifycompositelit.Analyzer.Name: {
+			Analyzer:   simplifycompositelit.Analyzer,
+			Enabled:    true,
+			ActionKind: []protocol.CodeActionKind{protocol.SourceFixAll, protocol.QuickFix},
+		},
+		simplifyrange.Analyzer.Name: {
+			Analyzer:   simplifyrange.Analyzer,
+			Enabled:    true,
+			ActionKind: []protocol.CodeActionKind{protocol.SourceFixAll, protocol.QuickFix},
+		},
+		simplifyslice.Analyzer.Name: {
+			Analyzer:   simplifyslice.Analyzer,
+			Enabled:    true,
+			ActionKind: []protocol.CodeActionKind{protocol.SourceFixAll, protocol.QuickFix},
+		},
 	}
 }
 
diff --git a/internal/lsp/source/signature_help.go b/internal/lsp/source/signature_help.go
index 03ac4e8..90cd554 100644
--- a/internal/lsp/source/signature_help.go
+++ b/internal/lsp/source/signature_help.go
@@ -106,7 +106,7 @@
 			node: node,
 		}
 		decl.MappedRange = append(decl.MappedRange, rng)
-		d, err := HoverInfo(ctx, pkg, decl.obj, decl.node)
+		d, err := HoverInfo(ctx, snapshot, pkg, decl.obj, decl.node)
 		if err != nil {
 			return nil, 0, err
 		}
diff --git a/internal/lsp/source/source_test.go b/internal/lsp/source/source_test.go
index 8064b0d..23df0c5 100644
--- a/internal/lsp/source/source_test.go
+++ b/internal/lsp/source/source_test.go
@@ -47,7 +47,7 @@
 func testSource(t *testing.T, datum *tests.Data) {
 	ctx := tests.Context(t)
 
-	cache := cache.New(ctx, nil)
+	cache := cache.New(nil)
 	session := cache.NewSession(ctx)
 	options := source.DefaultOptions().Clone()
 	tests.DefaultOptions(options)
@@ -177,9 +177,8 @@
 		opts.DeepCompletion = false
 		opts.CompleteUnimported = false
 		opts.InsertTextFormat = protocol.SnippetTextFormat
-		if !strings.Contains(string(src.URI()), "literal") {
-			opts.LiteralCompletions = false
-		}
+		opts.LiteralCompletions = strings.Contains(string(src.URI()), "literal")
+		opts.ExperimentalPostfixCompletions = strings.Contains(string(src.URI()), "postfix")
 	})
 	got = tests.FilterBuiltins(src, got)
 	if diff := tests.DiffCompletionItems(want, got); diff != "" {
@@ -278,6 +277,7 @@
 	_, got := r.callCompletion(t, src, func(opts *source.Options) {
 		opts.DeepCompletion = true
 		opts.Matcher = source.Fuzzy
+		opts.ExperimentalPostfixCompletions = true
 	})
 	if msg := tests.CheckCompletionOrder(want, got, true); msg != "" {
 		t.Errorf("%s: %s", src, msg)
@@ -931,6 +931,7 @@
 
 // These are pure LSP features, no source level functionality to be tested.
 func (r *runner) Link(t *testing.T, uri span.URI, wantLinks []tests.Link) {}
+
 func (r *runner) SuggestedFix(t *testing.T, spn span.Span, actionKinds []string, expectedActions int) {
 }
 func (r *runner) FunctionExtraction(t *testing.T, start span.Span, end span.Span) {}
diff --git a/internal/lsp/source/util.go b/internal/lsp/source/util.go
index c1ba082..690a781 100644
--- a/internal/lsp/source/util.go
+++ b/internal/lsp/source/util.go
@@ -350,6 +350,9 @@
 			return ""
 		}
 		if name, ok := imports[p]; ok {
+			if name == "." {
+				return ""
+			}
 			return name
 		}
 		return p.Name()
diff --git a/internal/lsp/source/view.go b/internal/lsp/source/view.go
index 9bc5eca..412866c 100644
--- a/internal/lsp/source/view.go
+++ b/internal/lsp/source/view.go
@@ -215,6 +215,10 @@
 	// Folder returns the folder with which this view was created.
 	Folder() span.URI
 
+	// TempWorkspace returns the folder this view uses for its temporary
+	// workspace module.
+	TempWorkspace() span.URI
+
 	// Shutdown closes this view, and detaches it from its session.
 	Shutdown(ctx context.Context)
 
@@ -291,8 +295,13 @@
 // of the client.
 // A session may have many active views at any given time.
 type Session interface {
-	// NewView creates a new View, returning it and its first snapshot.
-	NewView(ctx context.Context, name string, folder, tempWorkspaceDir span.URI, options *Options) (View, Snapshot, func(), error)
+	// ID returns the unique identifier for this session on this server.
+	ID() string
+	// NewView creates a new View, returning it and its first snapshot. If a
+	// non-empty tempWorkspace directory is provided, the View will record a copy
+	// of its gopls workspace module in that directory, so that client tooling
+	// can execute in the same main module.
+	NewView(ctx context.Context, name string, folder, tempWorkspace span.URI, options *Options) (View, Snapshot, func(), error)
 
 	// Cache returns the cache that created this session, for debugging only.
 	Cache() interface{}
@@ -522,7 +531,7 @@
 
 	// ActionKind is the kind of code action this analyzer produces. If
 	// unspecified the type defaults to quickfix.
-	ActionKind protocol.CodeActionKind
+	ActionKind []protocol.CodeActionKind
 }
 
 func (a Analyzer) IsEnabled(view View) bool {
diff --git a/internal/lsp/testdata/extract/extract_function/extract_issue_44813.go b/internal/lsp/testdata/extract/extract_function/extract_issue_44813.go
new file mode 100644
index 0000000..9713b91
--- /dev/null
+++ b/internal/lsp/testdata/extract/extract_function/extract_issue_44813.go
@@ -0,0 +1,13 @@
+package extract
+
+import "fmt"
+
+func main() {
+	x := []rune{} //@mark(exSt9, "x")
+	s := "HELLO"
+	for _, c := range s {
+		x = append(x, c)
+	} //@mark(exEn9, "}")
+	//@extractfunc(exSt9, exEn9)
+	fmt.Printf("%x\n", x)
+}
diff --git a/internal/lsp/testdata/extract/extract_function/extract_issue_44813.go.golden b/internal/lsp/testdata/extract/extract_function/extract_issue_44813.go.golden
new file mode 100644
index 0000000..8604745
--- /dev/null
+++ b/internal/lsp/testdata/extract/extract_function/extract_issue_44813.go.golden
@@ -0,0 +1,20 @@
+-- functionextraction_extract_issue_44813_6_2 --
+package extract
+
+import "fmt"
+
+func main() {
+	x := fn0() //@mark(exEn9, "}")
+	//@extractfunc(exSt9, exEn9)
+	fmt.Printf("%x\n", x)
+}
+
+func fn0() []rune {
+	x := []rune{}
+	s := "HELLO"
+	for _, c := range s {
+		x = append(x, c)
+	}
+	return x
+}
+
diff --git a/internal/lsp/testdata/godef/a/h.go b/internal/lsp/testdata/godef/a/h.go
new file mode 100644
index 0000000..efe7d4e
--- /dev/null
+++ b/internal/lsp/testdata/godef/a/h.go
@@ -0,0 +1,147 @@
+package a
+
+func _() {
+	type s struct {
+		nested struct {
+			// nested number
+			number int64 //@mark(nestedNumber, "number")
+		}
+		nested2 []struct {
+			// nested string
+			str string //@mark(nestedString, "str")
+		}
+		x struct {
+			x struct {
+				x struct {
+					x struct {
+						x struct {
+							// nested map
+							m map[string]float64 //@mark(nestedMap, "m")
+						}
+					}
+				}
+			}
+		}
+	}
+
+	var t s
+	_ = t.nested.number  //@hover("number", nestedNumber)
+	_ = t.nested2[0].str //@hover("str", nestedString)
+	_ = t.x.x.x.x.x.m    //@hover("m", nestedMap)
+}
+
+func _() {
+	var s struct {
+		// a field
+		a int //@mark(structA, "a")
+		// b nested struct
+		b struct { //@mark(structB, "b")
+			// c field of nested struct
+			c int //@mark(structC, "c")
+		}
+	}
+	_ = s.a   //@hover("a", structA)
+	_ = s.b   //@hover("b", structB)
+	_ = s.b.c //@hover("c", structC)
+
+	var arr []struct {
+		// d field
+		d int //@mark(arrD, "d")
+		// e nested struct
+		e struct { //@mark(arrE, "e")
+			// f field of nested struct
+			f int //@mark(arrF, "f")
+		}
+	}
+	_ = arr[0].d   //@hover("d", arrD)
+	_ = arr[0].e   //@hover("e", arrE)
+	_ = arr[0].e.f //@hover("f", arrF)
+
+	var complex []struct {
+		c <-chan map[string][]struct {
+			// h field
+			h int //@mark(complexH, "h")
+			// i nested struct
+			i struct { //@mark(complexI, "i")
+				// j field of nested struct
+				j int //@mark(complexJ, "j")
+			}
+		}
+	}
+	_ = (<-complex[0].c)["0"][0].h   //@hover("h", complexH)
+	_ = (<-complex[0].c)["0"][0].i   //@hover("i", complexI)
+	_ = (<-complex[0].c)["0"][0].i.j //@hover("j", complexJ)
+
+	var mapWithStructKey map[struct {
+		// X key field
+		x []string //@mark(mapStructKeyX, "x")
+	}]int
+	for k := range mapWithStructKey {
+		_ = k.x //@hover("x", mapStructKeyX)
+	}
+
+	var mapWithStructKeyAndValue map[struct {
+		// Y key field
+		y string //@mark(mapStructKeyY, "y")
+	}]struct {
+		// X value field
+		x string //@mark(mapStructValueX, "x")
+	}
+	for k, v := range mapWithStructKeyAndValue {
+		// TODO: we don't show docs for y field because both map key and value
+		// are structs. And in this case, we parse only map value
+		_ = k.y //@hover("y", mapStructKeyY)
+		_ = v.x //@hover("x", mapStructValueX)
+	}
+
+	var i []map[string]interface {
+		// open method comment
+		open() error //@mark(openMethod, "open")
+	}
+	i[0]["1"].open() //@hover("open", openMethod)
+}
+
+func _() {
+	test := struct {
+		// test description
+		desc string //@mark(testDescription, "desc")
+	}{}
+	_ = test.desc //@hover("desc", testDescription)
+
+	for _, tt := range []struct {
+		// test input
+		in map[string][]struct { //@mark(testInput, "in")
+			// test key
+			key string //@mark(testInputKey, "key")
+			// test value
+			value interface{} //@mark(testInputValue, "value")
+		}
+		result struct {
+			v <-chan struct {
+				// expected test value
+				value int //@mark(testResultValue, "value")
+			}
+		}
+	}{} {
+		_ = tt.in               //@hover("in", testInput)
+		_ = tt.in["0"][0].key   //@hover("key", testInputKey)
+		_ = tt.in["0"][0].value //@hover("value", testInputValue)
+
+		_ = (<-tt.result.v).value //@hover("value", testResultValue)
+	}
+}
+
+func _() {
+	getPoints := func() []struct {
+		// X coord
+		x int //@mark(returnX, "x")
+		// Y coord
+		y int //@mark(returnY, "y")
+	} {
+		return nil
+	}
+
+	r := getPoints()
+	r[0].x //@hover("x", returnX)
+	r[0].y //@hover("y", returnY)
+}
diff --git a/internal/lsp/testdata/godef/a/h.go.golden b/internal/lsp/testdata/godef/a/h.go.golden
new file mode 100644
index 0000000..71f78e1
--- /dev/null
+++ b/internal/lsp/testdata/godef/a/h.go.golden
@@ -0,0 +1,136 @@
+-- nestedNumber-hover --
+```go
+field number int64
+```
+
+nested number
+-- nestedString-hover --
+```go
+field str string
+```
+
+nested string
+-- nestedMap-hover --
+```go
+field m map[string]float64
+```
+
+nested map
+-- structA-hover --
+```go
+field a int
+```
+
+a field
+-- structB-hover --
+```go
+field b struct{c int}
+```
+
+b nested struct
+-- structC-hover --
+```go
+field c int
+```
+
+c field of nested struct
+-- arrD-hover --
+```go
+field d int
+```
+
+d field
+-- arrE-hover --
+```go
+field e struct{f int}
+```
+
+e nested struct
+-- arrF-hover --
+```go
+field f int
+```
+
+f field of nested struct
+-- complexH-hover --
+```go
+field h int
+```
+
+h field
+-- complexI-hover --
+```go
+field i struct{j int}
+```
+
+i nested struct
+-- complexJ-hover --
+```go
+field j int
+```
+
+j field of nested struct
+-- mapStructKeyX-hover --
+```go
+field x []string
+```
+
+X key field
+-- mapStructKeyY-hover --
+```go
+field y string
+```
+-- mapStructValueX-hover --
+```go
+field x string
+```
+
+X value field
+-- openMethod-hover --
+```go
+func (interface).open() error
+```
+
+open method comment
+-- testDescription-hover --
+```go
+field desc string
+```
+
+test description
+-- testInput-hover --
+```go
+field in map[string][]struct{key string; value interface{}}
+```
+
+test input
+-- testInputKey-hover --
+```go
+field key string
+```
+
+test key
+-- testInputValue-hover --
+```go
+field value interface{}
+```
+
+test value
+-- testResultValue-hover --
+```go
+field value int
+```
+
+expected test value
+-- returnX-hover --
+```go
+field x int
+```
+
+X coord
+-- returnY-hover --
+```go
+field y int
+```
+
+Y coord
\ No newline at end of file
diff --git a/internal/lsp/testdata/godef/b/h.go b/internal/lsp/testdata/godef/b/h.go
new file mode 100644
index 0000000..c2776a0
--- /dev/null
+++ b/internal/lsp/testdata/godef/b/h.go
@@ -0,0 +1,10 @@
+package b
+
+import . "golang.org/x/tools/internal/lsp/godef/a"
+
+func _() {
+	// variable of type a.A
+	var _ A //@mark(AVariable, "_"),hover("_", AVariable)
+
+	AStuff() //@hover("AStuff", AStuff)
+}
diff --git a/internal/lsp/testdata/godef/b/h.go.golden b/internal/lsp/testdata/godef/b/h.go.golden
new file mode 100644
index 0000000..85f0404
--- /dev/null
+++ b/internal/lsp/testdata/godef/b/h.go.golden
@@ -0,0 +1,12 @@
+-- AVariable-hover --
+```go
+var _ A
+```
+
+variable of type a\.A
+-- AStuff-hover --
+```go
+func AStuff()
+```
+
+[`a.AStuff` on pkg.go.dev](https://pkg.go.dev/golang.org/x/tools/internal/lsp/godef/a?utm_source=gopls#AStuff)
\ No newline at end of file
diff --git a/internal/lsp/testdata/semantic/a.go.golden b/internal/lsp/testdata/semantic/a.go.golden
index 5bb276c..b09c20d 100644
--- a/internal/lsp/testdata/semantic/a.go.golden
+++ b/internal/lsp/testdata/semantic/a.go.golden
@@ -11,12 +11,12 @@
 
 /*⇒3,keyword,[]*/var (
 	/*⇒1,variable,[definition]*/a           = /*⇒3,namespace,[]*/fmt./*⇒5,function,[]*/Print
-	/*⇒1,variable,[definition]*/b  []/*⇒6,type,[]*/string = []/*⇒6,type,[]*/string{/*⇒5,string,[]*/"foo"}
-	/*⇒2,variable,[definition]*/c1 /*⇒4,keyword,[]*/chan /*⇒3,type,[]*/int
-	/*⇒2,variable,[definition]*/c2 <-/*⇒4,keyword,[]*/chan /*⇒3,type,[]*/int
-	/*⇒2,variable,[definition]*/c3 = /*⇒4,function,[defaultLibrary]*/make([]/*⇒4,keyword,[]*/chan<- /*⇒3,type,[]*/int)
+	/*⇒1,variable,[definition]*/b  []/*⇒6,type,[defaultLibrary]*/string = []/*⇒6,type,[defaultLibrary]*/string{/*⇒5,string,[]*/"foo"}
+	/*⇒2,variable,[definition]*/c1 /*⇒4,keyword,[]*/chan /*⇒3,type,[defaultLibrary]*/int
+	/*⇒2,variable,[definition]*/c2 <-/*⇒4,keyword,[]*/chan /*⇒3,type,[defaultLibrary]*/int
+	/*⇒2,variable,[definition]*/c3 = /*⇒4,function,[defaultLibrary]*/make([]/*⇒4,keyword,[]*/chan<- /*⇒3,type,[defaultLibrary]*/int)
 	/*⇒1,variable,[definition]*/b  = /*⇒1,type,[]*/A{/*⇒1,variable,[]*/X: /*⇒2,number,[]*/23}
-	/*⇒1,variable,[definition]*/m  /*⇒3,keyword,[]*/map[/*⇒4,type,[]*/bool][/*⇒1,number,[]*/3]/*⇒1,operator,[]*/*/*⇒7,type,[]*/float64
+	/*⇒1,variable,[definition]*/m  /*⇒3,keyword,[]*/map[/*⇒4,type,[defaultLibrary]*/bool][/*⇒1,number,[]*/3]/*⇒1,operator,[]*/*/*⇒7,type,[defaultLibrary]*/float64
 )
 
 /*⇒5,keyword,[]*/const (
@@ -27,17 +27,17 @@
 )
 
 /*⇒4,keyword,[]*/type /*⇒1,type,[definition]*/A /*⇒6,keyword,[]*/struct {
-	/*⇒1,type,[definition]*/X /*⇒3,type,[]*/int /*⇒6,comment,[]*/`foof`
+	/*⇒1,variable,[definition]*/X /*⇒3,type,[defaultLibrary]*/int /*⇒6,comment,[]*/`foof`
 }
 /*⇒4,keyword,[]*/type /*⇒1,type,[definition]*/B /*⇒9,keyword,[]*/interface {
 	/*⇒1,type,[]*/A
-	/*⇒3,member,[definition]*/sad(/*⇒3,type,[]*/int) /*⇒4,type,[]*/bool
+	/*⇒3,member,[definition]*/sad(/*⇒3,type,[defaultLibrary]*/int) /*⇒4,type,[defaultLibrary]*/bool
 }
 
-/*⇒4,keyword,[]*/type /*⇒1,type,[definition]*/F /*⇒3,type,[]*/int
+/*⇒4,keyword,[]*/type /*⇒1,type,[definition]*/F /*⇒3,type,[defaultLibrary]*/int
 
-/*⇒4,keyword,[]*/func (/*⇒1,variable,[]*/a /*⇒1,operator,[]*/*/*⇒1,type,[]*/A) /*⇒1,member,[definition]*/f() /*⇒4,type,[]*/bool {
-	/*⇒3,keyword,[]*/var /*⇒1,variable,[definition]*/z /*⇒6,type,[]*/string
+/*⇒4,keyword,[]*/func (/*⇒1,variable,[]*/a /*⇒1,operator,[]*/*/*⇒1,type,[]*/A) /*⇒1,member,[definition]*/f() /*⇒4,type,[defaultLibrary]*/bool {
+	/*⇒3,keyword,[]*/var /*⇒1,variable,[definition]*/z /*⇒6,type,[defaultLibrary]*/string
 	/*⇒1,variable,[definition]*/x /*⇒2,operator,[]*/:= /*⇒5,string,[]*/"foo"
 	/*⇒1,variable,[]*/a(/*⇒1,variable,[definition]*/x)
 	/*⇒1,variable,[definition]*/y /*⇒2,operator,[]*/:= /*⇒5,string,[]*/"bar" /*⇒1,operator,[]*/+ /*⇒1,variable,[]*/x
@@ -50,7 +50,7 @@
 	/*⇒7,keyword,[]*/default:
 	}
 	/*⇒3,keyword,[]*/for /*⇒1,variable,[definition]*/k, /*⇒1,variable,[definition]*/v := /*⇒5,keyword,[]*/range /*⇒1,variable,[]*/m {
-		/*⇒6,keyword,[]*/return (/*⇒1,operator,[]*/!/*⇒1,variable,[]*/k) /*⇒2,operator,[]*/&& /*⇒1,variable,[]*/v[/*⇒1,number,[]*/0] /*⇒2,operator,[]*/== /*⇒3,variable,[readonly]*/nil
+		/*⇒6,keyword,[]*/return (/*⇒1,operator,[]*/!/*⇒1,variable,[]*/k) /*⇒2,operator,[]*/&& /*⇒1,variable,[]*/v[/*⇒1,number,[]*/0] /*⇒2,operator,[]*/== /*⇒3,variable,[readonly defaultLibrary]*/nil
 	}
 	/*⇒2,variable,[]*/c2 /*⇒2,operator,[]*/<- /*⇒1,type,[]*/A./*⇒1,variable,[definition]*/X
 	/*⇒1,variable,[definition]*/w /*⇒2,operator,[]*/:= /*⇒1,variable,[]*/b[/*⇒1,number,[]*/4:]
diff --git a/internal/lsp/testdata/semantic/b.go.golden b/internal/lsp/testdata/semantic/b.go.golden
index b56bb11..906a624 100644
--- a/internal/lsp/testdata/semantic/b.go.golden
+++ b/internal/lsp/testdata/semantic/b.go.golden
@@ -6,7 +6,7 @@
 
 /*⇒4,keyword,[]*/func /*⇒6,function,[definition]*/weirâ°€d() {
 	/*⇒5,keyword,[]*/const (
-		/*⇒4,variable,[definition readonly]*/snil   = /*⇒3,variable,[readonly]*/nil
+		/*⇒4,variable,[definition readonly]*/snil   = /*⇒3,variable,[readonly defaultLibrary]*/nil
 		/*⇒3,variable,[definition readonly]*/nil    = /*⇒4,variable,[readonly]*/true
 		/*⇒4,variable,[definition readonly]*/true   = /*⇒5,variable,[readonly]*/false
 		/*⇒5,variable,[definition readonly]*/false  = /*⇒4,variable,[readonly]*/snil
diff --git a/internal/lsp/testdata/snippets/postfix.go b/internal/lsp/testdata/snippets/postfix.go
new file mode 100644
index 0000000..29b4192
--- /dev/null
+++ b/internal/lsp/testdata/snippets/postfix.go
@@ -0,0 +1,27 @@
+package snippets
+
+// These tests check that postfix completions do and do not show up in
+// certain cases. Tests for the postfix completion contents are under
+// regtest.
+
+func _() {
+	/* append! */ //@item(postfixAppend, "append!", "append and re-assign slice", "snippet")
+	var foo []int
+	foo.append //@rank(" //", postfixAppend)
+
+	[]int{}.append //@complete(" //")
+
+	[]int{}.last //@complete(" //")
+
+	/* copy! */ //@item(postfixCopy, "copy!", "duplicate slice", "snippet")
+
+	foo.copy //@rank(" //", postfixCopy)
+
+	var s struct{ i []int }
+	s.i.copy //@rank(" //", postfixCopy)
+
+	var _ []int = s.i.copy //@complete(" //")
+
+	var blah func() []int
+	blah().append //@complete(" //")
+}
diff --git a/internal/lsp/testdata/statements/if_err_check_test.go b/internal/lsp/testdata/statements/if_err_check_test.go
new file mode 100644
index 0000000..6de5878
--- /dev/null
+++ b/internal/lsp/testdata/statements/if_err_check_test.go
@@ -0,0 +1,20 @@
+package statements
+
+import (
+	"os"
+	"testing"
+)
+
+func TestErr(t *testing.T) {
+	/* if err != nil { t.Fatal(err) } */ //@item(stmtOneIfErrTFatal, "if err != nil { t.Fatal(err) }", "", "")
+
+	_, err := os.Open("foo")
+	//@snippet("", stmtOneIfErrTFatal, "", "if err != nil {\n\tt.Fatal(err)\n\\}")
+}
+
+func BenchmarkErr(b *testing.B) {
+	/* if err != nil { b.Fatal(err) } */ //@item(stmtOneIfErrBFatal, "if err != nil { b.Fatal(err) }", "", "")
+
+	_, err := os.Open("foo")
+	//@snippet("", stmtOneIfErrBFatal, "", "if err != nil {\n\tb.Fatal(err)\n\\}")
+}
diff --git a/internal/lsp/testdata/summary.txt.golden b/internal/lsp/testdata/summary.txt.golden
index e0b6366..7b9b6ed 100644
--- a/internal/lsp/testdata/summary.txt.golden
+++ b/internal/lsp/testdata/summary.txt.golden
@@ -1,12 +1,12 @@
 -- summary --
 CallHierarchyCount = 2
 CodeLensCount = 5
-CompletionsCount = 258
-CompletionSnippetCount = 92
+CompletionsCount = 262
+CompletionSnippetCount = 94
 UnimportedCompletionsCount = 5
 DeepCompletionsCount = 5
 FuzzyCompletionsCount = 8
-RankedCompletionsCount = 159
+RankedCompletionsCount = 162
 CaseSensitiveCompletionsCount = 4
 DiagnosticsCount = 37
 FoldingRangesCount = 2
@@ -14,9 +14,9 @@
 ImportCount = 8
 SemanticTokenCount = 3
 SuggestedFixCount = 40
-FunctionExtractionCount = 12
-DefinitionsCount = 65
-TypeDefinitionsCount = 2
+FunctionExtractionCount = 13
+DefinitionsCount = 90
+TypeDefinitionsCount = 10
 HighlightsCount = 69
 ReferencesCount = 25
 RenamesCount = 33
diff --git a/internal/lsp/testdata/typdef/typdef.go b/internal/lsp/testdata/typdef/typdef.go
new file mode 100644
index 0000000..87d5197
--- /dev/null
+++ b/internal/lsp/testdata/typdef/typdef.go
@@ -0,0 +1,38 @@
+package typdef
+
+type Struct struct { //@item(Struct, "Struct", "struct{...}", "struct")
+	Field string
+}
+
+type Int int //@item(Int, "Int", "int", "type")
+
+func _() {
+	var (
+		value Struct
+		point *Struct
+	)
+	_ = value //@typdef("value", Struct)
+	_ = point //@typdef("point", Struct)
+
+	var (
+		array   [3]Struct
+		slice   []Struct
+		ch      chan Struct
+		complex [3]chan *[5][]Int
+	)
+	_ = array   //@typdef("array", Struct)
+	_ = slice   //@typdef("slice", Struct)
+	_ = ch      //@typdef("ch", Struct)
+	_ = complex //@typdef("complex", Int)
+
+	var s struct {
+		x struct {
+			xx struct {
+				field1 []Struct
+				field2 []Int
+			}
+		}
+	}
+	s.x.xx.field1 //@typdef("field1", Struct)
+	s.x.xx.field2 //@typdef("field2", Int)
+}
diff --git a/internal/lsp/tests/README.md b/internal/lsp/tests/README.md
index d8ba10f..2c18675 100644
--- a/internal/lsp/tests/README.md
+++ b/internal/lsp/tests/README.md
@@ -52,7 +52,7 @@
 
 ```bash
 cd /path/to/tools
-go test ./internal/lsp -v -run TestLSP/Modules/SuggestedFix/bar_11_21
+go test ./internal/lsp/... -v -run TestLSP/Modules/SuggestedFix/bar_11_21
 ```
 
 ## Resetting marker tests
diff --git a/internal/lsp/workspace.go b/internal/lsp/workspace.go
index 2dce905..093adc7 100644
--- a/internal/lsp/workspace.go
+++ b/internal/lsp/workspace.go
@@ -6,7 +6,12 @@
 
 import (
 	"context"
+	"fmt"
+	"os"
+	"path/filepath"
+	"sync/atomic"
 
+	"golang.org/x/tools/internal/event"
 	"golang.org/x/tools/internal/lsp/protocol"
 	"golang.org/x/tools/internal/lsp/source"
 	"golang.org/x/tools/internal/span"
@@ -26,7 +31,9 @@
 	return s.addFolders(ctx, event.Added)
 }
 
-func (s *Server) addView(ctx context.Context, name string, uri, tempWorkspace span.URI) (source.Snapshot, func(), error) {
+var wsIndex int64
+
+func (s *Server) addView(ctx context.Context, name string, uri span.URI) (source.Snapshot, func(), error) {
 	s.stateMu.Lock()
 	state := s.state
 	s.stateMu.Unlock()
@@ -37,6 +44,18 @@
 	if err := s.fetchConfig(ctx, name, uri, options); err != nil {
 		return nil, func() {}, err
 	}
+	// Try to assign a persistent temp directory for tracking this view's
+	// temporary workspace.
+	var tempWorkspace span.URI
+	if s.tempDir != "" {
+		index := atomic.AddInt64(&wsIndex, 1)
+		wsDir := filepath.Join(s.tempDir, fmt.Sprintf("workspace.%d", index))
+		if err := os.Mkdir(wsDir, 0700); err == nil {
+			tempWorkspace = span.URIFromPath(wsDir)
+		} else {
+			event.Error(ctx, "making workspace dir", err)
+		}
+	}
 	_, snapshot, release, err := s.session.NewView(ctx, name, uri, tempWorkspace, options)
 	return snapshot, release, err
 }
diff --git a/present/caption.go b/present/caption.go
index 0fa2656..64a5268 100644
--- a/present/caption.go
+++ b/present/caption.go
@@ -18,7 +18,7 @@
 func (c Caption) PresentCmd() string   { return c.Cmd }
 func (c Caption) TemplateName() string { return "caption" }
 
-func parseCaption(_ *Context, _ string, _ int, text string) (Elem, error) {
-	text = strings.TrimSpace(strings.TrimPrefix(text, ".caption"))
-	return Caption{text, text}, nil
+func parseCaption(_ *Context, _ string, _ int, cmd string) (Elem, error) {
+	text := strings.TrimSpace(strings.TrimPrefix(cmd, ".caption"))
+	return Caption{cmd, text}, nil
 }
diff --git a/present/parse.go b/present/parse.go
index 8340559..4294ea5 100644
--- a/present/parse.go
+++ b/present/parse.go
@@ -525,6 +525,7 @@
 					// Command breaks text block.
 					// Section heading breaks text block in markdown.
 					if text[0] == '.' || isSpeakerNote(text) {
+						lines.back()
 						break
 					}
 					if strings.HasPrefix(text, `\.`) { // Backslash escapes initial period.
diff --git a/present/testdata/media.p b/present/testdata/media.p
index f11970b..ffddf9f 100644
--- a/present/testdata/media.p
+++ b/present/testdata/media.p
@@ -2,6 +2,7 @@
 
 *
 
+The Gopher
 .image gopher.jpg _ 100
 .caption A gopher.
 
@@ -14,6 +15,7 @@
 ---
 <h1>Media</h1>
 <section>
+<p>The Gopher</p>
 <img src="gopher.jpg" width="100" alt="">
 <figcaption>A gopher.</figcaption>
 <iframe src="https://golang.org/"></iframe>