internal/godoc/redirect: remove unused package
Change-Id: I671c64ff191520395bb68430a51dab73cc9e0a30
Reviewed-on: https://go-review.googlesource.com/c/website/+/293424
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
diff --git a/internal/godoc/redirect/hash.go b/internal/godoc/redirect/hash.go
deleted file mode 100644
index d5a1e3e..0000000
--- a/internal/godoc/redirect/hash.go
+++ /dev/null
@@ -1,138 +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.
-
-// This file provides a compact encoding of
-// a map of Mercurial hashes to Git hashes.
-
-package redirect
-
-import (
- "encoding/binary"
- "fmt"
- "io"
- "os"
- "sort"
- "strconv"
- "strings"
-)
-
-// hashMap is a map of Mercurial hashes to Git hashes.
-type hashMap struct {
- file *os.File
- entries int
-}
-
-// newHashMap takes a file handle that contains a map of Mercurial to Git
-// hashes. The file should be a sequence of pairs of little-endian encoded
-// uint32s, representing a hgHash and a gitHash respectively.
-// The sequence must be sorted by hgHash.
-// The file must remain open for as long as the returned hashMap is used.
-func newHashMap(f *os.File) (*hashMap, error) {
- fi, err := f.Stat()
- if err != nil {
- return nil, err
- }
- return &hashMap{file: f, entries: int(fi.Size() / 8)}, nil
-}
-
-// Lookup finds an hgHash in the map that matches the given prefix, and returns
-// its corresponding gitHash. The prefix must be at least 8 characters long.
-func (m *hashMap) Lookup(s string) gitHash {
- if m == nil {
- return 0
- }
- hg, err := hgHashFromString(s)
- if err != nil {
- return 0
- }
- var git gitHash
- b := make([]byte, 8)
- sort.Search(m.entries, func(i int) bool {
- n, err := m.file.ReadAt(b, int64(i*8))
- if err != nil {
- panic(err)
- }
- if n != 8 {
- panic(io.ErrUnexpectedEOF)
- }
- v := hgHash(binary.LittleEndian.Uint32(b[:4]))
- if v == hg {
- git = gitHash(binary.LittleEndian.Uint32(b[4:]))
- }
- return v >= hg
- })
- return git
-}
-
-// hgHash represents the lower (leftmost) 32 bits of a Mercurial hash.
-type hgHash uint32
-
-func (h hgHash) String() string {
- return intToHash(int64(h))
-}
-
-func hgHashFromString(s string) (hgHash, error) {
- if len(s) < 8 {
- return 0, fmt.Errorf("string too small: len(s) = %d", len(s))
- }
- hash := s[:8]
- i, err := strconv.ParseInt(hash, 16, 64)
- if err != nil {
- return 0, err
- }
- return hgHash(i), nil
-}
-
-// gitHash represents the leftmost 28 bits of a Git hash in its upper 28 bits,
-// and it encodes hash's repository in the lower 4 bits.
-type gitHash uint32
-
-func (h gitHash) Hash() string {
- return intToHash(int64(h))[:7]
-}
-
-func (h gitHash) Repo() string {
- return repo(h & 0xF).String()
-}
-
-func intToHash(i int64) string {
- s := strconv.FormatInt(i, 16)
- if len(s) < 8 {
- s = strings.Repeat("0", 8-len(s)) + s
- }
- return s
-}
-
-// repo represents a Go Git repository.
-type repo byte
-
-const (
- repoGo repo = iota
- repoBlog
- repoCrypto
- repoExp
- repoImage
- repoMobile
- repoNet
- repoSys
- repoTalks
- repoText
- repoTools
-)
-
-func (r repo) String() string {
- return map[repo]string{
- repoGo: "go",
- repoBlog: "blog",
- repoCrypto: "crypto",
- repoExp: "exp",
- repoImage: "image",
- repoMobile: "mobile",
- repoNet: "net",
- repoSys: "sys",
- repoTalks: "talks",
- repoText: "text",
- repoTools: "tools",
- }[r]
-}
diff --git a/internal/godoc/redirect/redirect.go b/internal/godoc/redirect/redirect.go
deleted file mode 100644
index 059d264..0000000
--- a/internal/godoc/redirect/redirect.go
+++ /dev/null
@@ -1,324 +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 redirect provides hooks to register HTTP handlers that redirect old
-// godoc paths to their new equivalents and assist in accessing the issue
-// tracker, wiki, code review system, etc.
-package redirect // import "golang.org/x/website/internal/godoc/redirect"
-
-import (
- "context"
- "fmt"
- "html/template"
- "net/http"
- "os"
- "regexp"
- "strconv"
- "strings"
- "sync"
- "time"
-
- "golang.org/x/net/context/ctxhttp"
-)
-
-// Register registers HTTP handlers that redirect old godoc paths to their new
-// equivalents and assist in accessing the issue tracker, wiki, code review
-// system, etc. If mux is nil it uses http.DefaultServeMux.
-func Register(mux *http.ServeMux) {
- if mux == nil {
- mux = http.DefaultServeMux
- }
- handlePathRedirects(mux, pkgRedirects, "/pkg/")
- handlePathRedirects(mux, cmdRedirects, "/cmd/")
- for prefix, redirect := range prefixHelpers {
- p := "/" + prefix + "/"
- mux.Handle(p, PrefixHandler(p, redirect))
- }
- for path, redirect := range redirects {
- mux.Handle(path, Handler(redirect))
- }
- // NB: /src/pkg (sans trailing slash) is the index of packages.
- mux.HandleFunc("/src/pkg/", srcPkgHandler)
- mux.HandleFunc("/cl/", clHandler)
- mux.HandleFunc("/change/", changeHandler)
- mux.HandleFunc("/design/", designHandler)
-}
-
-func handlePathRedirects(mux *http.ServeMux, redirects map[string]string, prefix string) {
- for source, target := range redirects {
- h := Handler(prefix + target + "/")
- p := prefix + source
- mux.Handle(p, h)
- mux.Handle(p+"/", h)
- }
-}
-
-// Packages that were renamed between r60 and go1.
-var pkgRedirects = map[string]string{
- "asn1": "encoding/asn1",
- "big": "math/big",
- "cmath": "math/cmplx",
- "csv": "encoding/csv",
- "exec": "os/exec",
- "exp/template/html": "html/template",
- "gob": "encoding/gob",
- "http": "net/http",
- "http/cgi": "net/http/cgi",
- "http/fcgi": "net/http/fcgi",
- "http/httptest": "net/http/httptest",
- "http/pprof": "net/http/pprof",
- "json": "encoding/json",
- "mail": "net/mail",
- "rand": "math/rand",
- "rpc": "net/rpc",
- "rpc/jsonrpc": "net/rpc/jsonrpc",
- "scanner": "text/scanner",
- "smtp": "net/smtp",
- "tabwriter": "text/tabwriter",
- "template": "text/template",
- "template/parse": "text/template/parse",
- "url": "net/url",
- "utf16": "unicode/utf16",
- "utf8": "unicode/utf8",
- "xml": "encoding/xml",
-}
-
-// Commands that were renamed between r60 and go1.
-var cmdRedirects = map[string]string{
- "gofix": "fix",
- "goinstall": "go",
- "gopack": "pack",
- "gotest": "go",
- "govet": "vet",
- "goyacc": "yacc",
-}
-
-var redirects = map[string]string{
- "/blog": "/blog/",
- "/build": "http://build.golang.org",
- "/change": "https://go.googlesource.com/go",
- "/cl": "https://go-review.googlesource.com",
- "/cmd/godoc/": "https://pkg.go.dev/golang.org/x/tools/cmd/godoc",
- "/issue": "https://github.com/golang/go/issues",
- "/issue/new": "https://github.com/golang/go/issues/new",
- "/issues": "https://github.com/golang/go/issues",
- "/issues/new": "https://github.com/golang/go/issues/new",
- "/play": "http://play.golang.org",
- "/design": "https://go.googlesource.com/proposal/+/master/design",
-
- // In Go 1.2 the references page is part of /doc/.
- "/ref": "/doc/#references",
- // This next rule clobbers /ref/spec and /ref/mem.
- // TODO(adg): figure out what to do here, if anything.
- // "/ref/": "/doc/#references",
-
- // Be nice to people who are looking in the wrong place.
- "/doc/mem": "/ref/mem",
- "/doc/spec": "/ref/spec",
-
- "/talks": "http://talks.golang.org",
- "/tour": "http://tour.golang.org",
- "/wiki": "https://github.com/golang/go/wiki",
-
- "/doc/articles/c_go_cgo.html": "/blog/c-go-cgo",
- "/doc/articles/concurrency_patterns.html": "/blog/go-concurrency-patterns-timing-out-and",
- "/doc/articles/defer_panic_recover.html": "/blog/defer-panic-and-recover",
- "/doc/articles/error_handling.html": "/blog/error-handling-and-go",
- "/doc/articles/gobs_of_data.html": "/blog/gobs-of-data",
- "/doc/articles/godoc_documenting_go_code.html": "/blog/godoc-documenting-go-code",
- "/doc/articles/gos_declaration_syntax.html": "/blog/gos-declaration-syntax",
- "/doc/articles/image_draw.html": "/blog/go-imagedraw-package",
- "/doc/articles/image_package.html": "/blog/go-image-package",
- "/doc/articles/json_and_go.html": "/blog/json-and-go",
- "/doc/articles/json_rpc_tale_of_interfaces.html": "/blog/json-rpc-tale-of-interfaces",
- "/doc/articles/laws_of_reflection.html": "/blog/laws-of-reflection",
- "/doc/articles/slices_usage_and_internals.html": "/blog/go-slices-usage-and-internals",
- "/doc/go_for_cpp_programmers.html": "/wiki/GoForCPPProgrammers",
- "/doc/go_tutorial.html": "http://tour.golang.org/",
-}
-
-var prefixHelpers = map[string]string{
- "issue": "https://github.com/golang/go/issues/",
- "issues": "https://github.com/golang/go/issues/",
- "play": "http://play.golang.org/",
- "talks": "http://talks.golang.org/",
- "wiki": "https://github.com/golang/go/wiki/",
-}
-
-func Handler(target string) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- url := target
- if qs := r.URL.RawQuery; qs != "" {
- url += "?" + qs
- }
- http.Redirect(w, r, url, http.StatusMovedPermanently)
- })
-}
-
-var validID = regexp.MustCompile(`^[A-Za-z0-9-]*/?$`)
-
-func PrefixHandler(prefix, baseURL string) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if p := r.URL.Path; p == prefix {
- // redirect /prefix/ to /prefix
- http.Redirect(w, r, p[:len(p)-1], http.StatusFound)
- return
- }
- id := r.URL.Path[len(prefix):]
- if !validID.MatchString(id) {
- http.Error(w, "Not found", http.StatusNotFound)
- return
- }
- target := baseURL + id
- http.Redirect(w, r, target, http.StatusFound)
- })
-}
-
-// Redirect requests from the old "/src/pkg/foo" to the new "/src/foo".
-// See http://golang.org/s/go14nopkg
-func srcPkgHandler(w http.ResponseWriter, r *http.Request) {
- r.URL.Path = "/src/" + r.URL.Path[len("/src/pkg/"):]
- http.Redirect(w, r, r.URL.String(), http.StatusMovedPermanently)
-}
-
-func clHandler(w http.ResponseWriter, r *http.Request) {
- const prefix = "/cl/"
- if p := r.URL.Path; p == prefix {
- // redirect /prefix/ to /prefix
- http.Redirect(w, r, p[:len(p)-1], http.StatusFound)
- return
- }
- id := r.URL.Path[len(prefix):]
- // support /cl/152700045/, which is used in commit 0edafefc36.
- id = strings.TrimSuffix(id, "/")
- if !validID.MatchString(id) {
- http.Error(w, "Not found", http.StatusNotFound)
- return
- }
- target := ""
-
- if n, err := strconv.Atoi(id); err == nil && isRietveldCL(n) {
- // Issue 28836: if this Rietveld CL happens to
- // also be a Gerrit CL, render a disambiguation HTML
- // page with two links instead. We need to make a
- // Gerrit API call to figure that out, but we cache
- // known Gerrit CLs so it's done at most once per CL.
- if ok, err := isGerritCL(r.Context(), n); err == nil && ok {
- w.Header().Set("Content-Type", "text/html; charset=utf-8")
- clDisambiguationHTML.Execute(w, n)
- return
- }
-
- target = "https://codereview.appspot.com/" + id
- } else {
- target = "https://go-review.googlesource.com/" + id
- }
- http.Redirect(w, r, target, http.StatusFound)
-}
-
-var clDisambiguationHTML = template.Must(template.New("").Parse(`<!DOCTYPE html>
-<html lang="en">
- <head>
- <title>Go CL {{.}} Disambiguation</title>
- <meta name="viewport" content="width=device-width">
- </head>
- <body>
- CL number {{.}} exists in both Gerrit (the current code review system)
- and Rietveld (the previous code review system). Please make a choice:
-
- <ul>
- <li><a href="https://go-review.googlesource.com/{{.}}">Gerrit CL {{.}}</a></li>
- <li><a href="https://codereview.appspot.com/{{.}}">Rietveld CL {{.}}</a></li>
- </ul>
- </body>
-</html>`))
-
-// isGerritCL reports whether a Gerrit CL with the specified numeric change ID (e.g., "4247")
-// is known to exist by querying the Gerrit API at https://go-review.googlesource.com.
-// isGerritCL uses gerritCLCache as a cache of Gerrit CL IDs that exist.
-func isGerritCL(ctx context.Context, id int) (bool, error) {
- // Check cache first.
- gerritCLCache.Lock()
- ok := gerritCLCache.exist[id]
- gerritCLCache.Unlock()
- if ok {
- return true, nil
- }
-
- // Query the Gerrit API Get Change endpoint, as documented at
- // https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#get-change.
- ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
- defer cancel()
- resp, err := ctxhttp.Get(ctx, nil, fmt.Sprintf("https://go-review.googlesource.com/changes/%d", id))
- if err != nil {
- return false, err
- }
- resp.Body.Close()
- switch resp.StatusCode {
- case http.StatusOK:
- // A Gerrit CL with this ID exists. Add it to cache.
- gerritCLCache.Lock()
- gerritCLCache.exist[id] = true
- gerritCLCache.Unlock()
- return true, nil
- case http.StatusNotFound:
- // A Gerrit CL with this ID doesn't exist. It may get created in the future.
- return false, nil
- default:
- return false, fmt.Errorf("unexpected status code: %v", resp.Status)
- }
-}
-
-var gerritCLCache = struct {
- sync.Mutex
- exist map[int]bool // exist is a set of Gerrit CL IDs that are known to exist.
-}{exist: make(map[int]bool)}
-
-var changeMap *hashMap
-
-// LoadChangeMap loads the specified map of Mercurial to Git revisions,
-// which is used by the /change/ handler to intelligently map old hg
-// revisions to their new git equivalents.
-// It should be called before calling Register.
-// The file should remain open as long as the process is running.
-// See the implementation of this package for details.
-func LoadChangeMap(filename string) error {
- f, err := os.Open(filename)
- if err != nil {
- return err
- }
- m, err := newHashMap(f)
- if err != nil {
- return err
- }
- changeMap = m
- return nil
-}
-
-func changeHandler(w http.ResponseWriter, r *http.Request) {
- const prefix = "/change/"
- if p := r.URL.Path; p == prefix {
- // redirect /prefix/ to /prefix
- http.Redirect(w, r, p[:len(p)-1], http.StatusFound)
- return
- }
- hash := r.URL.Path[len(prefix):]
- target := "https://go.googlesource.com/go/+/" + hash
- if git := changeMap.Lookup(hash); git > 0 {
- target = fmt.Sprintf("https://go.googlesource.com/%v/+/%v", git.Repo(), git.Hash())
- }
- http.Redirect(w, r, target, http.StatusFound)
-}
-
-func designHandler(w http.ResponseWriter, r *http.Request) {
- const prefix = "/design/"
- if p := r.URL.Path; p == prefix {
- // redirect /prefix/ to /prefix
- http.Redirect(w, r, p[:len(p)-1], http.StatusFound)
- return
- }
- name := r.URL.Path[len(prefix):]
- target := "https://go.googlesource.com/proposal/+/master/design/" + name + ".md"
- http.Redirect(w, r, target, http.StatusFound)
-}
diff --git a/internal/godoc/redirect/redirect_test.go b/internal/godoc/redirect/redirect_test.go
deleted file mode 100644
index 756c0d0..0000000
--- a/internal/godoc/redirect/redirect_test.go
+++ /dev/null
@@ -1,113 +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 redirect
-
-import (
- "net/http"
- "net/http/httptest"
- "testing"
-)
-
-type redirectResult struct {
- status int
- path string
-}
-
-func errorResult(status int) redirectResult {
- return redirectResult{status, ""}
-}
-
-func TestRedirects(t *testing.T) {
- var tests = map[string]redirectResult{
- "/build": {301, "http://build.golang.org"},
- "/ref": {301, "/doc/#references"},
- "/doc/mem": {301, "/ref/mem"},
- "/doc/spec": {301, "/ref/spec"},
- "/tour": {301, "http://tour.golang.org"},
- "/foo": errorResult(404),
-
- "/pkg/asn1": {301, "/pkg/encoding/asn1/"},
- "/pkg/template/parse": {301, "/pkg/text/template/parse/"},
-
- "/src/pkg/foo": {301, "/src/foo"},
-
- "/cmd/gofix": {301, "/cmd/fix/"},
-
- // git commits (/change)
- // TODO: mercurial tags and LoadChangeMap.
- "/change": {301, "https://go.googlesource.com/go"},
- "/change/a": {302, "https://go.googlesource.com/go/+/a"},
-
- "/issue": {301, "https://github.com/golang/go/issues"},
- "/issue?": {301, "https://github.com/golang/go/issues"},
- "/issue/1": {302, "https://github.com/golang/go/issues/1"},
- "/issue/new": {301, "https://github.com/golang/go/issues/new"},
- "/issue/new?a=b&c=d%20&e=f": {301, "https://github.com/golang/go/issues/new?a=b&c=d%20&e=f"},
- "/issues": {301, "https://github.com/golang/go/issues"},
- "/issues/1": {302, "https://github.com/golang/go/issues/1"},
- "/issues/new": {301, "https://github.com/golang/go/issues/new"},
- "/issues/1/2/3": errorResult(404),
-
- "/wiki/foo": {302, "https://github.com/golang/go/wiki/foo"},
- "/wiki/foo/": {302, "https://github.com/golang/go/wiki/foo/"},
-
- "/design": {301, "https://go.googlesource.com/proposal/+/master/design"},
- "/design/": {302, "/design"},
- "/design/123-foo": {302, "https://go.googlesource.com/proposal/+/master/design/123-foo.md"},
- "/design/text/123-foo": {302, "https://go.googlesource.com/proposal/+/master/design/text/123-foo.md"},
-
- "/cl/1": {302, "https://go-review.googlesource.com/1"},
- "/cl/1/": {302, "https://go-review.googlesource.com/1"},
- "/cl/267120043": {302, "https://codereview.appspot.com/267120043"},
- "/cl/267120043/": {302, "https://codereview.appspot.com/267120043"},
-
- // Verify that we're using the Rietveld CL table:
- "/cl/152046": {302, "https://codereview.appspot.com/152046"},
- "/cl/152047": {302, "https://go-review.googlesource.com/152047"},
- "/cl/152048": {302, "https://codereview.appspot.com/152048"},
-
- // And verify we're using the "bigEnoughAssumeRietveld" value:
- "/cl/299999": {302, "https://go-review.googlesource.com/299999"},
- "/cl/300000": {302, "https://codereview.appspot.com/300000"},
- }
-
- mux := http.NewServeMux()
- Register(mux)
- ts := httptest.NewServer(mux)
- defer ts.Close()
-
- for path, want := range tests {
- if want.path != "" && want.path[0] == '/' {
- // All redirects are absolute.
- want.path = ts.URL + want.path
- }
-
- req, err := http.NewRequest("GET", ts.URL+path, nil)
- if err != nil {
- t.Errorf("(path: %q) unexpected error: %v", path, err)
- continue
- }
-
- resp, err := http.DefaultTransport.RoundTrip(req)
- if err != nil {
- t.Errorf("(path: %q) unexpected error: %v", path, err)
- continue
- }
-
- if resp.StatusCode != want.status {
- t.Errorf("(path: %q) got status %d, want %d", path, resp.StatusCode, want.status)
- }
-
- if want.status != 301 && want.status != 302 {
- // Not a redirect. Just check status.
- continue
- }
-
- out, _ := resp.Location()
- if got := out.String(); got != want.path {
- t.Errorf("(path: %q) got %s, want %s", path, got, want.path)
- }
- }
-}
diff --git a/internal/godoc/redirect/rietveld.go b/internal/godoc/redirect/rietveld.go
deleted file mode 100644
index 81b1094..0000000
--- a/internal/godoc/redirect/rietveld.go
+++ /dev/null
@@ -1,1093 +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 redirect
-
-// bigEnoughAssumeRietveld is the value where CLs equal or great are
-// assumed to be on Rietveld. By including this threshold we shrink
-// the size of the table below. When Go amasses 150,000 more CLs, we'll
-// need to bump this number and regenerate the list below.
-const bigEnoughAssumeRietveld = 300000
-
-// isRietveldCL reports whether cl was a Rietveld CL number.
-func isRietveldCL(cl int) bool {
- return cl >= bigEnoughAssumeRietveld || lowRietveldCL[cl]
-}
-
-// lowRietveldCLs are the old CL numbers assigned by Rietveld code
-// review system as used by Go prior to Gerrit which are less than
-// bigEnoughAssumeRietveld.
-//
-// This list of numbers is registered with the /cl/NNNN redirect
-// handler to disambiguate which code review system a particular
-// number corresponds to. In some rare cases there may be duplicates,
-// in which case we might render an HTML choice for the user.
-//
-// To re-generate this list, run:
-//
-// $ cd $GOROOT
-// $ git log 7d7c6a9..94151eb | grep "^ https://golang.org/cl/" | perl -ne 's,^\s+https://golang.org/cl/(\d+).*$,$1,; chomp; print "$_: true,\n" if $_ < 300000' | sort -n | uniq
-//
-// Note that we ignore the x/* repos because we didn't start using
-// "subrepos" until the Rietveld CLs numbers were already 4,000,000+,
-// well above bigEnoughAssumeRietveld.
-var lowRietveldCL = map[int]bool{
- 152046: true,
- 152048: true,
- 152049: true,
- 152050: true,
- 152051: true,
- 152052: true,
- 152055: true,
- 152056: true,
- 152057: true,
- 152072: true,
- 152073: true,
- 152075: true,
- 152076: true,
- 152077: true,
- 152078: true,
- 152079: true,
- 152080: true,
- 152082: true,
- 152084: true,
- 152085: true,
- 152086: true,
- 152088: true,
- 152089: true,
- 152091: true,
- 152098: true,
- 152101: true,
- 152102: true,
- 152105: true,
- 152106: true,
- 152107: true,
- 152108: true,
- 152109: true,
- 152110: true,
- 152114: true,
- 152117: true,
- 152118: true,
- 152120: true,
- 152123: true,
- 152124: true,
- 152128: true,
- 152130: true,
- 152131: true,
- 152138: true,
- 152141: true,
- 152142: true,
- 153048: true,
- 153049: true,
- 153050: true,
- 153051: true,
- 153055: true,
- 153056: true,
- 153057: true,
- 154043: true,
- 154044: true,
- 154045: true,
- 154049: true,
- 154055: true,
- 154057: true,
- 154058: true,
- 154059: true,
- 154061: true,
- 154064: true,
- 154065: true,
- 154067: true,
- 154068: true,
- 154069: true,
- 154071: true,
- 154072: true,
- 154073: true,
- 154076: true,
- 154079: true,
- 154096: true,
- 154097: true,
- 154099: true,
- 154100: true,
- 154101: true,
- 154102: true,
- 154108: true,
- 154118: true,
- 154121: true,
- 154122: true,
- 154123: true,
- 154125: true,
- 154126: true,
- 154128: true,
- 154136: true,
- 154138: true,
- 154139: true,
- 154140: true,
- 154141: true,
- 154142: true,
- 154143: true,
- 154144: true,
- 154145: true,
- 154146: true,
- 154152: true,
- 154153: true,
- 154156: true,
- 154159: true,
- 154161: true,
- 154166: true,
- 154167: true,
- 154169: true,
- 154171: true,
- 154172: true,
- 154173: true,
- 154174: true,
- 154175: true,
- 154176: true,
- 154177: true,
- 154178: true,
- 154179: true,
- 154180: true,
- 155041: true,
- 155042: true,
- 155045: true,
- 155047: true,
- 155048: true,
- 155049: true,
- 155050: true,
- 155054: true,
- 155055: true,
- 155056: true,
- 155057: true,
- 155058: true,
- 155059: true,
- 155061: true,
- 155062: true,
- 155063: true,
- 155065: true,
- 155067: true,
- 155069: true,
- 155072: true,
- 155074: true,
- 155075: true,
- 155077: true,
- 155078: true,
- 155079: true,
- 156041: true,
- 156044: true,
- 156045: true,
- 156046: true,
- 156047: true,
- 156051: true,
- 156052: true,
- 156054: true,
- 156055: true,
- 156056: true,
- 156058: true,
- 156059: true,
- 156060: true,
- 156061: true,
- 156062: true,
- 156063: true,
- 156066: true,
- 156067: true,
- 156070: true,
- 156071: true,
- 156073: true,
- 156075: true,
- 156077: true,
- 156079: true,
- 156080: true,
- 156081: true,
- 156083: true,
- 156084: true,
- 156085: true,
- 156086: true,
- 156089: true,
- 156091: true,
- 156092: true,
- 156093: true,
- 156094: true,
- 156097: true,
- 156099: true,
- 156100: true,
- 156102: true,
- 156103: true,
- 156104: true,
- 156106: true,
- 156107: true,
- 156108: true,
- 156109: true,
- 156110: true,
- 156113: true,
- 156115: true,
- 156116: true,
- 157041: true,
- 157042: true,
- 157043: true,
- 157044: true,
- 157046: true,
- 157053: true,
- 157055: true,
- 157056: true,
- 157058: true,
- 157060: true,
- 157061: true,
- 157062: true,
- 157065: true,
- 157066: true,
- 157067: true,
- 157068: true,
- 157069: true,
- 157071: true,
- 157072: true,
- 157073: true,
- 157074: true,
- 157075: true,
- 157076: true,
- 157077: true,
- 157082: true,
- 157084: true,
- 157085: true,
- 157087: true,
- 157088: true,
- 157091: true,
- 157095: true,
- 157096: true,
- 157099: true,
- 157100: true,
- 157101: true,
- 157102: true,
- 157103: true,
- 157104: true,
- 157106: true,
- 157110: true,
- 157111: true,
- 157112: true,
- 157114: true,
- 157116: true,
- 157119: true,
- 157140: true,
- 157142: true,
- 157143: true,
- 157144: true,
- 157146: true,
- 157147: true,
- 157149: true,
- 157151: true,
- 157152: true,
- 157153: true,
- 157154: true,
- 157156: true,
- 157157: true,
- 157158: true,
- 157159: true,
- 157160: true,
- 157162: true,
- 157166: true,
- 157167: true,
- 157168: true,
- 157170: true,
- 158041: true,
- 159044: true,
- 159049: true,
- 159050: true,
- 159051: true,
- 160043: true,
- 160044: true,
- 160045: true,
- 160046: true,
- 160047: true,
- 160054: true,
- 160056: true,
- 160057: true,
- 160059: true,
- 160060: true,
- 160061: true,
- 160064: true,
- 160065: true,
- 160069: true,
- 160070: true,
- 161049: true,
- 161050: true,
- 161056: true,
- 161058: true,
- 161060: true,
- 161061: true,
- 161069: true,
- 161070: true,
- 161073: true,
- 161075: true,
- 162041: true,
- 162044: true,
- 162046: true,
- 162053: true,
- 162054: true,
- 162055: true,
- 162056: true,
- 162057: true,
- 162058: true,
- 162059: true,
- 162061: true,
- 162062: true,
- 163042: true,
- 163044: true,
- 163049: true,
- 163050: true,
- 163051: true,
- 163052: true,
- 163053: true,
- 163055: true,
- 163058: true,
- 163061: true,
- 163062: true,
- 163064: true,
- 163067: true,
- 163068: true,
- 163069: true,
- 163070: true,
- 163071: true,
- 163072: true,
- 163082: true,
- 163083: true,
- 163085: true,
- 163088: true,
- 163091: true,
- 163092: true,
- 163097: true,
- 163098: true,
- 164043: true,
- 164047: true,
- 164049: true,
- 164052: true,
- 164053: true,
- 164056: true,
- 164059: true,
- 164060: true,
- 164062: true,
- 164068: true,
- 164069: true,
- 164071: true,
- 164073: true,
- 164074: true,
- 164075: true,
- 164078: true,
- 164079: true,
- 164081: true,
- 164082: true,
- 164083: true,
- 164085: true,
- 164086: true,
- 164088: true,
- 164090: true,
- 164091: true,
- 164092: true,
- 164093: true,
- 164094: true,
- 164095: true,
- 165042: true,
- 165044: true,
- 165045: true,
- 165048: true,
- 165049: true,
- 165050: true,
- 165051: true,
- 165055: true,
- 165057: true,
- 165058: true,
- 165059: true,
- 165061: true,
- 165062: true,
- 165063: true,
- 165064: true,
- 165065: true,
- 165068: true,
- 165070: true,
- 165076: true,
- 165078: true,
- 165080: true,
- 165083: true,
- 165086: true,
- 165097: true,
- 165100: true,
- 165101: true,
- 166041: true,
- 166043: true,
- 166044: true,
- 166047: true,
- 166049: true,
- 166052: true,
- 166053: true,
- 166055: true,
- 166058: true,
- 166059: true,
- 166060: true,
- 166064: true,
- 166066: true,
- 166067: true,
- 166068: true,
- 166070: true,
- 166071: true,
- 166072: true,
- 166073: true,
- 166074: true,
- 166076: true,
- 166077: true,
- 166078: true,
- 166080: true,
- 167043: true,
- 167044: true,
- 167047: true,
- 167050: true,
- 167055: true,
- 167057: true,
- 167058: true,
- 168041: true,
- 168045: true,
- 170042: true,
- 170043: true,
- 170044: true,
- 170046: true,
- 170047: true,
- 170048: true,
- 170049: true,
- 171044: true,
- 171046: true,
- 171047: true,
- 171048: true,
- 171051: true,
- 172041: true,
- 172042: true,
- 172043: true,
- 172045: true,
- 172049: true,
- 173041: true,
- 173044: true,
- 173045: true,
- 174042: true,
- 174047: true,
- 174048: true,
- 174050: true,
- 174051: true,
- 174052: true,
- 174053: true,
- 174063: true,
- 174064: true,
- 174072: true,
- 174076: true,
- 174077: true,
- 174078: true,
- 174082: true,
- 174083: true,
- 174087: true,
- 175045: true,
- 175046: true,
- 175047: true,
- 175048: true,
- 176056: true,
- 176057: true,
- 176058: true,
- 176061: true,
- 176062: true,
- 176063: true,
- 176064: true,
- 176066: true,
- 176067: true,
- 176070: true,
- 176071: true,
- 176076: true,
- 178043: true,
- 178044: true,
- 178046: true,
- 178048: true,
- 179047: true,
- 179055: true,
- 179061: true,
- 179062: true,
- 179063: true,
- 179067: true,
- 179069: true,
- 179070: true,
- 179072: true,
- 179079: true,
- 179088: true,
- 179095: true,
- 179096: true,
- 179097: true,
- 179099: true,
- 179105: true,
- 179106: true,
- 179108: true,
- 179118: true,
- 179120: true,
- 179125: true,
- 179126: true,
- 179128: true,
- 179129: true,
- 179130: true,
- 180044: true,
- 180045: true,
- 180046: true,
- 180047: true,
- 180048: true,
- 180049: true,
- 180050: true,
- 180052: true,
- 180053: true,
- 180054: true,
- 180055: true,
- 180056: true,
- 180057: true,
- 180059: true,
- 180061: true,
- 180064: true,
- 180065: true,
- 180068: true,
- 180069: true,
- 180070: true,
- 180074: true,
- 180075: true,
- 180081: true,
- 180082: true,
- 180085: true,
- 180092: true,
- 180099: true,
- 180105: true,
- 180108: true,
- 180112: true,
- 180118: true,
- 181041: true,
- 181043: true,
- 181044: true,
- 181045: true,
- 181049: true,
- 181050: true,
- 181055: true,
- 181057: true,
- 181058: true,
- 181059: true,
- 181063: true,
- 181071: true,
- 181073: true,
- 181075: true,
- 181077: true,
- 181080: true,
- 181083: true,
- 181084: true,
- 181085: true,
- 181086: true,
- 181087: true,
- 181089: true,
- 181097: true,
- 181099: true,
- 181102: true,
- 181111: true,
- 181130: true,
- 181135: true,
- 181137: true,
- 181138: true,
- 181139: true,
- 181151: true,
- 181152: true,
- 181153: true,
- 181155: true,
- 181156: true,
- 181157: true,
- 181158: true,
- 181160: true,
- 181161: true,
- 181163: true,
- 181164: true,
- 181171: true,
- 181179: true,
- 181183: true,
- 181184: true,
- 181186: true,
- 182041: true,
- 182043: true,
- 182044: true,
- 183042: true,
- 183043: true,
- 183044: true,
- 183047: true,
- 183049: true,
- 183065: true,
- 183066: true,
- 183073: true,
- 183074: true,
- 183075: true,
- 183083: true,
- 183084: true,
- 183087: true,
- 183088: true,
- 183090: true,
- 183095: true,
- 183104: true,
- 183107: true,
- 183109: true,
- 183111: true,
- 183112: true,
- 183113: true,
- 183116: true,
- 183123: true,
- 183124: true,
- 183125: true,
- 183126: true,
- 183132: true,
- 183133: true,
- 183135: true,
- 183136: true,
- 183137: true,
- 183138: true,
- 183139: true,
- 183140: true,
- 183141: true,
- 183142: true,
- 183153: true,
- 183155: true,
- 183156: true,
- 183157: true,
- 183160: true,
- 184043: true,
- 184055: true,
- 184058: true,
- 184059: true,
- 184068: true,
- 184069: true,
- 184079: true,
- 184080: true,
- 184081: true,
- 185043: true,
- 185045: true,
- 186042: true,
- 186043: true,
- 186073: true,
- 186076: true,
- 186077: true,
- 186078: true,
- 186079: true,
- 186081: true,
- 186095: true,
- 186108: true,
- 186113: true,
- 186115: true,
- 186116: true,
- 186118: true,
- 186119: true,
- 186132: true,
- 186137: true,
- 186138: true,
- 186139: true,
- 186143: true,
- 186144: true,
- 186145: true,
- 186146: true,
- 186147: true,
- 186148: true,
- 186159: true,
- 186160: true,
- 186161: true,
- 186165: true,
- 186169: true,
- 186173: true,
- 186180: true,
- 186210: true,
- 186211: true,
- 186212: true,
- 186213: true,
- 186214: true,
- 186215: true,
- 186216: true,
- 186228: true,
- 186229: true,
- 186230: true,
- 186232: true,
- 186234: true,
- 186255: true,
- 186263: true,
- 186276: true,
- 186279: true,
- 186282: true,
- 186283: true,
- 188043: true,
- 189042: true,
- 189057: true,
- 189059: true,
- 189062: true,
- 189078: true,
- 189080: true,
- 189083: true,
- 189088: true,
- 189093: true,
- 189095: true,
- 189096: true,
- 189098: true,
- 189100: true,
- 190041: true,
- 190042: true,
- 190043: true,
- 190044: true,
- 190059: true,
- 190062: true,
- 190068: true,
- 190074: true,
- 190076: true,
- 190077: true,
- 190079: true,
- 190085: true,
- 190088: true,
- 190103: true,
- 190104: true,
- 193055: true,
- 193066: true,
- 193067: true,
- 193070: true,
- 193075: true,
- 193079: true,
- 193080: true,
- 193081: true,
- 193091: true,
- 193092: true,
- 193095: true,
- 193101: true,
- 193104: true,
- 194043: true,
- 194045: true,
- 194046: true,
- 194050: true,
- 194051: true,
- 194052: true,
- 194053: true,
- 194064: true,
- 194066: true,
- 194069: true,
- 194071: true,
- 194072: true,
- 194073: true,
- 194074: true,
- 194076: true,
- 194077: true,
- 194078: true,
- 194082: true,
- 194084: true,
- 194085: true,
- 194090: true,
- 194091: true,
- 194092: true,
- 194094: true,
- 194097: true,
- 194098: true,
- 194099: true,
- 194100: true,
- 194114: true,
- 194116: true,
- 194118: true,
- 194119: true,
- 194120: true,
- 194121: true,
- 194122: true,
- 194126: true,
- 194129: true,
- 194131: true,
- 194132: true,
- 194133: true,
- 194134: true,
- 194146: true,
- 194151: true,
- 194156: true,
- 194157: true,
- 194159: true,
- 194161: true,
- 194165: true,
- 195041: true,
- 195044: true,
- 195050: true,
- 195051: true,
- 195052: true,
- 195068: true,
- 195075: true,
- 195076: true,
- 195079: true,
- 195080: true,
- 195081: true,
- 196042: true,
- 196044: true,
- 196050: true,
- 196051: true,
- 196055: true,
- 196056: true,
- 196061: true,
- 196063: true,
- 196065: true,
- 196070: true,
- 196071: true,
- 196075: true,
- 196077: true,
- 196079: true,
- 196087: true,
- 196088: true,
- 196090: true,
- 196091: true,
- 197041: true,
- 197042: true,
- 197043: true,
- 197044: true,
- 198044: true,
- 198045: true,
- 198046: true,
- 198048: true,
- 198049: true,
- 198050: true,
- 198053: true,
- 198057: true,
- 198058: true,
- 198066: true,
- 198071: true,
- 198074: true,
- 198081: true,
- 198084: true,
- 198085: true,
- 198102: true,
- 199042: true,
- 199044: true,
- 199045: true,
- 199046: true,
- 199047: true,
- 199052: true,
- 199054: true,
- 199057: true,
- 199066: true,
- 199070: true,
- 199082: true,
- 199091: true,
- 199094: true,
- 199096: true,
- 201041: true,
- 201042: true,
- 201043: true,
- 201047: true,
- 201048: true,
- 201049: true,
- 201058: true,
- 201061: true,
- 201064: true,
- 201065: true,
- 201068: true,
- 202042: true,
- 202043: true,
- 202044: true,
- 202051: true,
- 202054: true,
- 202055: true,
- 203043: true,
- 203050: true,
- 203051: true,
- 203053: true,
- 203060: true,
- 203062: true,
- 204042: true,
- 204044: true,
- 204048: true,
- 204052: true,
- 204053: true,
- 204061: true,
- 204062: true,
- 204064: true,
- 204065: true,
- 204067: true,
- 204068: true,
- 204069: true,
- 205042: true,
- 205044: true,
- 206043: true,
- 206044: true,
- 206047: true,
- 206050: true,
- 206051: true,
- 206052: true,
- 206053: true,
- 206054: true,
- 206055: true,
- 206058: true,
- 206059: true,
- 206060: true,
- 206067: true,
- 206069: true,
- 206077: true,
- 206078: true,
- 206079: true,
- 206084: true,
- 206089: true,
- 206101: true,
- 206107: true,
- 206109: true,
- 207043: true,
- 207044: true,
- 207049: true,
- 207050: true,
- 207051: true,
- 207052: true,
- 207053: true,
- 207054: true,
- 207055: true,
- 207061: true,
- 207062: true,
- 207069: true,
- 207071: true,
- 207085: true,
- 207086: true,
- 207087: true,
- 207088: true,
- 207095: true,
- 207096: true,
- 207102: true,
- 207103: true,
- 207106: true,
- 207108: true,
- 207110: true,
- 207111: true,
- 207112: true,
- 209041: true,
- 209042: true,
- 209043: true,
- 209044: true,
- 210042: true,
- 210043: true,
- 210044: true,
- 210047: true,
- 211041: true,
- 212041: true,
- 212045: true,
- 212046: true,
- 212047: true,
- 213041: true,
- 213042: true,
- 214042: true,
- 214046: true,
- 214049: true,
- 214050: true,
- 215042: true,
- 215048: true,
- 215050: true,
- 216043: true,
- 216046: true,
- 216047: true,
- 216052: true,
- 216053: true,
- 216054: true,
- 216059: true,
- 216068: true,
- 217041: true,
- 217044: true,
- 217047: true,
- 217048: true,
- 217049: true,
- 217056: true,
- 217058: true,
- 217059: true,
- 217060: true,
- 217061: true,
- 217064: true,
- 217066: true,
- 217069: true,
- 217071: true,
- 217085: true,
- 217086: true,
- 217088: true,
- 217093: true,
- 217094: true,
- 217108: true,
- 217109: true,
- 217111: true,
- 217115: true,
- 217116: true,
- 218042: true,
- 218044: true,
- 218046: true,
- 218050: true,
- 218060: true,
- 218061: true,
- 218063: true,
- 218064: true,
- 218065: true,
- 218070: true,
- 218071: true,
- 218072: true,
- 218074: true,
- 218076: true,
- 222041: true,
- 223041: true,
- 223043: true,
- 223044: true,
- 223050: true,
- 223052: true,
- 223054: true,
- 223058: true,
- 223059: true,
- 223061: true,
- 223068: true,
- 223069: true,
- 223070: true,
- 223071: true,
- 223073: true,
- 223075: true,
- 223076: true,
- 223083: true,
- 223087: true,
- 223094: true,
- 223096: true,
- 223101: true,
- 223106: true,
- 223108: true,
- 224041: true,
- 224042: true,
- 224043: true,
- 224045: true,
- 224051: true,
- 224053: true,
- 224057: true,
- 224060: true,
- 224061: true,
- 224062: true,
- 224063: true,
- 224068: true,
- 224069: true,
- 224081: true,
- 224084: true,
- 224087: true,
- 224090: true,
- 224096: true,
- 224105: true,
- 225042: true,
- 227041: true,
- 229045: true,
- 229046: true,
- 229048: true,
- 229049: true,
- 229050: true,
- 231042: true,
- 236041: true,
- 237041: true,
- 238041: true,
- 238042: true,
- 240041: true,
- 240042: true,
- 240043: true,
- 241041: true,
- 243041: true,
- 244041: true,
- 245041: true,
- 247041: true,
- 250041: true,
- 252041: true,
- 253041: true,
- 253045: true,
- 254043: true,
- 255042: true,
- 255043: true,
- 257041: true,
- 257042: true,
- 258041: true,
- 261041: true,
- 264041: true,
- 294042: true,
- 296042: true,
-}