diff --git a/cmd/godoc/blog.go b/cmd/godoc/blog.go deleted file mode 100644 index 42abeb6911..0000000000 --- a/cmd/godoc/blog.go +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2013 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 main - -import ( - "fmt" - "go/build" - "log" - "net/http" - "os" - "path/filepath" - "runtime" - "strings" - "sync" - - "golang.org/x/tools/blog" - "golang.org/x/tools/godoc/redirect" -) - -const ( - blogRepo = "golang.org/x/blog" - blogURL = "https://blog.golang.org/" - blogPath = "/blog/" -) - -var ( - blogServer http.Handler // set by blogInit - blogInitOnce sync.Once - playEnabled bool -) - -func init() { - // Initialize blog only when first accessed. - http.HandleFunc(blogPath, func(w http.ResponseWriter, r *http.Request) { - blogInitOnce.Do(func() { - blogInit(r.Host) - }) - blogServer.ServeHTTP(w, r) - }) -} - -func blogInit(host string) { - // Binary distributions included the blog content in "/blog". - // We stopped including this in Go 1.11. - root := filepath.Join(runtime.GOROOT(), "blog") - - // Prefer content from the golang.org/x/blog repository if present. - if pkg, err := build.Import(blogRepo, "", build.FindOnly); err == nil { - root = pkg.Dir - } - - // If content is not available fall back to redirect. - if fi, err := os.Stat(root); err != nil || !fi.IsDir() { - fmt.Fprintf(os.Stderr, "Blog content not available locally. "+ - "To install, run \n\tgo get %v\n", blogRepo) - blogServer = http.HandlerFunc(blogRedirectHandler) - return - } - - s, err := blog.NewServer(blog.Config{ - BaseURL: blogPath, - BasePath: strings.TrimSuffix(blogPath, "/"), - ContentPath: filepath.Join(root, "content"), - TemplatePath: filepath.Join(root, "template"), - HomeArticles: 5, - PlayEnabled: playEnabled, - ServeLocalLinks: strings.HasPrefix(host, "localhost"), - }) - if err != nil { - log.Fatal(err) - } - blogServer = s -} - -func blogRedirectHandler(w http.ResponseWriter, r *http.Request) { - if r.URL.Path == blogPath { - http.Redirect(w, r, blogURL, http.StatusFound) - return - } - blogPrefixHandler.ServeHTTP(w, r) -} - -var blogPrefixHandler = redirect.PrefixHandler(blogPath, blogURL) diff --git a/cmd/godoc/codewalk.go b/cmd/godoc/codewalk.go deleted file mode 100644 index 2f1c3ca6b9..0000000000 --- a/cmd/godoc/codewalk.go +++ /dev/null @@ -1,522 +0,0 @@ -// Copyright 2010 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. - -// The /doc/codewalk/ tree is synthesized from codewalk descriptions, -// files named $GOROOT/doc/codewalk/*.xml. -// For an example and a description of the format, see -// http://golang.org/doc/codewalk/codewalk or run godoc -http=:6060 -// and see http://localhost:6060/doc/codewalk/codewalk . -// That page is itself a codewalk; the source code for it is -// $GOROOT/doc/codewalk/codewalk.xml. - -package main - -import ( - "bytes" - "encoding/xml" - "errors" - "fmt" - "io" - "log" - "net/http" - "os" - pathpkg "path" - "regexp" - "sort" - "strconv" - "strings" - "text/template" - "unicode/utf8" - - "golang.org/x/tools/godoc" - "golang.org/x/tools/godoc/vfs" -) - -var codewalkHTML, codewalkdirHTML *template.Template - -// Handler for /doc/codewalk/ and below. -func codewalk(w http.ResponseWriter, r *http.Request) { - relpath := r.URL.Path[len("/doc/codewalk/"):] - abspath := r.URL.Path - - r.ParseForm() - if f := r.FormValue("fileprint"); f != "" { - codewalkFileprint(w, r, f) - return - } - - // If directory exists, serve list of code walks. - dir, err := fs.Lstat(abspath) - if err == nil && dir.IsDir() { - codewalkDir(w, r, relpath, abspath) - return - } - - // If file exists, serve using standard file server. - if err == nil { - pres.ServeFile(w, r) - return - } - - // Otherwise append .xml and hope to find - // a codewalk description, but before trim - // the trailing /. - abspath = strings.TrimRight(abspath, "/") - cw, err := loadCodewalk(abspath + ".xml") - if err != nil { - log.Print(err) - pres.ServeError(w, r, relpath, err) - return - } - - // Canonicalize the path and redirect if changed - if redir(w, r) { - return - } - - pres.ServePage(w, godoc.Page{ - Title: "Codewalk: " + cw.Title, - Tabtitle: cw.Title, - Body: applyTemplate(codewalkHTML, "codewalk", cw), - }) -} - -func redir(w http.ResponseWriter, r *http.Request) (redirected bool) { - canonical := pathpkg.Clean(r.URL.Path) - if !strings.HasSuffix(canonical, "/") { - canonical += "/" - } - if r.URL.Path != canonical { - url := *r.URL - url.Path = canonical - http.Redirect(w, r, url.String(), http.StatusMovedPermanently) - redirected = true - } - return -} - -func applyTemplate(t *template.Template, name string, data interface{}) []byte { - var buf bytes.Buffer - if err := t.Execute(&buf, data); err != nil { - log.Printf("%s.Execute: %s", name, err) - } - return buf.Bytes() -} - -// A Codewalk represents a single codewalk read from an XML file. -type Codewalk struct { - Title string `xml:"title,attr"` - File []string `xml:"file"` - Step []*Codestep `xml:"step"` -} - -// A Codestep is a single step in a codewalk. -type Codestep struct { - // Filled in from XML - Src string `xml:"src,attr"` - Title string `xml:"title,attr"` - XML string `xml:",innerxml"` - - // Derived from Src; not in XML. - Err error - File string - Lo int - LoByte int - Hi int - HiByte int - Data []byte -} - -// String method for printing in template. -// Formats file address nicely. -func (st *Codestep) String() string { - s := st.File - if st.Lo != 0 || st.Hi != 0 { - s += fmt.Sprintf(":%d", st.Lo) - if st.Lo != st.Hi { - s += fmt.Sprintf(",%d", st.Hi) - } - } - return s -} - -// loadCodewalk reads a codewalk from the named XML file. -func loadCodewalk(filename string) (*Codewalk, error) { - f, err := fs.Open(filename) - if err != nil { - return nil, err - } - defer f.Close() - cw := new(Codewalk) - d := xml.NewDecoder(f) - d.Entity = xml.HTMLEntity - err = d.Decode(cw) - if err != nil { - return nil, &os.PathError{Op: "parsing", Path: filename, Err: err} - } - - // Compute file list, evaluate line numbers for addresses. - m := make(map[string]bool) - for _, st := range cw.Step { - i := strings.Index(st.Src, ":") - if i < 0 { - i = len(st.Src) - } - filename := st.Src[0:i] - data, err := vfs.ReadFile(fs, filename) - if err != nil { - st.Err = err - continue - } - if i < len(st.Src) { - lo, hi, err := addrToByteRange(st.Src[i+1:], 0, data) - if err != nil { - st.Err = err - continue - } - // Expand match to line boundaries. - for lo > 0 && data[lo-1] != '\n' { - lo-- - } - for hi < len(data) && (hi == 0 || data[hi-1] != '\n') { - hi++ - } - st.Lo = byteToLine(data, lo) - st.Hi = byteToLine(data, hi-1) - } - st.Data = data - st.File = filename - m[filename] = true - } - - // Make list of files - cw.File = make([]string, len(m)) - i := 0 - for f := range m { - cw.File[i] = f - i++ - } - sort.Strings(cw.File) - - return cw, nil -} - -// codewalkDir serves the codewalk directory listing. -// It scans the directory for subdirectories or files named *.xml -// and prepares a table. -func codewalkDir(w http.ResponseWriter, r *http.Request, relpath, abspath string) { - type elem struct { - Name string - Title string - } - - dir, err := fs.ReadDir(abspath) - if err != nil { - log.Print(err) - pres.ServeError(w, r, relpath, err) - return - } - var v []interface{} - for _, fi := range dir { - name := fi.Name() - if fi.IsDir() { - v = append(v, &elem{name + "/", ""}) - } else if strings.HasSuffix(name, ".xml") { - cw, err := loadCodewalk(abspath + "/" + name) - if err != nil { - continue - } - v = append(v, &elem{name[0 : len(name)-len(".xml")], cw.Title}) - } - } - - pres.ServePage(w, godoc.Page{ - Title: "Codewalks", - Body: applyTemplate(codewalkdirHTML, "codewalkdir", v), - }) -} - -// codewalkFileprint serves requests with ?fileprint=f&lo=lo&hi=hi. -// The filename f has already been retrieved and is passed as an argument. -// Lo and hi are the numbers of the first and last line to highlight -// in the response. This format is used for the middle window pane -// of the codewalk pages. It is a separate iframe and does not get -// the usual godoc HTML wrapper. -func codewalkFileprint(w http.ResponseWriter, r *http.Request, f string) { - abspath := f - data, err := vfs.ReadFile(fs, abspath) - if err != nil { - log.Print(err) - pres.ServeError(w, r, f, err) - return - } - lo, _ := strconv.Atoi(r.FormValue("lo")) - hi, _ := strconv.Atoi(r.FormValue("hi")) - if hi < lo { - hi = lo - } - lo = lineToByte(data, lo) - hi = lineToByte(data, hi+1) - - // Put the mark 4 lines before lo, so that the iframe - // shows a few lines of context before the highlighted - // section. - n := 4 - mark := lo - for ; mark > 0 && n > 0; mark-- { - if data[mark-1] == '\n' { - if n--; n == 0 { - break - } - } - } - - io.WriteString(w, `
`)
-	template.HTMLEscape(w, data[0:mark])
-	io.WriteString(w, "")
-	template.HTMLEscape(w, data[mark:lo])
-	if lo < hi {
-		io.WriteString(w, "
") - template.HTMLEscape(w, data[lo:hi]) - io.WriteString(w, "
") - } - template.HTMLEscape(w, data[hi:]) - io.WriteString(w, "
") -} - -// addrToByte evaluates the given address starting at offset start in data. -// It returns the lo and hi byte offset of the matched region within data. -// See http://9p.io/sys/doc/sam/sam.html Table II for details on the syntax. -func addrToByteRange(addr string, start int, data []byte) (lo, hi int, err error) { - var ( - dir byte - prevc byte - charOffset bool - ) - lo = start - hi = start - for addr != "" && err == nil { - c := addr[0] - switch c { - default: - err = errors.New("invalid address syntax near " + string(c)) - case ',': - if len(addr) == 1 { - hi = len(data) - } else { - _, hi, err = addrToByteRange(addr[1:], hi, data) - } - return - - case '+', '-': - if prevc == '+' || prevc == '-' { - lo, hi, err = addrNumber(data, lo, hi, prevc, 1, charOffset) - } - dir = c - - case '$': - lo = len(data) - hi = len(data) - if len(addr) > 1 { - dir = '+' - } - - case '#': - charOffset = true - - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - var i int - for i = 1; i < len(addr); i++ { - if addr[i] < '0' || addr[i] > '9' { - break - } - } - var n int - n, err = strconv.Atoi(addr[0:i]) - if err != nil { - break - } - lo, hi, err = addrNumber(data, lo, hi, dir, n, charOffset) - dir = 0 - charOffset = false - prevc = c - addr = addr[i:] - continue - - case '/': - var i, j int - Regexp: - for i = 1; i < len(addr); i++ { - switch addr[i] { - case '\\': - i++ - case '/': - j = i + 1 - break Regexp - } - } - if j == 0 { - j = i - } - pattern := addr[1:i] - lo, hi, err = addrRegexp(data, lo, hi, dir, pattern) - prevc = c - addr = addr[j:] - continue - } - prevc = c - addr = addr[1:] - } - - if err == nil && dir != 0 { - lo, hi, err = addrNumber(data, lo, hi, dir, 1, charOffset) - } - if err != nil { - return 0, 0, err - } - return lo, hi, nil -} - -// addrNumber applies the given dir, n, and charOffset to the address lo, hi. -// dir is '+' or '-', n is the count, and charOffset is true if the syntax -// used was #n. Applying +n (or +#n) means to advance n lines -// (or characters) after hi. Applying -n (or -#n) means to back up n lines -// (or characters) before lo. -// The return value is the new lo, hi. -func addrNumber(data []byte, lo, hi int, dir byte, n int, charOffset bool) (int, int, error) { - switch dir { - case 0: - lo = 0 - hi = 0 - fallthrough - - case '+': - if charOffset { - pos := hi - for ; n > 0 && pos < len(data); n-- { - _, size := utf8.DecodeRune(data[pos:]) - pos += size - } - if n == 0 { - return pos, pos, nil - } - break - } - // find next beginning of line - if hi > 0 { - for hi < len(data) && data[hi-1] != '\n' { - hi++ - } - } - lo = hi - if n == 0 { - return lo, hi, nil - } - for ; hi < len(data); hi++ { - if data[hi] != '\n' { - continue - } - switch n--; n { - case 1: - lo = hi + 1 - case 0: - return lo, hi + 1, nil - } - } - - case '-': - if charOffset { - // Scan backward for bytes that are not UTF-8 continuation bytes. - pos := lo - for ; pos > 0 && n > 0; pos-- { - if data[pos]&0xc0 != 0x80 { - n-- - } - } - if n == 0 { - return pos, pos, nil - } - break - } - // find earlier beginning of line - for lo > 0 && data[lo-1] != '\n' { - lo-- - } - hi = lo - if n == 0 { - return lo, hi, nil - } - for ; lo >= 0; lo-- { - if lo > 0 && data[lo-1] != '\n' { - continue - } - switch n--; n { - case 1: - hi = lo - case 0: - return lo, hi, nil - } - } - } - - return 0, 0, errors.New("address out of range") -} - -// addrRegexp searches for pattern in the given direction starting at lo, hi. -// The direction dir is '+' (search forward from hi) or '-' (search backward from lo). -// Backward searches are unimplemented. -func addrRegexp(data []byte, lo, hi int, dir byte, pattern string) (int, int, error) { - re, err := regexp.Compile(pattern) - if err != nil { - return 0, 0, err - } - if dir == '-' { - // Could implement reverse search using binary search - // through file, but that seems like overkill. - return 0, 0, errors.New("reverse search not implemented") - } - m := re.FindIndex(data[hi:]) - if len(m) > 0 { - m[0] += hi - m[1] += hi - } else if hi > 0 { - // No match. Wrap to beginning of data. - m = re.FindIndex(data) - } - if len(m) == 0 { - return 0, 0, errors.New("no match for " + pattern) - } - return m[0], m[1], nil -} - -// lineToByte returns the byte index of the first byte of line n. -// Line numbers begin at 1. -func lineToByte(data []byte, n int) int { - if n <= 1 { - return 0 - } - n-- - for i, c := range data { - if c == '\n' { - if n--; n == 0 { - return i + 1 - } - } - } - return len(data) -} - -// byteToLine returns the number of the line containing the byte at index i. -func byteToLine(data []byte, i int) int { - l := 1 - for j, c := range data { - if j == i { - return l - } - if c == '\n' { - l++ - } - } - return l -} diff --git a/cmd/godoc/dl.go b/cmd/godoc/dl.go deleted file mode 100644 index 962a0f0172..0000000000 --- a/cmd/godoc/dl.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2014 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 main - -import "net/http" - -// Register a redirect handler for /dl/ to the golang.org download page. -// This file will not be included when deploying godoc to golang.org. - -func init() { - http.Handle("/dl/", http.RedirectHandler("https://golang.org/dl/", http.StatusFound)) -} diff --git a/cmd/godoc/godoc_test.go b/cmd/godoc/godoc_test.go index 3748388fd8..7e44348919 100644 --- a/cmd/godoc/godoc_test.go +++ b/cmd/godoc/godoc_test.go @@ -81,7 +81,7 @@ func waitForServerReady(t *testing.T, cmd *exec.Cmd, addr string) { go func() { ch <- fmt.Errorf("server exited early: %v", cmd.Wait()) }() go waitForServer(t, ch, fmt.Sprintf("http://%v/", addr), - "The Go Programming Language", + "Go Documentation Server", 15*time.Second, false) if err := <-ch; err != nil { @@ -201,7 +201,7 @@ func TestURL(t *testing.T) { } } - t.Run("index", testcase("/", "Go is an open source programming language")) + t.Run("index", testcase("/", "These packages are part of the Go Project but outside the main Go tree.")) t.Run("fmt", testcase("/pkg/fmt", "Package fmt implements formatted I/O")) } @@ -286,8 +286,12 @@ package a; import _ "godoc.test/repo2/a"; const Name = "repo1a"`, releaseTag string // optional release tag that must be in go/build.ReleaseTags }{ { - path: "/", - contains: []string{"Go is an open source programming language"}, + path: "/", + contains: []string{ + "Go Documentation Server", + "Standard library", + "These packages are part of the Go Project but outside the main Go tree.", + }, }, { path: "/pkg/fmt/", diff --git a/cmd/godoc/handlers.go b/cmd/godoc/handlers.go index 2e98501898..a59301be51 100644 --- a/cmd/godoc/handlers.go +++ b/cmd/godoc/handlers.go @@ -2,14 +2,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// The /doc/codewalk/ tree is synthesized from codewalk descriptions, -// files named $GOROOT/doc/codewalk/*.xml. -// For an example and a description of the format, see -// http://golang.org/doc/codewalk/codewalk or run godoc -http=:6060 -// and see http://localhost:6060/doc/codewalk/codewalk . -// That page is itself a codewalk; the source code for it is -// $GOROOT/doc/codewalk/codewalk.xml. - package main import ( @@ -17,79 +9,39 @@ import ( "go/format" "log" "net/http" - "strings" "text/template" "golang.org/x/tools/godoc" - "golang.org/x/tools/godoc/golangorgenv" "golang.org/x/tools/godoc/redirect" "golang.org/x/tools/godoc/vfs" ) +// This package registers "/compile" and "/share" handlers +// that redirect to the golang.org playground. +import _ "golang.org/x/tools/playground" + var ( pres *godoc.Presentation fs = vfs.NameSpace{} ) -// hostEnforcerHandler redirects requests to "http://foo.golang.org/bar" -// to "https://golang.org/bar". -// It permits requests to the host "godoc-test.golang.org" for testing and -// golang.google.cn for Chinese users. -type hostEnforcerHandler struct { - h http.Handler -} - -func (h hostEnforcerHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - if !golangorgenv.EnforceHosts() { - h.h.ServeHTTP(w, r) - return - } - if !h.isHTTPS(r) || !h.validHost(r.Host) { - r.URL.Scheme = "https" - if h.validHost(r.Host) { - r.URL.Host = r.Host - } else { - r.URL.Host = "golang.org" - } - http.Redirect(w, r, r.URL.String(), http.StatusFound) - return - } - w.Header().Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload") - h.h.ServeHTTP(w, r) -} - -func (h hostEnforcerHandler) isHTTPS(r *http.Request) bool { - return r.TLS != nil || r.Header.Get("X-Forwarded-Proto") == "https" -} - -func (h hostEnforcerHandler) validHost(host string) bool { - switch strings.ToLower(host) { - case "golang.org", "golang.google.cn": - return true - } - if strings.HasSuffix(host, "-dot-golang-org.appspot.com") { - // staging/test - return true - } - return false -} - -func registerHandlers(pres *godoc.Presentation) *http.ServeMux { +func registerHandlers(pres *godoc.Presentation) { if pres == nil { panic("nil Presentation") } mux := http.NewServeMux() - mux.HandleFunc("/doc/codewalk/", codewalk) - mux.Handle("/doc/play/", pres.FileServer()) - mux.Handle("/robots.txt", pres.FileServer()) - mux.Handle("/", pres) + mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { + if req.URL.Path == "/" { + http.Redirect(w, req, "/pkg/", http.StatusFound) + return + } + pres.ServeHTTP(w, req) + }) mux.Handle("/pkg/C/", redirect.Handler("/cmd/cgo/")) mux.HandleFunc("/fmt", fmtHandler) redirect.Register(mux) - http.Handle("/", hostEnforcerHandler{mux}) - - return mux + http.Handle("/", mux) } func readTemplate(name string) *template.Template { @@ -113,8 +65,6 @@ func readTemplate(name string) *template.Template { } func readTemplates(p *godoc.Presentation) { - codewalkHTML = readTemplate("codewalk.html") - codewalkdirHTML = readTemplate("codewalkdir.html") p.CallGraphHTML = readTemplate("callgraph.html") p.DirlistHTML = readTemplate("dirlist.html") p.ErrorHTML = readTemplate("error.html") @@ -128,7 +78,6 @@ func readTemplates(p *godoc.Presentation) { p.SearchDocHTML = readTemplate("searchdoc.html") p.SearchCodeHTML = readTemplate("searchcode.html") p.SearchTxtHTML = readTemplate("searchtxt.html") - p.SearchDescXML = readTemplate("opensearch.xml") } type fmtResponse struct { diff --git a/cmd/godoc/index.go b/cmd/godoc/index.go deleted file mode 100644 index f84b29a29d..0000000000 --- a/cmd/godoc/index.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2015 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 main - -import "strings" - -func indexDirectoryDefault(dir string) bool { - return dir != "/pkg" && !strings.HasPrefix(dir, "/pkg/") -} diff --git a/cmd/godoc/main.go b/cmd/godoc/main.go index 1d402ba0bd..dc8a08159f 100644 --- a/cmd/godoc/main.go +++ b/cmd/godoc/main.go @@ -6,8 +6,7 @@ // Web server tree: // -// http://godoc/ main landing page -// http://godoc/doc/ serve from $GOROOT/doc - spec, mem, etc. +// http://godoc/ redirect to /pkg/ // http://godoc/src/ serve files from $GOROOT/src; .go gets pretty-printed // http://godoc/cmd/ serve documentation about commands // http://godoc/pkg/ serve documentation about packages @@ -164,8 +163,6 @@ func main() { certInit() } - playEnabled = *showPlayground - // Check usage. if flag.NArg() > 0 { fmt.Fprintln(os.Stderr, `Unexpected arguments. Use "go doc" for command-line help output instead. For example, "go doc fmt.Printf".`) @@ -276,7 +273,9 @@ func main() { corpus.IndexFullText = false } corpus.IndexFiles = *indexFiles - corpus.IndexDirectory = indexDirectoryDefault + corpus.IndexDirectory = func(dir string) bool { + return dir != "/pkg" && !strings.HasPrefix(dir, "/pkg/") + } corpus.IndexThrottle = *indexThrottle corpus.IndexInterval = *indexInterval if *writeIndex || *urlFlag != "" { diff --git a/cmd/godoc/play.go b/cmd/godoc/play.go deleted file mode 100644 index a899353e68..0000000000 --- a/cmd/godoc/play.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2012 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 main - -// This package registers "/compile" and "/share" handlers -// that redirect to the golang.org playground. -import _ "golang.org/x/tools/playground" diff --git a/godoc/pres.go b/godoc/pres.go index 7cedcb54e1..1daa5a125b 100644 --- a/godoc/pres.go +++ b/godoc/pres.go @@ -38,7 +38,7 @@ type Presentation struct { SearchDocHTML, SearchCodeHTML, SearchTxtHTML, - SearchDescXML *template.Template + SearchDescXML *template.Template // If not nil, register a /opensearch.xml handler with this template. // TabWidth optionally specifies the tab width. TabWidth int @@ -129,7 +129,9 @@ func NewPresentation(c *Corpus) *Presentation { p.pkgHandler.registerWithMux(p.mux) p.mux.HandleFunc("/", p.ServeFile) p.mux.HandleFunc("/search", p.HandleSearch) - p.mux.HandleFunc("/opensearch.xml", p.serveSearchDesc) + if p.SearchDescXML != nil { + p.mux.HandleFunc("/opensearch.xml", p.serveSearchDesc) + } return p } diff --git a/godoc/static/codewalk.html b/godoc/static/codewalk.html deleted file mode 100644 index 0f3d22a20c..0000000000 --- a/godoc/static/codewalk.html +++ /dev/null @@ -1,56 +0,0 @@ - - - - - -
-
-
-
-
- - Pop Out Code - - -
-
- -
-
-
- code on leftright - code width 70% - filepaths shownhidden -
-
-
-
- {{range .Step}} -
- -
{{html .Title}}
-
- {{with .Err}} - ERROR LOADING FILE: {{html .}}

- {{end}} - {{.XML}} -
-
{{html .}}
-
- {{end}} -
-
- previous step - • - next step -
-
-
diff --git a/godoc/static/codewalkdir.html b/godoc/static/codewalkdir.html deleted file mode 100644 index b7674c6ce9..0000000000 --- a/godoc/static/codewalkdir.html +++ /dev/null @@ -1,16 +0,0 @@ - - - -{{range .}} - - {{$name_html := html .Name}} - - - - -{{end}} -
{{$name_html}} {{html .Title}}
diff --git a/godoc/static/gen.go b/godoc/static/gen.go index 76f7d34b37..c1c308d1eb 100644 --- a/godoc/static/gen.go +++ b/godoc/static/gen.go @@ -33,8 +33,6 @@ var files = []string{ "analysis/typeinfo-pkg.png", "analysis/typeinfo-src.png", "callgraph.html", - "codewalk.html", - "codewalkdir.html", "dirlist.html", "error.html", "example.html", @@ -54,7 +52,6 @@ var files = []string{ "jquery.treeview.edit.js", "jquery.treeview.js", "methodset.html", - "opensearch.xml", "package.html", "packageroot.html", "play.js", diff --git a/godoc/static/godoc.html b/godoc/static/godoc.html index 89e089bad0..86cacb707b 100644 --- a/godoc/static/godoc.html +++ b/godoc/static/godoc.html @@ -5,31 +5,15 @@ {{with .Tabtitle}} - {{html .}} - The Go Programming Language + {{html .}} - Go Documentation Server {{else}} - The Go Programming Language + Go Documentation Server {{end}} -{{if .SearchBox}} - -{{end}} {{if .TreeView}} {{end}} -{{with .GoogleAnalytics}} - -{{end}} {{if .TreeView}} @@ -49,18 +33,11 @@ window.trackEvent = function(category, action, opt_label, opt_value, opt_noninte
- - + +
-{{if .GoogleAnalytics}} - -{{end}} - diff --git a/godoc/static/opensearch.xml b/godoc/static/opensearch.xml deleted file mode 100644 index 1b652db376..0000000000 --- a/godoc/static/opensearch.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - godoc - The Go Programming Language - go golang - - - /favicon.ico - UTF-8 - UTF-8 - diff --git a/godoc/static/static.go b/godoc/static/static.go index 46c1d2397c..5950f2d643 100644 --- a/godoc/static/static.go +++ b/godoc/static/static.go @@ -41,17 +41,13 @@ var Files = map[string]string{ "callgraph.html": "\x0a\x09\x0a\x09\x09\xe2\x96\xb9\x20Internal\x20call\x20graph

\x0a\x09
\x0a\x09\x0a\x09\x09\xe2\x96\xbe\x20Internal\x20call\x20graph

\x0a\x09\x09

\x0a\x09\x09\x20\x20This\x20viewer\x20shows\x20the\x20portion\x20of\x20the\x20internal\x20call\x0a\x09\x09\x20\x20graph\x20of\x20this\x20package\x20that\x20is\x20reachable\x20from\x20this\x20function.\x0a\x09\x09\x20\x20See\x20the\x20package's\x20call\x0a\x09\x09\x20\x20graph\x20for\x20more\x20information.\x0a\x09\x09

\x0a\x09\x09\x0a\x09\x0a\x0a", - "codewalk.html": "\x0a\x0a@import\x20\"/doc/codewalk/codewalk.css\";\x0a\x0a\x0a\x0a\x20\x20\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\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\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20{{range\x20.File}}\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20{{html\x20.}}\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20{{end}}\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\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\x0a\x20\x20\x20\x20\x20\x20code\x20on\x20left\x20•\x20right\x0a\x20\x20\x20\x20\x20\x20code\x20width\x2070%\x0a\x20\x20\x20\x20\x20\x20filepaths\x20shown\x20•\x20hidden\x0a\x20\x20\x20\x20\x0a\x20\x20\x0a\x20\x20\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20{{range\x20.Step}}\x0a\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20{{html\x20.Title}}\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x09{{with\x20.Err}}\x0a\x09ERROR\x20LOADING\x20FILE:\x20{{html\x20.}}

\x0a\x09{{end}}\x0a\x20\x20\x20\x20\x20\x20\x20\x20{{.XML}}\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20{{html\x20.}}\x0a\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20{{end}}\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20previous\x20step\x0a\x20\x20\x20\x20\x20\x20•\x0a\x20\x20\x20\x20\x20\x20next\x20step\x0a\x20\x20\x20\x20\x0a\x20\x20\x0a\x0a", - - "codewalkdir.html": "\x0a\x0a\x0a{{range\x20.}}\x0a\x0a\x09{{$name_html\x20:=\x20html\x20.Name}}\x0a\x09{{$name_html}}\x0a\x09 \x0a\x09{{html\x20.Title}}\x0a\x0a{{end}}\x0a\x0a", - "dirlist.html": "\x0a\x0a

\x0a\x0a\x0a\x09File\x0a\x09 \x0a\x09Bytes\x0a\x09 \x0a\x09Modified\x0a\x0a\x0a\x09..\x0a\x0a{{range\x20.}}\x0a\x0a\x09{{$name_html\x20:=\x20fileInfoName\x20.\x20|\x20html}}\x0a\x09{{$name_html}}\x0a\x09\x0a\x09{{html\x20.Size}}\x0a\x09\x0a\x09{{fileInfoTime\x20.\x20|\x20html}}\x0a\x0a{{end}}\x0a\x0a\x0a

\x0a", "error.html": "\x0a\x0a

\x0a{{html\x20.}}\x0a

\x0a", "example.html": "\x0a\x09\x0a\x09\x09\xe2\x96\xb9\x20Example{{example_suffix\x20.Name}}

\x0a\x09\x0a\x09\x0a\x09\x09\xe2\x96\xbe\x20Example{{example_suffix\x20.Name}}

\x0a\x09\x09{{with\x20.Doc}}

{{html\x20.}}

{{end}}\x0a\x09\x09{{$output\x20:=\x20.Output}}\x0a\x09\x09{{with\x20.Play}}\x0a\x09\x09\x09\x0a\x09\x09\x09\x09{{html\x20.}}\x0a\x09\x09\x09\x09
{{html\x20$output}}
\x0a\x09\x09\x09\x09\x0a\x09\x09\x09\x09\x09Run\x0a\x09\x09\x09\x09\x09Format\x0a\x09\x09\x09\x09\x09{{if\x20not\x20$.GoogleCN}}\x0a\x09\x09\x09\x09\x09Share\x0a\x09\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09\x0a\x09\x09\x09\x0a\x09\x09{{else}}\x0a\x09\x09\x09

Code:

\x0a\x09\x09\x09{{.Code}}\x0a\x09\x09\x09{{with\x20.Output}}\x0a\x09\x09\x09

Output:

\x0a\x09\x09\x09{{html\x20.}}\x0a\x09\x09\x09{{end}}\x0a\x09\x09{{end}}\x0a\x09\x0a\x0a", - "godoc.html": "\x0a\x0a\x0a\x0a\x0a\x0a{{with\x20.Tabtitle}}\x0a\x20\x20{{html\x20.}}\x20-\x20The\x20Go\x20Programming\x20Language\x0a{{else}}\x0a\x20\x20The\x20Go\x20Programming\x20Language\x0a{{end}}\x0a\x0a{{if\x20.SearchBox}}\x0a\x0a{{end}}\x0a{{if\x20.TreeView}}\x0a\x0a{{end}}\x0a\x0a{{with\x20.GoogleAnalytics}}\x0a\x0avar\x20_gaq\x20=\x20_gaq\x20||\x20[];\x0a_gaq.push([\"_setAccount\",\x20\"{{.}}\"]);\x0awindow.trackPageview\x20=\x20function()\x20{\x0a\x20\x20_gaq.push([\"_trackPageview\",\x20location.pathname+location.hash]);\x0a};\x0awindow.trackPageview();\x0awindow.trackEvent\x20=\x20function(category,\x20action,\x20opt_label,\x20opt_value,\x20opt_noninteraction)\x20{\x0a\x20\x20_gaq.push([\"_trackEvent\",\x20category,\x20action,\x20opt_label,\x20opt_value,\x20opt_noninteraction]);\x0a};\x0a\x0a{{end}}\x0a\x0a{{if\x20.TreeView}}\x0a\x0a\x0a{{end}}\x0a\x0a{{if\x20.Playground}}\x0a\x0a{{end}}\x0a{{with\x20.Version}}{{end}}\x0a\x0a\x0a\x0a\x0a\x0a...\x0a\x0a\x0a\x0aThe\x20Go\x20Programming\x20Language\x0aGo\x0a▽\x0a\x0a\x0aDocuments\x0aPackages\x0aThe\x20Project\x0aHelp\x0a{{if\x20not\x20.GoogleCN}}\x0aBlog\x0a{{end}}\x0a{{if\x20(and\x20.Playground\x20.Title)}}\x0aPlay\x0a{{end}}\x0asubmit\x20search\x0a\x0a\x0a\x0a\x0a\x0a{{if\x20.Playground}}\x0a\x0a\x09package\x20main\x0a\x0aimport\x20\"fmt\"\x0a\x0afunc\x20main()\x20{\x0a\x09fmt.Println(\"Hello,\x20\xe4\xb8\x96\xe7\x95\x8c\")\x0a}\x0a\x09\x0a\x09\x0a\x09\x09Run\x0a\x09\x09Format\x0a\x09\x09{{if\x20not\x20$.GoogleCN}}\x0a\x09\x09Share\x0a\x09\x09{{end}}\x0a\x09\x0a\x0a{{end}}\x0a\x0a\x0a\x0a\x0a{{if\x20or\x20.Title\x20.SrcPath}}\x0a\x20\x20

\x0a\x20\x20\x20\x20{{html\x20.Title}}\x0a\x20\x20\x20\x20{{html\x20.SrcPath\x20|\x20srcBreadcrumb}}\x0a\x20\x20

\x0a{{end}}\x0a\x0a{{with\x20.Subtitle}}\x0a\x20\x20

{{html\x20.}}

\x0a{{end}}\x0a\x0a{{with\x20.SrcPath}}\x0a\x20\x20

\x0a\x20\x20\x20\x20Documentation:\x20{{html\x20.\x20|\x20srcToPkgLink}}\x0a\x20\x20

\x0a{{end}}\x0a\x0a{{/*\x20The\x20Table\x20of\x20Contents\x20is\x20automatically\x20inserted\x20in\x20this\x20
.\x0a\x20\x20\x20\x20\x20Do\x20not\x20delete\x20this\x20
.\x20*/}}\x0a
\x0a\x0a{{/*\x20Body\x20is\x20HTML-escaped\x20elsewhere\x20*/}}\x0a{{printf\x20\"%s\"\x20.Body}}\x0a\x0a\x0aBuild\x20version\x20{{html\x20.Version}}.
\x0aExcept\x20as\x20noted,\x0athe\x20content\x20of\x20this\x20page\x20is\x20licensed\x20under\x20the\x0aCreative\x20Commons\x20Attribution\x203.0\x20License,\x0aand\x20code\x20is\x20licensed\x20under\x20a\x20BSD\x20license.
\x0aTerms\x20of\x20Service\x20|\x0aPrivacy\x20Policy\x0a
\x0a\x0a\x0a\x0a{{if\x20.GoogleAnalytics}}\x0a\x0a(function()\x20{\x0a\x20\x20var\x20ga\x20=\x20document.createElement(\"script\");\x20ga.type\x20=\x20\"text/javascript\";\x20ga.async\x20=\x20true;\x0a\x20\x20ga.src\x20=\x20(\"https:\"\x20==\x20document.location.protocol\x20?\x20\"https://ssl\"\x20:\x20\"http://www\")\x20+\x20\".google-analytics.com/ga.js\";\x0a\x20\x20var\x20s\x20=\x20document.getElementsByTagName(\"script\")[0];\x20s.parentNode.insertBefore(ga,\x20s);\x0a})();\x0a\x0a{{end}}\x0a\x0a\x0a\x0a", + "godoc.html": "\x0a\x0a\x0a\x0a\x0a\x0a{{with\x20.Tabtitle}}\x0a\x20\x20{{html\x20.}}\x20-\x20Go\x20Documentation\x20Server\x0a{{else}}\x0a\x20\x20Go\x20Documentation\x20Server\x0a{{end}}\x0a\x0a{{if\x20.TreeView}}\x0a\x0a{{end}}\x0a\x0a\x0a{{if\x20.TreeView}}\x0a\x0a\x0a{{end}}\x0a\x0a{{if\x20.Playground}}\x0a\x0a{{end}}\x0a{{with\x20.Version}}{{end}}\x0a\x0a\x0a\x0a\x0a\x0a...\x0a\x0a\x0a\x0aGo\x20Documentation\x20Server\x0aGoDoc\x0a▽\x0a\x0a\x0a{{if\x20(and\x20.Playground\x20.Title)}}\x0aPlay\x0a{{end}}\x0asubmit\x20search\x0a\x0a\x0a\x0a\x0a\x0a{{if\x20.Playground}}\x0a\x0a\x09package\x20main\x0a\x0aimport\x20\"fmt\"\x0a\x0afunc\x20main()\x20{\x0a\x09fmt.Println(\"Hello,\x20\xe4\xb8\x96\xe7\x95\x8c\")\x0a}\x0a\x09\x0a\x09\x0a\x09\x09Run\x0a\x09\x09Format\x0a\x09\x09{{if\x20not\x20$.GoogleCN}}\x0a\x09\x09Share\x0a\x09\x09{{end}}\x0a\x09\x0a\x0a{{end}}\x0a\x0a\x0a\x0a\x0a{{if\x20or\x20.Title\x20.SrcPath}}\x0a\x20\x20

\x0a\x20\x20\x20\x20{{html\x20.Title}}\x0a\x20\x20\x20\x20{{html\x20.SrcPath\x20|\x20srcBreadcrumb}}\x0a\x20\x20

\x0a{{end}}\x0a\x0a{{with\x20.Subtitle}}\x0a\x20\x20

{{html\x20.}}

\x0a{{end}}\x0a\x0a{{with\x20.SrcPath}}\x0a\x20\x20

\x0a\x20\x20\x20\x20Documentation:\x20{{html\x20.\x20|\x20srcToPkgLink}}\x0a\x20\x20

\x0a{{end}}\x0a\x0a{{/*\x20The\x20Table\x20of\x20Contents\x20is\x20automatically\x20inserted\x20in\x20this\x20
.\x0a\x20\x20\x20\x20\x20Do\x20not\x20delete\x20this\x20
.\x20*/}}\x0a
\x0a\x0a{{/*\x20Body\x20is\x20HTML-escaped\x20elsewhere\x20*/}}\x0a{{printf\x20\"%s\"\x20.Body}}\x0a\x0a\x0aBuild\x20version\x20{{html\x20.Version}}.
\x0aExcept\x20as\x20noted,\x0athe\x20content\x20of\x20this\x20page\x20is\x20licensed\x20under\x20the\x0aCreative\x20Commons\x20Attribution\x203.0\x20License,\x0aand\x20code\x20is\x20licensed\x20under\x20a\x20BSD\x20license.
\x0aTerms\x20of\x20Service\x20|\x0aPrivacy\x20Policy\x0a
\x0a\x0a\x0a\x0a\x0a\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'use\x20strict';\x0a\x0a//\x20Mobile-friendly\x20topbar\x20menu\x0a$(function()\x20{\x0a\x20\x20var\x20menu\x20=\x20$('#menu');\x0a\x20\x20var\x20menuButton\x20=\x20$('#menu-button');\x0a\x20\x20var\x20menuButtonArrow\x20=\x20$('#menu-button-arrow');\x0a\x20\x20menuButton.click(function(event)\x20{\x0a\x20\x20\x20\x20menu.toggleClass('menu-visible');\x0a\x20\x20\x20\x20menuButtonArrow.toggleClass('vertical-flip');\x0a\x20\x20\x20\x20event.preventDefault();\x0a\x20\x20\x20\x20return\x20false;\x0a\x20\x20});\x0a});\x0a\x0a/*\x20Generates\x20a\x20table\x20of\x20contents:\x20looks\x20for\x20h2\x20and\x20h3\x20elements\x20and\x20generates\x0a\x20*\x20links.\x20\"Decorates\"\x20the\x20element\x20with\x20id==\"nav\"\x20with\x20this\x20table\x20of\x20contents.\x0a\x20*/\x0afunction\x20generateTOC()\x20{\x0a\x20\x20if\x20($('#manual-nav').length\x20>\x200)\x20{\x0a\x20\x20\x20\x20return;\x0a\x20\x20}\x0a\x0a\x20\x20//\x20For\x20search,\x20we\x20send\x20the\x20toc\x20precomputed\x20from\x20server-side.\x0a\x20\x20//\x20TODO:\x20Ideally,\x20this\x20should\x20always\x20be\x20precomputed\x20for\x20all\x20pages,\x20but\x20then\x0a\x20\x20//\x20we\x20need\x20to\x20do\x20HTML\x20parsing\x20on\x20the\x20server-side.\x0a\x20\x20if\x20(location.pathname\x20===\x20'/search')\x20{\x0a\x20\x20\x20\x20return;\x0a\x20\x20}\x0a\x0a\x20\x20var\x20nav\x20=\x20$('#nav');\x0a\x20\x20if\x20(nav.length\x20===\x200)\x20{\x0a\x20\x20\x20\x20return;\x0a\x20\x20}\x0a\x0a\x20\x20var\x20toc_items\x20=\x20[];\x0a\x20\x20$(nav).nextAll('h2,\x20h3').each(function()\x20{\x0a\x20\x20\x20\x20var\x20node\x20=\x20this;\x0a\x20\x20\x20\x20if\x20(node.id\x20==\x20'')\x0a\x20\x20\x20\x20\x20\x20node.id\x20=\x20'tmp_'\x20+\x20toc_items.length;\x0a\x20\x20\x20\x20var\x20link\x20=\x20$('').attr('href',\x20'#'\x20+\x20node.id).text($(node).text());\x0a\x20\x20\x20\x20var\x20item;\x0a\x20\x20\x20\x20if\x20($(node).is('h2'))\x20{\x0a\x20\x20\x20\x20\x20\x20item\x20=\x20$('
');\x0a\x20\x20\x20\x20}\x20else\x20{\x20//\x20h3\x0a\x20\x20\x20\x20\x20\x20item\x20=\x20$('');\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20item.append(link);\x0a\x20\x20\x20\x20toc_items.push(item);\x0a\x20\x20});\x0a\x20\x20if\x20(toc_items.length\x20<=\x201)\x20{\x0a\x20\x20\x20\x20return;\x0a\x20\x20}\x0a\x20\x20var\x20dl1\x20=\x20$('
');\x0a\x20\x20var\x20dl2\x20=\x20$('
');\x0a\x0a\x20\x20var\x20split_index\x20=\x20(toc_items.length\x20/\x202)\x20+\x201;\x0a\x20\x20if\x20(split_index\x20<\x208)\x20{\x0a\x20\x20\x20\x20split_index\x20=\x20toc_items.length;\x0a\x20\x20}\x0a\x20\x20for\x20(var\x20i\x20=\x200;\x20i\x20<\x20split_index;\x20i++)\x20{\x0a\x20\x20\x20\x20dl1.append(toc_items[i]);\x0a\x20\x20}\x0a\x20\x20for\x20(/*\x20keep\x20using\x20i\x20*/;\x20i\x20<\x20toc_items.length;\x20i++)\x20{\x0a\x20\x20\x20\x20dl2.append(toc_items[i]);\x0a\x20\x20}\x0a\x0a\x20\x20var\x20tocTable\x20=\x20$('').appendTo(nav);\x0a\x20\x20var\x20tocBody\x20=\x20$('').appendTo(tocTable);\x0a\x20\x20var\x20tocRow\x20=\x20$('').appendTo(tocBody);\x0a\x0a\x20\x20//\x201st\x20column\x0a\x20\x20$('').appendTo(tocRow).append(dl1);\x0a\x20\x20//\x202nd\x20column\x0a\x20\x20$('').appendTo(tocRow).append(dl2);\x0a}\x0a\x0afunction\x20bindToggle(el)\x20{\x0a\x20\x20$('.toggleButton',\x20el).click(function()\x20{\x0a\x20\x20\x20\x20if\x20($(this).closest(\".toggle,\x20.toggleVisible\")[0]\x20!=\x20el)\x20{\x0a\x20\x20\x20\x20\x20\x20//\x20Only\x20trigger\x20the\x20closest\x20toggle\x20header.\x0a\x20\x20\x20\x20\x20\x20return;\x0a\x20\x20\x20\x20}\x0a\x0a\x20\x20\x20\x20if\x20($(el).is('.toggle'))\x20{\x0a\x20\x20\x20\x20\x20\x20$(el).addClass('toggleVisible').removeClass('toggle');\x0a\x20\x20\x20\x20}\x20else\x20{\x0a\x20\x20\x20\x20\x20\x20$(el).addClass('toggle').removeClass('toggleVisible');\x0a\x20\x20\x20\x20}\x0a\x20\x20});\x0a}\x0a\x0afunction\x20bindToggles(selector)\x20{\x0a\x20\x20$(selector).each(function(i,\x20el)\x20{\x0a\x20\x20\x20\x20bindToggle(el);\x0a\x20\x20});\x0a}\x0a\x0afunction\x20bindToggleLink(el,\x20prefix)\x20{\x0a\x20\x20$(el).click(function()\x20{\x0a\x20\x20\x20\x20var\x20href\x20=\x20$(el).attr('href');\x0a\x20\x20\x20\x20var\x20i\x20=\x20href.indexOf('#'+prefix);\x0a\x20\x20\x20\x20if\x20(i\x20<\x200)\x20{\x0a\x20\x20\x20\x20\x20\x20return;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20var\x20id\x20=\x20'#'\x20+\x20prefix\x20+\x20href.slice(i+1+prefix.length);\x0a\x20\x20\x20\x20if\x20($(id).is('.toggle'))\x20{\x0a\x20\x20\x20\x20\x20\x20$(id).find('.toggleButton').first().click();\x0a\x20\x20\x20\x20}\x0a\x20\x20});\x0a}\x0afunction\x20bindToggleLinks(selector,\x20prefix)\x20{\x0a\x20\x20$(selector).each(function(i,\x20el)\x20{\x0a\x20\x20\x20\x20bindToggleLink(el,\x20prefix);\x0a\x20\x20});\x0a}\x0a\x0afunction\x20setupDropdownPlayground()\x20{\x0a\x20\x20if\x20(!$('#page').is('.wide'))\x20{\x0a\x20\x20\x20\x20return;\x20//\x20don't\x20show\x20on\x20front\x20page\x0a\x20\x20}\x0a\x20\x20var\x20button\x20=\x20$('#playgroundButton');\x0a\x20\x20var\x20div\x20=\x20$('#playground');\x0a\x20\x20var\x20setup\x20=\x20false;\x0a\x20\x20button.toggle(function()\x20{\x0a\x20\x20\x20\x20button.addClass('active');\x0a\x20\x20\x20\x20div.show();\x0a\x20\x20\x20\x20if\x20(setup)\x20{\x0a\x20\x20\x20\x20\x20\x20return;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20setup\x20=\x20true;\x0a\x20\x20\x20\x20playground({\x0a\x20\x20\x20\x20\x20\x20'codeEl':\x20$('.code',\x20div),\x0a\x20\x20\x20\x20\x20\x20'outputEl':\x20$('.output',\x20div),\x0a\x20\x20\x20\x20\x20\x20'runEl':\x20$('.run',\x20div),\x0a\x20\x20\x20\x20\x20\x20'fmtEl':\x20$('.fmt',\x20div),\x0a\x20\x20\x20\x20\x20\x20'shareEl':\x20$('.share',\x20div),\x0a\x20\x20\x20\x20\x20\x20'shareRedirect':\x20'//play.golang.org/p/'\x0a\x20\x20\x20\x20});\x0a\x20\x20},\x0a\x20\x20function()\x20{\x0a\x20\x20\x20\x20button.removeClass('active');\x0a\x20\x20\x20\x20div.hide();\x0a\x20\x20});\x0a\x20\x20$('#menu').css('min-width',\x20'+=60');\x0a\x0a\x20\x20//\x20Hide\x20inline\x20playground\x20if\x20we\x20click\x20somewhere\x20on\x20the\x20page.\x0a\x20\x20//\x20This\x20is\x20needed\x20in\x20mobile\x20devices,\x20where\x20the\x20\"Play\"\x20button\x0a\x20\x20//\x20is\x20not\x20clickable\x20once\x20the\x20playground\x20opens\x20up.\x0a\x20\x20$(\"#page\").click(function()\x20{\x0a\x20\x20\x20\x20if\x20(button.hasClass('active'))\x20{\x0a\x20\x20\x20\x20\x20\x20button.click();\x0a\x20\x20\x20\x20}\x0a\x20\x20});\x0a}\x0a\x0afunction\x20setupInlinePlayground()\x20{\x0a\x09'use\x20strict';\x0a\x09//\x20Set\x20up\x20playground\x20when\x20each\x20element\x20is\x20toggled.\x0a\x09$('div.play').each(function\x20(i,\x20el)\x20{\x0a\x09\x09//\x20Set\x20up\x20playground\x20for\x20this\x20example.\x0a\x09\x09var\x20setup\x20=\x20function()\x20{\x0a\x09\x09\x09var\x20code\x20=\x20$('.code',\x20el);\x0a\x09\x09\x09playground({\x0a\x09\x09\x09\x09'codeEl':\x20\x20\x20code,\x0a\x09\x09\x09\x09'outputEl':\x20$('.output',\x20el),\x0a\x09\x09\x09\x09'runEl':\x20\x20\x20\x20$('.run',\x20el),\x0a\x09\x09\x09\x09'fmtEl':\x20\x20\x20\x20$('.fmt',\x20el),\x0a\x09\x09\x09\x09'shareEl':\x20\x20$('.share',\x20el),\x0a\x09\x09\x09\x09'shareRedirect':\x20'//play.golang.org/p/'\x0a\x09\x09\x09});\x0a\x0a\x09\x09\x09//\x20Make\x20the\x20code\x20textarea\x20resize\x20to\x20fit\x20content.\x0a\x09\x09\x09var\x20resize\x20=\x20function()\x20{\x0a\x09\x09\x09\x09code.height(0);\x0a\x09\x09\x09\x09var\x20h\x20=\x20code[0].scrollHeight;\x0a\x09\x09\x09\x09code.height(h+20);\x20//\x20minimize\x20bouncing.\x0a\x09\x09\x09\x09code.closest('.input').height(h);\x0a\x09\x09\x09};\x0a\x09\x09\x09code.on('keydown',\x20resize);\x0a\x09\x09\x09code.on('keyup',\x20resize);\x0a\x09\x09\x09code.keyup();\x20//\x20resize\x20now.\x0a\x09\x09};\x0a\x0a\x09\x09//\x20If\x20example\x20already\x20visible,\x20set\x20up\x20playground\x20now.\x0a\x09\x09if\x20($(el).is(':visible'))\x20{\x0a\x09\x09\x09setup();\x0a\x09\x09\x09return;\x0a\x09\x09}\x0a\x0a\x09\x09//\x20Otherwise,\x20set\x20up\x20playground\x20when\x20example\x20is\x20expanded.\x0a\x09\x09var\x20built\x20=\x20false;\x0a\x09\x09$(el).closest('.toggle').click(function()\x20{\x0a\x09\x09\x09//\x20Only\x20set\x20up\x20once.\x0a\x09\x09\x09if\x20(!built)\x20{\x0a\x09\x09\x09\x09setup();\x0a\x09\x09\x09\x09built\x20=\x20true;\x0a\x09\x09\x09}\x0a\x09\x09});\x0a\x09});\x0a}\x0a\x0a//\x20fixFocus\x20tries\x20to\x20put\x20focus\x20to\x20div#page\x20so\x20that\x20keyboard\x20navigation\x20works.\x0afunction\x20fixFocus()\x20{\x0a\x20\x20var\x20page\x20=\x20$('div#page');\x0a\x20\x20var\x20topbar\x20=\x20$('div#topbar');\x0a\x20\x20page.css('outline',\x200);\x20//\x20disable\x20outline\x20when\x20focused\x0a\x20\x20page.attr('tabindex',\x20-1);\x20//\x20and\x20set\x20tabindex\x20so\x20that\x20it\x20is\x20focusable\x0a\x20\x20$(window).resize(function\x20(evt)\x20{\x0a\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//\x20front\x20of\x20page,\x20and\x20keyboard\x20event\x20will\x20go\x20to\x20the\x20former\x20by\x20default.)\x0a\x20\x20\x20\x20//\x20by\x20focusing\x20page,\x20keyboard\x20event\x20will\x20go\x20to\x20page\x20so\x20that\x20up/down\x20arrow,\x0a\x20\x20\x20\x20//\x20space,\x20etc.\x20will\x20work\x20as\x20expected.\x0a\x20\x20\x20\x20if\x20(topbar.css('position')\x20==\x20\"fixed\")\x0a\x20\x20\x20\x20\x20\x20page.focus();\x0a\x20\x20}).resize();\x0a}\x0a\x0afunction\x20toggleHash()\x20{\x0a\x20\x20var\x20id\x20=\x20window.location.hash.substring(1);\x0a\x20\x20//\x20Open\x20all\x20of\x20the\x20toggles\x20for\x20a\x20particular\x20hash.\x0a\x20\x20var\x20els\x20=\x20$(\x0a\x20\x20\x20\x20document.getElementById(id),\x0a\x20\x20\x20\x20$('a[name]').filter(function()\x20{\x0a\x20\x20\x20\x20\x20\x20return\x20$(this).attr('name')\x20==\x20id;\x0a\x20\x20\x20\x20})\x0a\x20\x20);\x0a\x0a\x20\x20while\x20(els.length)\x20{\x0a\x20\x20\x20\x20for\x20(var\x20i\x20=\x200;\x20i\x20<\x20els.length;\x20i++)\x20{\x0a\x20\x20\x20\x20\x20\x20var\x20el\x20=\x20$(els[i]);\x0a\x20\x20\x20\x20\x20\x20if\x20(el.is('.toggle'))\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20el.find('.toggleButton').first().click();\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20els\x20=\x20el.parent();\x0a\x20\x20}\x0a}\x0a\x0afunction\x20personalizeInstallInstructions()\x20{\x0a\x20\x20var\x20prefix\x20=\x20'?download=';\x0a\x20\x20var\x20s\x20=\x20window.location.search;\x0a\x20\x20if\x20(s.indexOf(prefix)\x20!=\x200)\x20{\x0a\x20\x20\x20\x20//\x20No\x20'download'\x20query\x20string;\x20detect\x20\"test\"\x20instructions\x20from\x20User\x20Agent.\x0a\x20\x20\x20\x20if\x20(navigator.platform.indexOf('Win')\x20!=\x20-1)\x20{\x0a\x20\x20\x20\x20\x20\x20$('.testUnix').hide();\x0a\x20\x20\x20\x20\x20\x20$('.testWindows').show();\x0a\x20\x20\x20\x20}\x20else\x20{\x0a\x20\x20\x20\x20\x20\x20$('.testUnix').show();\x0a\x20\x20\x20\x20\x20\x20$('.testWindows').hide();\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20return;\x0a\x20\x20}\x0a\x0a\x20\x20var\x20filename\x20=\x20s.substr(prefix.length);\x0a\x20\x20var\x20filenameRE\x20=\x20/^go1\\.\\d+(\\.\\d+)?([a-z0-9]+)?\\.([a-z0-9]+)(-[a-z0-9]+)?(-osx10\\.[68])?\\.([a-z.]+)$/;\x0a\x20\x20var\x20m\x20=\x20filenameRE.exec(filename);\x0a\x20\x20if\x20(!m)\x20{\x0a\x20\x20\x20\x20//\x20Can't\x20interpret\x20file\x20name;\x20bail.\x0a\x20\x20\x20\x20return;\x0a\x20\x20}\x0a\x20\x20$('.downloadFilename').text(filename);\x0a\x20\x20$('.hideFromDownload').hide();\x0a\x0a\x20\x20var\x20os\x20=\x20m[3];\x0a\x20\x20var\x20ext\x20=\x20m[6];\x0a\x20\x20if\x20(ext\x20!=\x20'tar.gz')\x20{\x0a\x20\x20\x20\x20$('#tarballInstructions').hide();\x0a\x20\x20}\x0a\x20\x20if\x20(os\x20!=\x20'darwin'\x20||\x20ext\x20!=\x20'pkg')\x20{\x0a\x20\x20\x20\x20$('#darwinPackageInstructions').hide();\x0a\x20\x20}\x0a\x20\x20if\x20(os\x20!=\x20'windows')\x20{\x0a\x20\x20\x20\x20$('#windowsInstructions').hide();\x0a\x20\x20\x20\x20$('.testUnix').show();\x0a\x20\x20\x20\x20$('.testWindows').hide();\x0a\x20\x20}\x20else\x20{\x0a\x20\x20\x20\x20if\x20(ext\x20!=\x20'msi')\x20{\x0a\x20\x20\x20\x20\x20\x20$('#windowsInstallerInstructions').hide();\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20if\x20(ext\x20!=\x20'zip')\x20{\x0a\x20\x20\x20\x20\x20\x20$('#windowsZipInstructions').hide();\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20$('.testUnix').hide();\x0a\x20\x20\x20\x20$('.testWindows').show();\x0a\x20\x20}\x0a\x0a\x20\x20var\x20download\x20=\x20\"https://dl.google.com/go/\"\x20+\x20filename;\x0a\x0a\x20\x20var\x20message\x20=\x20$(''+\x0a\x20\x20\x20\x20'Your\x20download\x20should\x20begin\x20shortly.\x20'+\x0a\x20\x20\x20\x20'If\x20it\x20does\x20not,\x20click\x20this\x20link.

');\x0a\x20\x20message.find('a').attr('href',\x20download);\x0a\x20\x20message.insertAfter('#nav');\x0a\x0a\x20\x20window.location\x20=\x20download;\x0a}\x0a\x0afunction\x20updateVersionTags()\x20{\x0a\x20\x20var\x20v\x20=\x20window.goVersion;\x0a\x20\x20if\x20(/^go[0-9.]+$/.test(v))\x20{\x0a\x20\x20\x20\x20$(\".versionTag\").empty().text(v);\x0a\x20\x20\x20\x20$(\".whereTag\").hide();\x0a\x20\x20}\x0a}\x0a\x0afunction\x20addPermalinks()\x20{\x0a\x20\x20function\x20addPermalink(source,\x20parent)\x20{\x0a\x20\x20\x20\x20var\x20id\x20=\x20source.attr(\"id\");\x0a\x20\x20\x20\x20if\x20(id\x20==\x20\"\"\x20||\x20id.indexOf(\"tmp_\")\x20===\x200)\x20{\x0a\x20\x20\x20\x20\x20\x20//\x20Auto-generated\x20permalink.\x0a\x20\x20\x20\x20\x20\x20return;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20if\x20(parent.find(\">\x20.permalink\").length)\x20{\x0a\x20\x20\x20\x20\x20\x20//\x20Already\x20attached.\x0a\x20\x20\x20\x20\x20\x20return;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20parent.append(\"\x20\").append($(\"¶\").attr(\"href\",\x20\"#\"\x20+\x20id));\x0a\x20\x20}\x0a\x0a\x20\x20$(\"#page\x20.container\").find(\"h2[id],\x20h3[id]\").each(function()\x20{\x0a\x20\x20\x20\x20var\x20el\x20=\x20$(this);\x0a\x20\x20\x20\x20addPermalink(el,\x20el);\x0a\x20\x20});\x0a\x0a\x20\x20$(\"#page\x20.container\").find(\"dl[id]\").each(function()\x20{\x0a\x20\x20\x20\x20var\x20el\x20=\x20$(this);\x0a\x20\x20\x20\x20//\x20Add\x20the\x20anchor\x20to\x20the\x20\"dt\"\x20element.\x0a\x20\x20\x20\x20addPermalink(el,\x20el.find(\">\x20dt\").first());\x0a\x20\x20});\x0a}\x0a\x0a$(\".js-expandAll\").click(function()\x20{\x0a\x20\x20if\x20($(this).hasClass(\"collapsed\"))\x20{\x0a\x20\x20\x20\x20toggleExamples('toggle');\x0a\x20\x20\x20\x20$(this).text(\"(Collapse\x20All)\");\x0a\x20\x20}\x20else\x20{\x0a\x20\x20\x20\x20toggleExamples('toggleVisible');\x0a\x20\x20\x20\x20$(this).text(\"(Expand\x20All)\");\x0a\x20\x20}\x0a\x20\x20$(this).toggleClass(\"collapsed\")\x0a});\x0a\x0afunction\x20toggleExamples(className)\x20{\x0a\x20\x20//\x20We\x20need\x20to\x20explicitly\x20iterate\x20through\x20divs\x20starting\x20with\x20\"example_\"\x0a\x20\x20//\x20to\x20avoid\x20toggling\x20Overview\x20and\x20Index\x20collapsibles.\x0a\x20\x20$(\"[id^='example_']\").each(function()\x20{\x0a\x20\x20\x20\x20//\x20Check\x20for\x20state\x20and\x20click\x20it\x20only\x20if\x20required.\x0a\x20\x20\x20\x20if\x20($(this).hasClass(className))\x20{\x0a\x20\x20\x20\x20\x20\x20$(this).find('.toggleButton').first().click();\x0a\x20\x20\x20\x20}\x0a\x20\x20});\x0a}\x0a\x0a$(document).ready(function()\x20{\x0a\x20\x20generateTOC();\x0a\x20\x20addPermalinks();\x0a\x20\x20bindToggles(\".toggle\");\x0a\x20\x20bindToggles(\".toggleVisible\");\x0a\x20\x20bindToggleLinks(\".exampleLink\",\x20\"example_\");\x0a\x20\x20bindToggleLinks(\".overviewLink\",\x20\"\");\x0a\x20\x20bindToggleLinks(\".examplesLink\",\x20\"\");\x0a\x20\x20bindToggleLinks(\".indexLink\",\x20\"\");\x0a\x20\x20setupDropdownPlayground();\x0a\x20\x20setupInlinePlayground();\x0a\x20\x20fixFocus();\x0a\x20\x20setupTypeInfo();\x0a\x20\x20setupCallgraphs();\x0a\x20\x20toggleHash();\x0a\x20\x20personalizeInstallInstructions();\x0a\x20\x20updateVersionTags();\x0a\x0a\x20\x20//\x20godoc.html\x20defines\x20window.initFuncs\x20in\x20the\x20\x20tag,\x20and\x20root.html\x20and\x0a\x20\x20//\x20codewalk.js\x20push\x20their\x20on-page-ready\x20functions\x20to\x20the\x20list.\x0a\x20\x20//\x20We\x20execute\x20those\x20functions\x20here,\x20to\x20avoid\x20loading\x20jQuery\x20until\x20the\x20page\x0a\x20\x20//\x20content\x20is\x20loaded.\x0a\x20\x20for\x20(var\x20i\x20=\x200;\x20i\x20<\x20window.initFuncs.length;\x20i++)\x20window.initFuncs[i]();\x0a});\x0a\x0a//\x20--\x20analysis\x20---------------------------------------------------------\x0a\x0a//\x20escapeHTML\x20returns\x20HTML\x20for\x20s,\x20with\x20metacharacters\x20quoted.\x0a//\x20It\x20is\x20safe\x20for\x20use\x20in\x20both\x20elements\x20and\x20attributes\x0a//\x20(unlike\x20the\x20\"set\x20innerText,\x20read\x20innerHTML\"\x20trick).\x0afunction\x20escapeHTML(s)\x20{\x0a\x20\x20\x20\x20return\x20s.replace(/&/g,\x20'&').\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20replace(/\\\"/g,\x20'"').\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20replace(/\\'/g,\x20''').\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20replace(//g,\x20'>');\x0a}\x0a\x0a//\x20makeAnchor\x20returns\x20HTML\x20for\x20an\x20\x20element,\x20given\x20an\x20anchorJSON\x20object.\x0afunction\x20makeAnchor(json)\x20{\x0a\x20\x20var\x20html\x20=\x20escapeHTML(json.Text);\x0a\x20\x20if\x20(json.Href\x20!=\x20\"\")\x20{\x0a\x20\x20\x20\x20\x20\x20html\x20=\x20\"\"\x20+\x20html\x20+\x20\"\";\x0a\x20\x20}\x0a\x20\x20return\x20html;\x0a}\x0a\x0afunction\x20showLowFrame(html)\x20{\x0a\x20\x20var\x20lowframe\x20=\x20document.getElementById('lowframe');\x0a\x20\x20lowframe.style.height\x20=\x20\"200px\";\x0a\x20\x20lowframe.innerHTML\x20=\x20\"\"\x20+\x20html\x20+\x20\"

\\n\"\x20+\x0a\x20\x20\x20\x20\x20\x20\"\xe2\x9c\x98\"\x0a};\x0a\x0adocument.hideLowFrame\x20=\x20function()\x20{\x0a\x20\x20var\x20lowframe\x20=\x20document.getElementById('lowframe');\x0a\x20\x20lowframe.style.height\x20=\x20\"0px\";\x0a}\x0a\x0a//\x20onClickCallers\x20is\x20the\x20onclick\x20action\x20for\x20the\x20'func'\x20tokens\x20of\x20a\x0a//\x20function\x20declaration.\x0adocument.onClickCallers\x20=\x20function(index)\x20{\x0a\x20\x20var\x20data\x20=\x20document.ANALYSIS_DATA[index]\x0a\x20\x20if\x20(data.Callers.length\x20==\x201\x20&&\x20data.Callers[0].Sites.length\x20==\x201)\x20{\x0a\x20\x20\x20\x20document.location\x20=\x20data.Callers[0].Sites[0].Href;\x20//\x20jump\x20to\x20sole\x20caller\x0a\x20\x20\x20\x20return;\x0a\x20\x20}\x0a\x0a\x20\x20var\x20html\x20=\x20\"Callers\x20of\x20\"\x20+\x20escapeHTML(data.Callee)\x20+\x20\":
\\n\";\x0a\x20\x20for\x20(var\x20i\x20=\x200;\x20i\x20<\x20data.Callers.length;\x20i++)\x20{\x0a\x20\x20\x20\x20var\x20caller\x20=\x20data.Callers[i];\x0a\x20\x20\x20\x20html\x20+=\x20\"\"\x20+\x20escapeHTML(caller.Func)\x20+\x20\"\";\x0a\x20\x20\x20\x20var\x20sites\x20=\x20caller.Sites;\x0a\x20\x20\x20\x20if\x20(sites\x20!=\x20null\x20&&\x20sites.length\x20>\x200)\x20{\x0a\x20\x20\x20\x20\x20\x20html\x20+=\x20\"\x20at\x20line\x20\";\x0a\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\x20if\x20(j\x20>\x200)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20html\x20+=\x20\",\x20\";\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20html\x20+=\x20\"\"\x20+\x20makeAnchor(sites[j])\x20+\x20\"\";\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20html\x20+=\x20\"
\\n\";\x0a\x20\x20}\x0a\x20\x20showLowFrame(html);\x0a};\x0a\x0a//\x20onClickCallees\x20is\x20the\x20onclick\x20action\x20for\x20the\x20'('\x20token\x20of\x20a\x20function\x20call.\x0adocument.onClickCallees\x20=\x20function(index)\x20{\x0a\x20\x20var\x20data\x20=\x20document.ANALYSIS_DATA[index]\x0a\x20\x20if\x20(data.Callees.length\x20==\x201)\x20{\x0a\x20\x20\x20\x20document.location\x20=\x20data.Callees[0].Href;\x20//\x20jump\x20to\x20sole\x20callee\x0a\x20\x20\x20\x20return;\x0a\x20\x20}\x0a\x0a\x20\x20var\x20html\x20=\x20\"Callees\x20of\x20this\x20\"\x20+\x20escapeHTML(data.Descr)\x20+\x20\":
\\n\";\x0a\x20\x20for\x20(var\x20i\x20=\x200;\x20i\x20<\x20data.Callees.length;\x20i++)\x20{\x0a\x20\x20\x20\x20html\x20+=\x20\"\"\x20+\x20makeAnchor(data.Callees[i])\x20+\x20\"
\\n\";\x0a\x20\x20}\x0a\x20\x20showLowFrame(html);\x0a};\x0a\x0a//\x20onClickTypeInfo\x20is\x20the\x20onclick\x20action\x20for\x20identifiers\x20declaring\x20a\x20named\x20type.\x0adocument.onClickTypeInfo\x20=\x20function(index)\x20{\x0a\x20\x20var\x20data\x20=\x20document.ANALYSIS_DATA[index];\x0a\x20\x20var\x20html\x20=\x20\"Type\x20\"\x20+\x20data.Name\x20+\x20\":\x20\"\x20+\x0a\x20\x20\"      (size=\"\x20+\x20data.Size\x20+\x20\",\x20align=\"\x20+\x20data.Align\x20+\x20\")
\\n\";\x0a\x20\x20html\x20+=\x20implementsHTML(data);\x0a\x20\x20html\x20+=\x20methodsetHTML(data);\x0a\x20\x20showLowFrame(html);\x0a};\x0a\x0a//\x20implementsHTML\x20returns\x20HTML\x20for\x20the\x20implements\x20relation\x20of\x20the\x0a//\x20specified\x20TypeInfoJSON\x20value.\x0afunction\x20implementsHTML(info)\x20{\x0a\x20\x20var\x20html\x20=\x20\"\";\x0a\x20\x20if\x20(info.ImplGroups\x20!=\x20null)\x20{\x0a\x20\x20\x20\x20for\x20(var\x20i\x20=\x200;\x20i\x20<\x20info.ImplGroups.length;\x20i++)\x20{\x0a\x20\x20\x20\x20\x20\x20var\x20group\x20=\x20info.ImplGroups[i];\x0a\x20\x20\x20\x20\x20\x20var\x20x\x20=\x20\"\"\x20+\x20escapeHTML(group.Descr)\x20+\x20\"\x20\";\x0a\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\x20var\x20fact\x20=\x20group.Facts[j];\x0a\x20\x20\x20\x20\x20\x20\x20\x20var\x20y\x20=\x20\"\"\x20+\x20makeAnchor(fact.Other)\x20+\x20\"\";\x0a\x20\x20\x20\x20\x20\x20\x20\x20if\x20(fact.ByKind\x20!=\x20null)\x20{\x0a\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}\x20else\x20{\x0a\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}\x0a\x20\x20\x20\x20\x20\x20\x20\x20html\x20+=\x20\"
\\n\";\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20}\x0a\x20\x20}\x0a\x20\x20return\x20html;\x0a}\x0a\x0a\x0a//\x20methodsetHTML\x20returns\x20HTML\x20for\x20the\x20methodset\x20of\x20the\x20specified\x0a//\x20TypeInfoJSON\x20value.\x0afunction\x20methodsetHTML(info)\x20{\x0a\x20\x20var\x20html\x20=\x20\"\";\x0a\x20\x20if\x20(info.Methods\x20!=\x20null)\x20{\x0a\x20\x20\x20\x20for\x20(var\x20i\x20=\x200;\x20i\x20<\x20info.Methods.length;\x20i++)\x20{\x0a\x20\x20\x20\x20\x20\x20html\x20+=\x20\"\"\x20+\x20makeAnchor(info.Methods[i])\x20+\x20\"
\\n\";\x0a\x20\x20\x20\x20}\x0a\x20\x20}\x0a\x20\x20return\x20html;\x0a}\x0a\x0a//\x20onClickComm\x20is\x20the\x20onclick\x20action\x20for\x20channel\x20\"make\"\x20and\x20\"<-\"\x0a//\x20send/receive\x20tokens.\x0adocument.onClickComm\x20=\x20function(index)\x20{\x0a\x20\x20var\x20ops\x20=\x20document.ANALYSIS_DATA[index].Ops\x0a\x20\x20if\x20(ops.length\x20==\x201)\x20{\x0a\x20\x20\x20\x20document.location\x20=\x20ops[0].Op.Href;\x20//\x20jump\x20to\x20sole\x20element\x0a\x20\x20\x20\x20return;\x0a\x20\x20}\x0a\x0a\x20\x20var\x20html\x20=\x20\"Operations\x20on\x20this\x20channel:
\\n\";\x0a\x20\x20for\x20(var\x20i\x20=\x200;\x20i\x20<\x20ops.length;\x20i++)\x20{\x0a\x20\x20\x20\x20html\x20+=\x20makeAnchor(ops[i].Op)\x20+\x20\"\x20by\x20\"\x20+\x20escapeHTML(ops[i].Fn)\x20+\x20\"
\\n\";\x0a\x20\x20}\x0a\x20\x20if\x20(ops.length\x20==\x200)\x20{\x0a\x20\x20\x20\x20html\x20+=\x20\"(none)
\\n\";\x0a\x20\x20}\x0a\x20\x20showLowFrame(html);\x0a};\x0a\x0a$(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\x09elts[0].scrollIntoView()\x0a\x20\x20\x20\x20}\x0a});\x0a\x0a//\x20setupTypeInfo\x20populates\x20the\x20\"Implements\"\x20and\x20\"Method\x20set\"\x20toggle\x20for\x0a//\x20each\x20type\x20in\x20the\x20package\x20doc.\x0afunction\x20setupTypeInfo()\x20{\x0a\x20\x20for\x20(var\x20i\x20in\x20document.ANALYSIS_DATA)\x20{\x0a\x20\x20\x20\x20var\x20data\x20=\x20document.ANALYSIS_DATA[i];\x0a\x0a\x20\x20\x20\x20var\x20el\x20=\x20document.getElementById(\"implements-\"\x20+\x20i);\x0a\x20\x20\x20\x20if\x20(el\x20!=\x20null)\x20{\x0a\x20\x20\x20\x20\x20\x20//\x20el\x20!=\x20null\x20=>\x20data\x20is\x20TypeInfoJSON.\x0a\x20\x20\x20\x20\x20\x20if\x20(data.ImplGroups\x20!=\x20null)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20el.innerHTML\x20=\x20implementsHTML(data);\x0a\x20\x20\x20\x20\x20\x20\x20\x20el.parentNode.parentNode.style.display\x20=\x20\"block\";\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20}\x0a\x0a\x20\x20\x20\x20var\x20el\x20=\x20document.getElementById(\"methodset-\"\x20+\x20i);\x0a\x20\x20\x20\x20if\x20(el\x20!=\x20null)\x20{\x0a\x20\x20\x20\x20\x20\x20//\x20el\x20!=\x20null\x20=>\x20data\x20is\x20TypeInfoJSON.\x0a\x20\x20\x20\x20\x20\x20if\x20(data.Methods\x20!=\x20null)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20el.innerHTML\x20=\x20methodsetHTML(data);\x0a\x20\x20\x20\x20\x20\x20\x20\x20el.parentNode.parentNode.style.display\x20=\x20\"block\";\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20}\x0a\x20\x20}\x0a}\x0a\x0afunction\x20setupCallgraphs()\x20{\x0a\x20\x20if\x20(document.CALLGRAPH\x20==\x20null)\x20{\x0a\x20\x20\x20\x20return\x0a\x20\x20}\x0a\x20\x20document.getElementById(\"pkg-callgraph\").style.display\x20=\x20\"block\";\x0a\x0a\x20\x20var\x20treeviews\x20=\x20document.getElementsByClassName(\"treeview\");\x0a\x20\x20for\x20(var\x20i\x20=\x200;\x20i\x20<\x20treeviews.length;\x20i++)\x20{\x0a\x20\x20\x20\x20var\x20tree\x20=\x20treeviews[i];\x0a\x20\x20\x20\x20if\x20(tree.id\x20==\x20null\x20||\x20tree.id.indexOf(\"callgraph-\")\x20!=\x200)\x20{\x0a\x20\x20\x20\x20\x20\x20continue;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20var\x20id\x20=\x20tree.id.substring(\"callgraph-\".length);\x0a\x20\x20\x20\x20$(tree).treeview({collapsed:\x20true,\x20animated:\x20\"fast\"});\x0a\x20\x20\x20\x20document.cgAddChildren(tree,\x20tree,\x20[id]);\x0a\x20\x20\x20\x20tree.parentNode.parentNode.style.display\x20=\x20\"block\";\x0a\x20\x20}\x0a}\x0a\x0adocument.cgAddChildren\x20=\x20function(tree,\x20ul,\x20indices)\x20{\x0a\x20\x20if\x20(indices\x20!=\x20null)\x20{\x0a\x20\x20\x20\x20for\x20(var\x20i\x20=\x200;\x20i\x20<\x20indices.length;\x20i++)\x20{\x0a\x20\x20\x20\x20\x20\x20var\x20li\x20=\x20cgAddChild(tree,\x20ul,\x20document.CALLGRAPH[indices[i]]);\x0a\x20\x20\x20\x20\x20\x20if\x20(i\x20==\x20indices.length\x20-\x201)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20$(li).addClass(\"last\");\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20}\x0a\x20\x20}\x0a\x20\x20$(tree).treeview({animated:\x20\"fast\",\x20add:\x20ul});\x0a}\x0a\x0a//\x20cgAddChild\x20adds\x20an\x20
  • \x20element\x20for\x20document.CALLGRAPH\x20node\x20cgn\x20to\x0a//\x20the\x20parent\x20
      \x20element\x20ul.\x20tree\x20is\x20the\x20tree's\x20root\x20
        \x20element.\x0afunction\x20cgAddChild(tree,\x20ul,\x20cgn)\x20{\x0a\x20\x20\x20var\x20li\x20=\x20document.createElement(\"li\");\x0a\x20\x20\x20ul.appendChild(li);\x0a\x20\x20\x20li.className\x20=\x20\"closed\";\x0a\x0a\x20\x20\x20var\x20code\x20=\x20document.createElement(\"code\");\x0a\x0a\x20\x20\x20if\x20(cgn.Callees\x20!=\x20null)\x20{\x0a\x20\x20\x20\x20\x20$(li).addClass(\"expandable\");\x0a\x0a\x20\x20\x20\x20\x20//\x20Event\x20handlers\x20and\x20innerHTML\x20updates\x20don't\x20play\x20nicely\x20together,\x0a\x20\x20\x20\x20\x20//\x20hence\x20all\x20this\x20explicit\x20DOM\x20manipulation.\x0a\x20\x20\x20\x20\x20var\x20hitarea\x20=\x20document.createElement(\"div\");\x0a\x20\x20\x20\x20\x20hitarea.className\x20=\x20\"hitarea\x20expandable-hitarea\";\x0a\x20\x20\x20\x20\x20li.appendChild(hitarea);\x0a\x0a\x20\x20\x20\x20\x20li.appendChild(code);\x0a\x0a\x20\x20\x20\x20\x20var\x20childUL\x20=\x20document.createElement(\"ul\");\x0a\x20\x20\x20\x20\x20li.appendChild(childUL);\x0a\x20\x20\x20\x20\x20childUL.setAttribute('style',\x20\"display:\x20none;\");\x0a\x0a\x20\x20\x20\x20\x20var\x20onClick\x20=\x20function()\x20{\x0a\x20\x20\x20\x20\x20\x20\x20document.cgAddChildren(tree,\x20childUL,\x20cgn.Callees);\x0a\x20\x20\x20\x20\x20\x20\x20hitarea.removeEventListener('click',\x20onClick)\x0a\x20\x20\x20\x20\x20};\x0a\x20\x20\x20\x20\x20hitarea.addEventListener('click',\x20onClick);\x0a\x0a\x20\x20\x20}\x20else\x20{\x0a\x20\x20\x20\x20\x20li.appendChild(code);\x0a\x20\x20\x20}\x0a\x20\x20\x20code.innerHTML\x20+=\x20\" \"\x20+\x20makeAnchor(cgn.Func);\x0a\x20\x20\x20return\x20li\x0a}\x0a\x0a})();\x0a", @@ -83,8 +79,6 @@ var Files = map[string]string{ "methodset.html": "\x0a\x09\x0a\x09\x09\xe2\x96\xb9\x20Method\x20set

        \x0a\x09\x0a\x09\x0a\x09\x09\xe2\x96\xbe\x20Method\x20set

        \x0a\x09\x09...\x0a\x09\x0a\x0a", - "opensearch.xml": "\x0a\x0a\x20\x20godoc\x0a\x20\x20The\x20Go\x20Programming\x20Language\x0a\x20\x20go\x20golang\x0a\x20\x20\x0a\x20\x20\x0a\x20\x20/favicon.ico\x0a\x20\x20UTF-8\x0a\x20\x20UTF-8\x0a\x0a", - "package.html": "\x0a\x0a{{with\x20.PDoc}}\x0a\x09\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\x0a\x09\x09\x09
        \x0a\x09\x09\x09
        import\x20\"{{html\x20.ImportPath}}\"
        \x0a\x09\x09\x09
        \x0a\x09\x09\x09
        \x0a\x09\x09\x09
        Overview
        \x0a\x09\x09\x09
        Index
        \x0a\x09\x09\x09{{if\x20$.Examples}}\x0a\x09\x09\x09\x09
        Examples
        \x0a\x09\x09\x09{{end}}\x0a\x09\x09\x09{{if\x20$.Dirs}}\x0a\x09\x09\x09\x09
        Subdirectories
        \x0a\x09\x09\x09{{end}}\x0a\x09\x09\x09
        \x0a\x09\x09\x0a\x09\x09\x0a\x09\x09\x0a\x09\x09\x09\x0a\x09\x09\x09\x09Overview\x20\xe2\x96\xb9\x0a\x09\x09\x09\x0a\x09\x09\x09\x0a\x09\x09\x09\x09Overview\x20\xe2\x96\xbe\x0a\x09\x09\x09\x09{{comment_html\x20.Doc}}\x0a\x09\x09\x09\x09{{example_html\x20$\x20\"\"}}\x0a\x09\x09\x09\x0a\x09\x09\x0a\x0a\x09\x09\x0a\x09\x09\x0a\x09\x09\x09Index\x20\xe2\x96\xb9\x0a\x09\x09\x0a\x09\x09\x0a\x09\x09\x09Index\x20\xe2\x96\xbe\x0a\x0a\x09\x09\x0a\x09\x09\x09\x0a\x09\x09\x09
        \x0a\x09\x09\x09{{if\x20.Consts}}\x0a\x09\x09\x09\x09
        Constants
        \x0a\x09\x09\x09{{end}}\x0a\x09\x09\x09{{if\x20.Vars}}\x0a\x09\x09\x09\x09
        Variables
        \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
        {{node_html\x20$\x20.Decl\x20false\x20|\x20sanitize}}
        \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
        type\x20{{$tname_html}}
        \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
         \x20 \x20{{node_html\x20$\x20.Decl\x20false\x20|\x20sanitize}}
        \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
         \x20 \x20{{node_html\x20$\x20.Decl\x20false\x20|\x20sanitize}}
        \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
        {{noteTitle\x20$marker\x20|\x20html}}s
        \x0a\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09{{end}}\x0a\x09\x09\x09
        \x0a\x09\x09\x09\x0a\x0a\x09\x09{{if\x20$.Examples}}\x0a\x09\x09\x0a\x09\x09\x09

        Examples

        \x0a\x09\x09\x09(Expand\x20All)\x0a\x09\x09\x09
        \x0a\x09\x09\x09{{range\x20$.Examples}}\x0a\x09\x09\x09
        {{example_name\x20.Name}}
        \x0a\x09\x09\x09{{end}}\x0a\x09\x09\x09
        \x0a\x09\x09\x0a\x09\x09{{end}}\x0a\x0a\x09\x09{{with\x20.Filenames}}\x0a\x09\x09\x09

        Package\x20files

        \x0a\x09\x09\x09

        \x0a\x09\x09\x09\x0a\x09\x09\x09{{range\x20.}}\x0a\x09\x09\x09\x09{{.|filename|html}}\x0a\x09\x09\x09{{end}}\x0a\x09\x09\x09\x0a\x09\x09\x09

        \x0a\x09\x09{{end}}\x0a\x09\x09\x0a\x09\x09\x0a\x0a\x09\x09{{if\x20ne\x20$.CallGraph\x20\"null\"}}\x0a\x09\x09\x0a\x09\x09\x0a\x09\x09\x09Internal\x20call\x20graph\x20\xe2\x96\xb9\x0a\x09\x09\x20\x0a\x09\x09\x0a\x09\x09\x09Internal\x20call\x20graph\x20\xe2\x96\xbe\x0a\x09\x09\x09

        \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—perhaps\x20dynamically.\x0a\x09\x09\x09

        \x0a\x09\x09\x09

        \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

        \x0a\x09\x09\x09

        \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\x20func\x0a\x09\x09\x09\x20\x20token.\x0a\x09\x09\x09

        \x0a\x09\x09\x09

        \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

        \x0a\x09\x09\x09\x0a\x09\x09\x09
      \x0a\x09\x09\x0a\x09\x09\x20\x0a\x09\x09{{end}}\x0a\x0a\x09\x09{{with\x20.Consts}}\x0a\x09\x09\x09Constants\x0a\x09\x09\x09{{range\x20.}}\x0a\x09\x09\x09\x09{{comment_html\x20.Doc}}\x0a\x09\x09\x09\x09
      {{node_html\x20$\x20.Decl\x20true}}
      \x0a\x09\x09\x09{{end}}\x0a\x09\x09{{end}}\x0a\x09\x09{{with\x20.Vars}}\x0a\x09\x09\x09Variables\x0a\x09\x09\x09{{range\x20.}}\x0a\x09\x09\x09\x09{{comment_html\x20.Doc}}\x0a\x09\x09\x09\x09
      {{node_html\x20$\x20.Decl\x20true}}
      \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\x09func\x20{{$name_html}}\x0a\x09\x09\x09\x09¶\x0a\x09\x09\x09\x09{{$since\x20:=\x20since\x20\"func\"\x20\"\"\x20.Name\x20$.PDoc.ImportPath}}\x0a\x09\x09\x09\x09{{if\x20$since}}{{$since}}{{end}}\x0a\x09\x09\x09\x0a\x09\x09\x09
      {{node_html\x20$\x20.Decl\x20true}}
      \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\x09type\x20{{$tname_html}}\x0a\x09\x09\x09\x09¶\x0a\x09\x09\x09\x09{{$since\x20:=\x20since\x20\"type\"\x20\"\"\x20.Name\x20$.PDoc.ImportPath}}\x0a\x09\x09\x09\x09{{if\x20$since}}{{$since}}{{end}}\x0a\x09\x09\x09\x0a\x09\x09\x09{{comment_html\x20.Doc}}\x0a\x09\x09\x09
      {{node_html\x20$\x20.Decl\x20true}}
      \x0a\x0a\x09\x09\x09{{range\x20.Consts}}\x0a\x09\x09\x09\x09{{comment_html\x20.Doc}}\x0a\x09\x09\x09\x09
      {{node_html\x20$\x20.Decl\x20true}}
      \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
      {{node_html\x20$\x20.Decl\x20true}}
      \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\x09func\x20{{$name_html}}\x0a\x09\x09\x09\x09\x09¶\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}}{{$since}}{{end}}\x0a\x09\x09\x09\x09\x0a\x09\x09\x09\x09
      {{node_html\x20$\x20.Decl\x20true}}
      \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\x09func\x20({{html\x20.Recv}})\x20{{$name_html}}\x0a\x09\x09\x09\x09\x09¶\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}}{{$since}}{{end}}\x0a\x09\x09\x09\x09\x0a\x09\x09\x09\x09
      {{node_html\x20$\x20.Decl\x20true}}
      \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{{noteTitle\x20$marker\x20|\x20html}}s\x0a\x09\x09\x09\x0a\x09\x09\x09{{range\x20.}}\x0a\x09\x09\x09
    • ☞\x20{{comment_html\x20.Body}}
    • \x0a\x09\x09\x09{{end}}\x0a\x09\x09\x09
    \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{{$filename|filename|html}}:
    {{node_html\x20$\x20$ast\x20false}}
    \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\x09Subdirectories\x0a\x09{{end}}\x0a\x09\x0a\x09\x09\x0a\x09\x09\x09\x0a\x09\x09\x09\x09Name\x0a\x09\x09\x09\x09Synopsis\x0a\x09\x09\x09\x0a\x0a\x09\x09\x09{{if\x20not\x20((eq\x20$.Dirname\x20\"/src/cmd\")\x20$.DirFlat)}}\x0a\x09\x09\x09\x0a\x09\x09\x09\x09..\x0a\x09\x09\x09\x0a\x09\x09\x09{{end}}\x0a\x0a\x09\x09\x09{{range\x20.List}}\x0a\x09\x09\x09\x09\x0a\x09\x09\x09\x09{{if\x20$.DirFlat}}\x0a\x09\x09\x09\x09\x09{{if\x20.HasPkg}}\x0a\x09\x09\x09\x09\x09\x09\x0a\x09\x09\x09\x09\x09\x09\x09{{html\x20.Path}}\x0a\x09\x09\x09\x09\x09\x09\x0a\x09\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09{{else}}\x0a\x09\x09\x09\x09\x09\x0a\x09\x09\x09\x09\x09\x09{{html\x20.Name}}\x0a\x09\x09\x09\x09\x09\x0a\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09\x09\x0a\x09\x09\x09\x09\x09\x09{{html\x20.Synopsis}}\x0a\x09\x09\x09\x09\x09\x0a\x09\x09\x09\x09\x0a\x09\x09\x09{{end}}\x0a\x09\x09
    \x0a\x09\x0a{{end}}\x0a", "packageroot.html": "\x0a\x0a{{with\x20.PAst}}\x0a\x09{{range\x20$filename,\x20$ast\x20:=\x20.}}\x0a\x09\x09{{$filename|filename|html}}:
    {{node_html\x20$\x20$ast\x20false}}
    \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\x09Subdirectories\x0a\x09{{end}}\x0a\x09\x09\x0a\x09\x09\x09
    \x0a\x09\x09\x09\x09
    Standard\x20library
    \x0a\x09\x09\x09\x09{{if\x20hasThirdParty\x20.List\x20}}\x0a\x09\x09\x09\x09\x09
    Third\x20party
    \x0a\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09
    Other\x20packages
    \x0a\x09\x09\x09\x09
    Sub-repositories
    \x0a\x09\x09\x09\x09
    Community
    \x0a\x09\x09\x09
    \x0a\x09\x09\x0a\x0a\x09\x09\x0a\x09\x09\x09\x0a\x09\x09\x09\x09Standard\x20library\x20\xe2\x96\xb9\x0a\x09\x09\x09\x0a\x09\x09\x09\x0a\x09\x09\x09\x09Standard\x20library\x20\xe2\x96\xbe\x0a\x09\x09\x09\x09\x0a\x09\x09\x09\x09\x0a\x09\x09\x09\x09\x09\x0a\x09\x09\x09\x09\x09\x09\x0a\x09\x09\x09\x09\x09\x09\x09Name\x0a\x09\x09\x09\x09\x09\x09\x09Synopsis\x0a\x09\x09\x09\x09\x09\x09\x0a\x0a\x09\x09\x09\x09\x09\x09{{range\x20.List}}\x0a\x09\x09\x09\x09\x09\x09\x09\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\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09{{html\x20.Path}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\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\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09{{html\x20.Name}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x0a\x09\x09\x09\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09{{html\x20.Synopsis}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x0a\x09\x09\x09\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09\x09\x09\x09\x0a\x09\x09\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09\x09
    \x0a\x09\x09\x09\x09\x20\x0a\x09\x09\x09\x20\x0a\x09\x09\x20\x0a\x0a\x09{{if\x20hasThirdParty\x20.List\x20}}\x0a\x09\x09\x0a\x09\x09\x09\x0a\x09\x09\x09\x09Third\x20party\x20\xe2\x96\xb9\x0a\x09\x09\x09\x0a\x09\x09\x09\x0a\x09\x09\x09\x09Third\x20party\x20\xe2\x96\xbe\x0a\x09\x09\x09\x09\x0a\x09\x09\x09\x09\x09\x0a\x09\x09\x09\x09\x09\x09\x0a\x09\x09\x09\x09\x09\x09\x09Name\x0a\x09\x09\x09\x09\x09\x09\x09Synopsis\x0a\x09\x09\x09\x09\x09\x09\x0a\x0a\x09\x09\x09\x09\x09\x09{{range\x20.List}}\x0a\x09\x09\x09\x09\x09\x09\x09\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\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09{{html\x20.Path}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\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\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09{{html\x20.Name}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09\x0a\x09\x09\x09\x09\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x09{{html\x20.Synopsis}}\x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09\x0a\x09\x09\x09\x09\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09\x09\x09\x09\x0a\x09\x09\x09\x09\x09\x09{{end}}\x0a\x09\x09\x09\x09\x09
    \x0a\x09\x09\x09\x09\x20\x0a\x09\x09\x09\x20\x0a\x09\x09\x20\x0a\x09{{end}}\x0a\x0a\x09Other\x20packages\x0a\x09Sub-repositories\x0a\x09

    \x0a\x09These\x20packages\x20are\x20part\x20of\x20the\x20Go\x20Project\x20but\x20outside\x20the\x20main\x20Go\x20tree.\x0a\x09They\x20are\x20developed\x20under\x20looser\x20compatibility\x20requirements\x20than\x20the\x20Go\x20core.\x0a\x09Install\x20them\x20with\x20\"go\x20get\".\x0a\x09

    \x0a\x09
      \x0a\x09\x09
    • benchmarks\x20\xe2\x80\x94\x20benchmarks\x20to\x20measure\x20Go\x20as\x20it\x20is\x20developed.
    • \x0a\x09\x09
    • blog\x20\xe2\x80\x94\x20blog.golang.org's\x20implementation.
    • \x0a\x09\x09
    • build\x20\xe2\x80\x94\x20build.golang.org's\x20implementation.
    • \x0a\x09\x09
    • crypto\x20\xe2\x80\x94\x20additional\x20cryptography\x20packages.
    • \x0a\x09\x09
    • debug\x20\xe2\x80\x94\x20an\x20experimental\x20debugger\x20for\x20Go.
    • \x0a\x09\x09
    • image\x20\xe2\x80\x94\x20additional\x20imaging\x20packages.
    • \x0a\x09\x09
    • mobile\x20\xe2\x80\x94\x20experimental\x20support\x20for\x20Go\x20on\x20mobile\x20platforms.
    • \x0a\x09\x09
    • net\x20\xe2\x80\x94\x20additional\x20networking\x20packages.
    • \x0a\x09\x09
    • perf\x20\xe2\x80\x94\x20packages\x20and\x20tools\x20for\x20performance\x20measurement,\x20storage,\x20and\x20analysis.
    • \x0a\x09\x09
    • review\x20\xe2\x80\x94\x20a\x20tool\x20for\x20working\x20with\x20Gerrit\x20code\x20reviews.
    • \x0a\x09\x09
    • sync\x20\xe2\x80\x94\x20additional\x20concurrency\x20primitives.
    • \x0a\x09\x09
    • sys\x20\xe2\x80\x94\x20packages\x20for\x20making\x20system\x20calls.
    • \x0a\x09\x09
    • text\x20\xe2\x80\x94\x20packages\x20for\x20working\x20with\x20text.
    • \x0a\x09\x09
    • time\x20\xe2\x80\x94\x20additional\x20time\x20packages.
    • \x0a\x09\x09
    • tools\x20\xe2\x80\x94\x20godoc,\x20goimports,\x20gorename,\x20and\x20other\x20tools.
    • \x0a\x09\x09
    • tour\x20\xe2\x80\x94\x20tour.golang.org's\x20implementation.
    • \x0a\x09\x09
    • exp\x20\xe2\x80\x94\x20experimental\x20and\x20deprecated\x20packages\x20(handle\x20with\x20care;\x20may\x20change\x20without\x20warning).
    • \x0a\x09
    \x0a\x0a\x09Community\x0a\x09

    \x0a\x09These\x20services\x20can\x20help\x20you\x20find\x20Open\x20Source\x20packages\x20provided\x20by\x20the\x20community.\x0a\x09

    \x0a\x09
      \x0a\x09\x09
    • GoDoc\x20-\x20a\x20package\x20index\x20and\x20search\x20engine.
    • \x0a\x09\x09
    • Go\x20Search\x20-\x20a\x20code\x20search\x20engine.
    • \x0a\x09\x09
    • Projects\x20at\x20the\x20Go\x20Wiki\x20-\x20a\x20curated\x20list\x20of\x20Go\x20projects.
    • \x0a\x09
    \x0a{{end}}\x0a",